ActivityManagerService.java revision 4b4971b8a31f29e9dd3d27d54a49914a7c3ec1fb
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;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    if (!showBackground && UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1211                            && proc.pid != MY_PID) {
1212                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1213                        if (res != null) {
1214                            res.set(0);
1215                        }
1216                        return;
1217                    }
1218                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1219                        Dialog d = new AppErrorDialog(mContext,
1220                                ActivityManagerService.this, res, proc);
1221                        d.show();
1222                        proc.crashDialog = d;
1223                    } else {
1224                        // The device is asleep, so just pretend that the user
1225                        // saw a crash dialog and hit "force quit".
1226                        if (res != null) {
1227                            res.set(0);
1228                        }
1229                    }
1230                }
1231
1232                ensureBootCompleted();
1233            } break;
1234            case SHOW_NOT_RESPONDING_MSG: {
1235                synchronized (ActivityManagerService.this) {
1236                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1237                    ProcessRecord proc = (ProcessRecord)data.get("app");
1238                    if (proc != null && proc.anrDialog != null) {
1239                        Slog.e(TAG, "App already has anr dialog: " + proc);
1240                        return;
1241                    }
1242
1243                    Intent intent = new Intent("android.intent.action.ANR");
1244                    if (!mProcessesReady) {
1245                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1246                                | Intent.FLAG_RECEIVER_FOREGROUND);
1247                    }
1248                    broadcastIntentLocked(null, null, intent,
1249                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1250                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1251
1252                    if (mShowDialogs) {
1253                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1254                                mContext, proc, (ActivityRecord)data.get("activity"),
1255                                msg.arg1 != 0);
1256                        d.show();
1257                        proc.anrDialog = d;
1258                    } else {
1259                        // Just kill the app if there is no dialog to be shown.
1260                        killAppAtUsersRequest(proc, null);
1261                    }
1262                }
1263
1264                ensureBootCompleted();
1265            } break;
1266            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1267                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1268                synchronized (ActivityManagerService.this) {
1269                    ProcessRecord proc = (ProcessRecord) data.get("app");
1270                    if (proc == null) {
1271                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1272                        break;
1273                    }
1274                    if (proc.crashDialog != null) {
1275                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1276                        return;
1277                    }
1278                    AppErrorResult res = (AppErrorResult) data.get("result");
1279                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1280                        Dialog d = new StrictModeViolationDialog(mContext,
1281                                ActivityManagerService.this, res, proc);
1282                        d.show();
1283                        proc.crashDialog = d;
1284                    } else {
1285                        // The device is asleep, so just pretend that the user
1286                        // saw a crash dialog and hit "force quit".
1287                        res.set(0);
1288                    }
1289                }
1290                ensureBootCompleted();
1291            } break;
1292            case SHOW_FACTORY_ERROR_MSG: {
1293                Dialog d = new FactoryErrorDialog(
1294                    mContext, msg.getData().getCharSequence("msg"));
1295                d.show();
1296                ensureBootCompleted();
1297            } break;
1298            case UPDATE_CONFIGURATION_MSG: {
1299                final ContentResolver resolver = mContext.getContentResolver();
1300                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1301            } break;
1302            case GC_BACKGROUND_PROCESSES_MSG: {
1303                synchronized (ActivityManagerService.this) {
1304                    performAppGcsIfAppropriateLocked();
1305                }
1306            } break;
1307            case WAIT_FOR_DEBUGGER_MSG: {
1308                synchronized (ActivityManagerService.this) {
1309                    ProcessRecord app = (ProcessRecord)msg.obj;
1310                    if (msg.arg1 != 0) {
1311                        if (!app.waitedForDebugger) {
1312                            Dialog d = new AppWaitingForDebuggerDialog(
1313                                    ActivityManagerService.this,
1314                                    mContext, app);
1315                            app.waitDialog = d;
1316                            app.waitedForDebugger = true;
1317                            d.show();
1318                        }
1319                    } else {
1320                        if (app.waitDialog != null) {
1321                            app.waitDialog.dismiss();
1322                            app.waitDialog = null;
1323                        }
1324                    }
1325                }
1326            } break;
1327            case SERVICE_TIMEOUT_MSG: {
1328                if (mDidDexOpt) {
1329                    mDidDexOpt = false;
1330                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1331                    nmsg.obj = msg.obj;
1332                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1333                    return;
1334                }
1335                mServices.serviceTimeout((ProcessRecord)msg.obj);
1336            } break;
1337            case UPDATE_TIME_ZONE: {
1338                synchronized (ActivityManagerService.this) {
1339                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1340                        ProcessRecord r = mLruProcesses.get(i);
1341                        if (r.thread != null) {
1342                            try {
1343                                r.thread.updateTimeZone();
1344                            } catch (RemoteException ex) {
1345                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1346                            }
1347                        }
1348                    }
1349                }
1350            } break;
1351            case CLEAR_DNS_CACHE_MSG: {
1352                synchronized (ActivityManagerService.this) {
1353                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1354                        ProcessRecord r = mLruProcesses.get(i);
1355                        if (r.thread != null) {
1356                            try {
1357                                r.thread.clearDnsCache();
1358                            } catch (RemoteException ex) {
1359                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1360                            }
1361                        }
1362                    }
1363                }
1364            } break;
1365            case UPDATE_HTTP_PROXY_MSG: {
1366                ProxyInfo proxy = (ProxyInfo)msg.obj;
1367                String host = "";
1368                String port = "";
1369                String exclList = "";
1370                Uri pacFileUrl = Uri.EMPTY;
1371                if (proxy != null) {
1372                    host = proxy.getHost();
1373                    port = Integer.toString(proxy.getPort());
1374                    exclList = proxy.getExclusionListAsString();
1375                    pacFileUrl = proxy.getPacFileUrl();
1376                }
1377                synchronized (ActivityManagerService.this) {
1378                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1379                        ProcessRecord r = mLruProcesses.get(i);
1380                        if (r.thread != null) {
1381                            try {
1382                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1383                            } catch (RemoteException ex) {
1384                                Slog.w(TAG, "Failed to update http proxy for: " +
1385                                        r.info.processName);
1386                            }
1387                        }
1388                    }
1389                }
1390            } break;
1391            case SHOW_UID_ERROR_MSG: {
1392                String title = "System UIDs Inconsistent";
1393                String text = "UIDs on the system are inconsistent, you need to wipe your"
1394                        + " data partition or your device will be unstable.";
1395                Log.e(TAG, title + ": " + text);
1396                if (mShowDialogs) {
1397                    // XXX This is a temporary dialog, no need to localize.
1398                    AlertDialog d = new BaseErrorDialog(mContext);
1399                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1400                    d.setCancelable(false);
1401                    d.setTitle(title);
1402                    d.setMessage(text);
1403                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1404                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1405                    mUidAlert = d;
1406                    d.show();
1407                }
1408            } break;
1409            case IM_FEELING_LUCKY_MSG: {
1410                if (mUidAlert != null) {
1411                    mUidAlert.dismiss();
1412                    mUidAlert = null;
1413                }
1414            } break;
1415            case PROC_START_TIMEOUT_MSG: {
1416                if (mDidDexOpt) {
1417                    mDidDexOpt = false;
1418                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1419                    nmsg.obj = msg.obj;
1420                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1421                    return;
1422                }
1423                ProcessRecord app = (ProcessRecord)msg.obj;
1424                synchronized (ActivityManagerService.this) {
1425                    processStartTimedOutLocked(app);
1426                }
1427            } break;
1428            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1429                synchronized (ActivityManagerService.this) {
1430                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1431                }
1432            } break;
1433            case KILL_APPLICATION_MSG: {
1434                synchronized (ActivityManagerService.this) {
1435                    int appid = msg.arg1;
1436                    boolean restart = (msg.arg2 == 1);
1437                    Bundle bundle = (Bundle)msg.obj;
1438                    String pkg = bundle.getString("pkg");
1439                    String reason = bundle.getString("reason");
1440                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1441                            false, UserHandle.USER_ALL, reason);
1442                }
1443            } break;
1444            case FINALIZE_PENDING_INTENT_MSG: {
1445                ((PendingIntentRecord)msg.obj).completeFinalize();
1446            } break;
1447            case POST_HEAVY_NOTIFICATION_MSG: {
1448                INotificationManager inm = NotificationManager.getService();
1449                if (inm == null) {
1450                    return;
1451                }
1452
1453                ActivityRecord root = (ActivityRecord)msg.obj;
1454                ProcessRecord process = root.app;
1455                if (process == null) {
1456                    return;
1457                }
1458
1459                try {
1460                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1461                    String text = mContext.getString(R.string.heavy_weight_notification,
1462                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1463                    Notification notification = new Notification();
1464                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1465                    notification.when = 0;
1466                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1467                    notification.tickerText = text;
1468                    notification.defaults = 0; // please be quiet
1469                    notification.sound = null;
1470                    notification.vibrate = null;
1471                    notification.setLatestEventInfo(context, text,
1472                            mContext.getText(R.string.heavy_weight_notification_detail),
1473                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1474                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1475                                    new UserHandle(root.userId)));
1476
1477                    try {
1478                        int[] outId = new int[1];
1479                        inm.enqueueNotificationWithTag("android", "android", null,
1480                                R.string.heavy_weight_notification,
1481                                notification, outId, root.userId);
1482                    } catch (RuntimeException e) {
1483                        Slog.w(ActivityManagerService.TAG,
1484                                "Error showing notification for heavy-weight app", e);
1485                    } catch (RemoteException e) {
1486                    }
1487                } catch (NameNotFoundException e) {
1488                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1489                }
1490            } break;
1491            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1492                INotificationManager inm = NotificationManager.getService();
1493                if (inm == null) {
1494                    return;
1495                }
1496                try {
1497                    inm.cancelNotificationWithTag("android", null,
1498                            R.string.heavy_weight_notification,  msg.arg1);
1499                } catch (RuntimeException e) {
1500                    Slog.w(ActivityManagerService.TAG,
1501                            "Error canceling notification for service", e);
1502                } catch (RemoteException e) {
1503                }
1504            } break;
1505            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1506                synchronized (ActivityManagerService.this) {
1507                    checkExcessivePowerUsageLocked(true);
1508                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1509                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1510                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1511                }
1512            } break;
1513            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1514                synchronized (ActivityManagerService.this) {
1515                    ActivityRecord ar = (ActivityRecord)msg.obj;
1516                    if (mCompatModeDialog != null) {
1517                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1518                                ar.info.applicationInfo.packageName)) {
1519                            return;
1520                        }
1521                        mCompatModeDialog.dismiss();
1522                        mCompatModeDialog = null;
1523                    }
1524                    if (ar != null && false) {
1525                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1526                                ar.packageName)) {
1527                            int mode = mCompatModePackages.computeCompatModeLocked(
1528                                    ar.info.applicationInfo);
1529                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1530                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1531                                mCompatModeDialog = new CompatModeDialog(
1532                                        ActivityManagerService.this, mContext,
1533                                        ar.info.applicationInfo);
1534                                mCompatModeDialog.show();
1535                            }
1536                        }
1537                    }
1538                }
1539                break;
1540            }
1541            case DISPATCH_PROCESSES_CHANGED: {
1542                dispatchProcessesChanged();
1543                break;
1544            }
1545            case DISPATCH_PROCESS_DIED: {
1546                final int pid = msg.arg1;
1547                final int uid = msg.arg2;
1548                dispatchProcessDied(pid, uid);
1549                break;
1550            }
1551            case REPORT_MEM_USAGE_MSG: {
1552                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1553                Thread thread = new Thread() {
1554                    @Override public void run() {
1555                        final SparseArray<ProcessMemInfo> infoMap
1556                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1557                        for (int i=0, N=memInfos.size(); i<N; i++) {
1558                            ProcessMemInfo mi = memInfos.get(i);
1559                            infoMap.put(mi.pid, mi);
1560                        }
1561                        updateCpuStatsNow();
1562                        synchronized (mProcessCpuThread) {
1563                            final int N = mProcessCpuTracker.countStats();
1564                            for (int i=0; i<N; i++) {
1565                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1566                                if (st.vsize > 0) {
1567                                    long pss = Debug.getPss(st.pid, null);
1568                                    if (pss > 0) {
1569                                        if (infoMap.indexOfKey(st.pid) < 0) {
1570                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1571                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1572                                            mi.pss = pss;
1573                                            memInfos.add(mi);
1574                                        }
1575                                    }
1576                                }
1577                            }
1578                        }
1579
1580                        long totalPss = 0;
1581                        for (int i=0, N=memInfos.size(); i<N; i++) {
1582                            ProcessMemInfo mi = memInfos.get(i);
1583                            if (mi.pss == 0) {
1584                                mi.pss = Debug.getPss(mi.pid, null);
1585                            }
1586                            totalPss += mi.pss;
1587                        }
1588                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1589                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1590                                if (lhs.oomAdj != rhs.oomAdj) {
1591                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1592                                }
1593                                if (lhs.pss != rhs.pss) {
1594                                    return lhs.pss < rhs.pss ? 1 : -1;
1595                                }
1596                                return 0;
1597                            }
1598                        });
1599
1600                        StringBuilder tag = new StringBuilder(128);
1601                        StringBuilder stack = new StringBuilder(128);
1602                        tag.append("Low on memory -- ");
1603                        appendMemBucket(tag, totalPss, "total", false);
1604                        appendMemBucket(stack, totalPss, "total", true);
1605
1606                        StringBuilder logBuilder = new StringBuilder(1024);
1607                        logBuilder.append("Low on memory:\n");
1608
1609                        boolean firstLine = true;
1610                        int lastOomAdj = Integer.MIN_VALUE;
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613
1614                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1615                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1616                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1617                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1618                                if (lastOomAdj != mi.oomAdj) {
1619                                    lastOomAdj = mi.oomAdj;
1620                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1621                                        tag.append(" / ");
1622                                    }
1623                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1624                                        if (firstLine) {
1625                                            stack.append(":");
1626                                            firstLine = false;
1627                                        }
1628                                        stack.append("\n\t at ");
1629                                    } else {
1630                                        stack.append("$");
1631                                    }
1632                                } else {
1633                                    tag.append(" ");
1634                                    stack.append("$");
1635                                }
1636                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1637                                    appendMemBucket(tag, mi.pss, mi.name, false);
1638                                }
1639                                appendMemBucket(stack, mi.pss, mi.name, true);
1640                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1641                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1642                                    stack.append("(");
1643                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1644                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1645                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1646                                            stack.append(":");
1647                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1648                                        }
1649                                    }
1650                                    stack.append(")");
1651                                }
1652                            }
1653
1654                            logBuilder.append("  ");
1655                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1656                            logBuilder.append(' ');
1657                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1658                            logBuilder.append(' ');
1659                            ProcessList.appendRamKb(logBuilder, mi.pss);
1660                            logBuilder.append(" kB: ");
1661                            logBuilder.append(mi.name);
1662                            logBuilder.append(" (");
1663                            logBuilder.append(mi.pid);
1664                            logBuilder.append(") ");
1665                            logBuilder.append(mi.adjType);
1666                            logBuilder.append('\n');
1667                            if (mi.adjReason != null) {
1668                                logBuilder.append("                      ");
1669                                logBuilder.append(mi.adjReason);
1670                                logBuilder.append('\n');
1671                            }
1672                        }
1673
1674                        logBuilder.append("           ");
1675                        ProcessList.appendRamKb(logBuilder, totalPss);
1676                        logBuilder.append(" kB: TOTAL\n");
1677
1678                        long[] infos = new long[Debug.MEMINFO_COUNT];
1679                        Debug.getMemInfo(infos);
1680                        logBuilder.append("  MemInfo: ");
1681                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1684                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1685                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1686                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1687                            logBuilder.append("  ZRAM: ");
1688                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1689                            logBuilder.append(" kB RAM, ");
1690                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1691                            logBuilder.append(" kB swap total, ");
1692                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1693                            logBuilder.append(" kB swap free\n");
1694                        }
1695                        Slog.i(TAG, logBuilder.toString());
1696
1697                        StringBuilder dropBuilder = new StringBuilder(1024);
1698                        /*
1699                        StringWriter oomSw = new StringWriter();
1700                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1701                        StringWriter catSw = new StringWriter();
1702                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1703                        String[] emptyArgs = new String[] { };
1704                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1705                        oomPw.flush();
1706                        String oomString = oomSw.toString();
1707                        */
1708                        dropBuilder.append(stack);
1709                        dropBuilder.append('\n');
1710                        dropBuilder.append('\n');
1711                        dropBuilder.append(logBuilder);
1712                        dropBuilder.append('\n');
1713                        /*
1714                        dropBuilder.append(oomString);
1715                        dropBuilder.append('\n');
1716                        */
1717                        StringWriter catSw = new StringWriter();
1718                        synchronized (ActivityManagerService.this) {
1719                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1720                            String[] emptyArgs = new String[] { };
1721                            catPw.println();
1722                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1723                            catPw.println();
1724                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1725                                    false, false, null);
1726                            catPw.println();
1727                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1728                            catPw.flush();
1729                        }
1730                        dropBuilder.append(catSw.toString());
1731                        addErrorToDropBox("lowmem", null, "system_server", null,
1732                                null, tag.toString(), dropBuilder.toString(), null, null);
1733                        //Slog.i(TAG, "Sent to dropbox:");
1734                        //Slog.i(TAG, dropBuilder.toString());
1735                        synchronized (ActivityManagerService.this) {
1736                            long now = SystemClock.uptimeMillis();
1737                            if (mLastMemUsageReportTime < now) {
1738                                mLastMemUsageReportTime = now;
1739                            }
1740                        }
1741                    }
1742                };
1743                thread.start();
1744                break;
1745            }
1746            case REPORT_USER_SWITCH_MSG: {
1747                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1748                break;
1749            }
1750            case CONTINUE_USER_SWITCH_MSG: {
1751                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case USER_SWITCH_TIMEOUT_MSG: {
1755                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case IMMERSIVE_MODE_LOCK_MSG: {
1759                final boolean nextState = (msg.arg1 != 0);
1760                if (mUpdateLock.isHeld() != nextState) {
1761                    if (DEBUG_IMMERSIVE) {
1762                        final ActivityRecord r = (ActivityRecord) msg.obj;
1763                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1764                    }
1765                    if (nextState) {
1766                        mUpdateLock.acquire();
1767                    } else {
1768                        mUpdateLock.release();
1769                    }
1770                }
1771                break;
1772            }
1773            case PERSIST_URI_GRANTS_MSG: {
1774                writeGrantedUriPermissions();
1775                break;
1776            }
1777            case REQUEST_ALL_PSS_MSG: {
1778                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1779                break;
1780            }
1781            case START_PROFILES_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    startProfilesLocked();
1784                }
1785                break;
1786            }
1787            case UPDATE_TIME: {
1788                synchronized (ActivityManagerService.this) {
1789                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1790                        ProcessRecord r = mLruProcesses.get(i);
1791                        if (r.thread != null) {
1792                            try {
1793                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1794                            } catch (RemoteException ex) {
1795                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1796                            }
1797                        }
1798                    }
1799                }
1800                break;
1801            }
1802            case SYSTEM_USER_START_MSG: {
1803                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1804                        Integer.toString(msg.arg1), msg.arg1);
1805                mSystemServiceManager.startUser(msg.arg1);
1806                break;
1807            }
1808            case SYSTEM_USER_CURRENT_MSG: {
1809                mBatteryStatsService.noteEvent(
1810                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1811                        Integer.toString(msg.arg2), msg.arg2);
1812                mBatteryStatsService.noteEvent(
1813                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1814                        Integer.toString(msg.arg1), msg.arg1);
1815                mSystemServiceManager.switchUser(msg.arg1);
1816                break;
1817            }
1818            case ENTER_ANIMATION_COMPLETE_MSG: {
1819                synchronized (ActivityManagerService.this) {
1820                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1821                    if (r != null && r.app != null && r.app.thread != null) {
1822                        try {
1823                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1824                        } catch (RemoteException e) {
1825                        }
1826                    }
1827                }
1828                break;
1829            }
1830            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1831                enableScreenAfterBoot();
1832                break;
1833            }
1834            }
1835        }
1836    };
1837
1838    static final int COLLECT_PSS_BG_MSG = 1;
1839
1840    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1841        @Override
1842        public void handleMessage(Message msg) {
1843            switch (msg.what) {
1844            case COLLECT_PSS_BG_MSG: {
1845                long start = SystemClock.uptimeMillis();
1846                MemInfoReader memInfo = null;
1847                synchronized (ActivityManagerService.this) {
1848                    if (mFullPssPending) {
1849                        mFullPssPending = false;
1850                        memInfo = new MemInfoReader();
1851                    }
1852                }
1853                if (memInfo != null) {
1854                    updateCpuStatsNow();
1855                    long nativeTotalPss = 0;
1856                    synchronized (mProcessCpuThread) {
1857                        final int N = mProcessCpuTracker.countStats();
1858                        for (int j=0; j<N; j++) {
1859                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1860                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1861                                // This is definitely an application process; skip it.
1862                                continue;
1863                            }
1864                            synchronized (mPidsSelfLocked) {
1865                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1866                                    // This is one of our own processes; skip it.
1867                                    continue;
1868                                }
1869                            }
1870                            nativeTotalPss += Debug.getPss(st.pid, null);
1871                        }
1872                    }
1873                    memInfo.readMemInfo();
1874                    synchronized (this) {
1875                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1876                                + (SystemClock.uptimeMillis()-start) + "ms");
1877                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1878                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1879                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1880                                        +memInfo.getSlabSizeKb(),
1881                                nativeTotalPss);
1882                    }
1883                }
1884
1885                int i=0, num=0;
1886                long[] tmp = new long[1];
1887                do {
1888                    ProcessRecord proc;
1889                    int procState;
1890                    int pid;
1891                    synchronized (ActivityManagerService.this) {
1892                        if (i >= mPendingPssProcesses.size()) {
1893                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1894                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1895                            mPendingPssProcesses.clear();
1896                            return;
1897                        }
1898                        proc = mPendingPssProcesses.get(i);
1899                        procState = proc.pssProcState;
1900                        if (proc.thread != null && procState == proc.setProcState) {
1901                            pid = proc.pid;
1902                        } else {
1903                            proc = null;
1904                            pid = 0;
1905                        }
1906                        i++;
1907                    }
1908                    if (proc != null) {
1909                        long pss = Debug.getPss(pid, tmp);
1910                        synchronized (ActivityManagerService.this) {
1911                            if (proc.thread != null && proc.setProcState == procState
1912                                    && proc.pid == pid) {
1913                                num++;
1914                                proc.lastPssTime = SystemClock.uptimeMillis();
1915                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1916                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1917                                        + ": " + pss + " lastPss=" + proc.lastPss
1918                                        + " state=" + ProcessList.makeProcStateString(procState));
1919                                if (proc.initialIdlePss == 0) {
1920                                    proc.initialIdlePss = pss;
1921                                }
1922                                proc.lastPss = pss;
1923                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1924                                    proc.lastCachedPss = pss;
1925                                }
1926                            }
1927                        }
1928                    }
1929                } while (true);
1930            }
1931            }
1932        }
1933    };
1934
1935    /**
1936     * Monitor for package changes and update our internal state.
1937     */
1938    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1939        @Override
1940        public void onPackageRemoved(String packageName, int uid) {
1941            // Remove all tasks with activities in the specified package from the list of recent tasks
1942            synchronized (ActivityManagerService.this) {
1943                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1944                    TaskRecord tr = mRecentTasks.get(i);
1945                    ComponentName cn = tr.intent.getComponent();
1946                    if (cn != null && cn.getPackageName().equals(packageName)) {
1947                        // If the package name matches, remove the task and kill the process
1948                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1949                    }
1950                }
1951            }
1952        }
1953
1954        @Override
1955        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1956            onPackageModified(packageName);
1957            return true;
1958        }
1959
1960        @Override
1961        public void onPackageModified(String packageName) {
1962            final PackageManager pm = mContext.getPackageManager();
1963            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1964                    new ArrayList<Pair<Intent, Integer>>();
1965            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1966            // Copy the list of recent tasks so that we don't hold onto the lock on
1967            // ActivityManagerService for long periods while checking if components exist.
1968            synchronized (ActivityManagerService.this) {
1969                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1970                    TaskRecord tr = mRecentTasks.get(i);
1971                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1972                }
1973            }
1974            // Check the recent tasks and filter out all tasks with components that no longer exist.
1975            Intent tmpI = new Intent();
1976            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1977                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1978                ComponentName cn = p.first.getComponent();
1979                if (cn != null && cn.getPackageName().equals(packageName)) {
1980                    try {
1981                        // Add the task to the list to remove if the component no longer exists
1982                        tmpI.setComponent(cn);
1983                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1984                            tasksToRemove.add(p.second);
1985                        }
1986                    } catch (Exception e) {}
1987                }
1988            }
1989            // Prune all the tasks with removed components from the list of recent tasks
1990            synchronized (ActivityManagerService.this) {
1991                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1992                    // Remove the task but don't kill the process (since other components in that
1993                    // package may still be running and in the background)
1994                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1995                }
1996            }
1997        }
1998
1999        @Override
2000        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2001            // Force stop the specified packages
2002            if (packages != null) {
2003                for (String pkg : packages) {
2004                    synchronized (ActivityManagerService.this) {
2005                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2006                                "finished booting")) {
2007                            return true;
2008                        }
2009                    }
2010                }
2011            }
2012            return false;
2013        }
2014    };
2015
2016    public void setSystemProcess() {
2017        try {
2018            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2019            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2020            ServiceManager.addService("meminfo", new MemBinder(this));
2021            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2022            ServiceManager.addService("dbinfo", new DbBinder(this));
2023            if (MONITOR_CPU_USAGE) {
2024                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2025            }
2026            ServiceManager.addService("permission", new PermissionController(this));
2027
2028            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2029                    "android", STOCK_PM_FLAGS);
2030            mSystemThread.installSystemApplicationInfo(info);
2031
2032            synchronized (this) {
2033                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2034                app.persistent = true;
2035                app.pid = MY_PID;
2036                app.maxAdj = ProcessList.SYSTEM_ADJ;
2037                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2038                mProcessNames.put(app.processName, app.uid, app);
2039                synchronized (mPidsSelfLocked) {
2040                    mPidsSelfLocked.put(app.pid, app);
2041                }
2042                updateLruProcessLocked(app, false, null);
2043                updateOomAdjLocked();
2044            }
2045        } catch (PackageManager.NameNotFoundException e) {
2046            throw new RuntimeException(
2047                    "Unable to find android system package", e);
2048        }
2049    }
2050
2051    public void setWindowManager(WindowManagerService wm) {
2052        mWindowManager = wm;
2053        mStackSupervisor.setWindowManager(wm);
2054    }
2055
2056    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2057        mUsageStatsService = usageStatsManager;
2058    }
2059
2060    public void startObservingNativeCrashes() {
2061        final NativeCrashListener ncl = new NativeCrashListener(this);
2062        ncl.start();
2063    }
2064
2065    public IAppOpsService getAppOpsService() {
2066        return mAppOpsService;
2067    }
2068
2069    static class MemBinder extends Binder {
2070        ActivityManagerService mActivityManagerService;
2071        MemBinder(ActivityManagerService activityManagerService) {
2072            mActivityManagerService = activityManagerService;
2073        }
2074
2075        @Override
2076        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2077            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2078                    != PackageManager.PERMISSION_GRANTED) {
2079                pw.println("Permission Denial: can't dump meminfo from from pid="
2080                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2081                        + " without permission " + android.Manifest.permission.DUMP);
2082                return;
2083            }
2084
2085            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2086        }
2087    }
2088
2089    static class GraphicsBinder extends Binder {
2090        ActivityManagerService mActivityManagerService;
2091        GraphicsBinder(ActivityManagerService activityManagerService) {
2092            mActivityManagerService = activityManagerService;
2093        }
2094
2095        @Override
2096        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2097            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2098                    != PackageManager.PERMISSION_GRANTED) {
2099                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2100                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2101                        + " without permission " + android.Manifest.permission.DUMP);
2102                return;
2103            }
2104
2105            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2106        }
2107    }
2108
2109    static class DbBinder extends Binder {
2110        ActivityManagerService mActivityManagerService;
2111        DbBinder(ActivityManagerService activityManagerService) {
2112            mActivityManagerService = activityManagerService;
2113        }
2114
2115        @Override
2116        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2117            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2118                    != PackageManager.PERMISSION_GRANTED) {
2119                pw.println("Permission Denial: can't dump dbinfo from from pid="
2120                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2121                        + " without permission " + android.Manifest.permission.DUMP);
2122                return;
2123            }
2124
2125            mActivityManagerService.dumpDbInfo(fd, pw, args);
2126        }
2127    }
2128
2129    static class CpuBinder extends Binder {
2130        ActivityManagerService mActivityManagerService;
2131        CpuBinder(ActivityManagerService activityManagerService) {
2132            mActivityManagerService = activityManagerService;
2133        }
2134
2135        @Override
2136        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2137            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2138                    != PackageManager.PERMISSION_GRANTED) {
2139                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2140                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2141                        + " without permission " + android.Manifest.permission.DUMP);
2142                return;
2143            }
2144
2145            synchronized (mActivityManagerService.mProcessCpuThread) {
2146                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2147                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2148                        SystemClock.uptimeMillis()));
2149            }
2150        }
2151    }
2152
2153    public static final class Lifecycle extends SystemService {
2154        private final ActivityManagerService mService;
2155
2156        public Lifecycle(Context context) {
2157            super(context);
2158            mService = new ActivityManagerService(context);
2159        }
2160
2161        @Override
2162        public void onStart() {
2163            mService.start();
2164        }
2165
2166        public ActivityManagerService getService() {
2167            return mService;
2168        }
2169    }
2170
2171    // Note: This method is invoked on the main thread but may need to attach various
2172    // handlers to other threads.  So take care to be explicit about the looper.
2173    public ActivityManagerService(Context systemContext) {
2174        mContext = systemContext;
2175        mFactoryTest = FactoryTest.getMode();
2176        mSystemThread = ActivityThread.currentActivityThread();
2177
2178        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2179
2180        mHandlerThread = new ServiceThread(TAG,
2181                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2182        mHandlerThread.start();
2183        mHandler = new MainHandler(mHandlerThread.getLooper());
2184
2185        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2186                "foreground", BROADCAST_FG_TIMEOUT, false);
2187        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2188                "background", BROADCAST_BG_TIMEOUT, true);
2189        mBroadcastQueues[0] = mFgBroadcastQueue;
2190        mBroadcastQueues[1] = mBgBroadcastQueue;
2191
2192        mServices = new ActiveServices(this);
2193        mProviderMap = new ProviderMap(this);
2194
2195        // TODO: Move creation of battery stats service outside of activity manager service.
2196        File dataDir = Environment.getDataDirectory();
2197        File systemDir = new File(dataDir, "system");
2198        systemDir.mkdirs();
2199        mBatteryStatsService = new BatteryStatsService(new File(
2200                systemDir, "batterystats.bin").toString(), mHandler);
2201        mBatteryStatsService.getActiveStatistics().readLocked();
2202        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2203        mOnBattery = DEBUG_POWER ? true
2204                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2205        mBatteryStatsService.getActiveStatistics().setCallback(this);
2206
2207        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2208
2209        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2210
2211        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2212
2213        // User 0 is the first and only user that runs at boot.
2214        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2215        mUserLru.add(Integer.valueOf(0));
2216        updateStartedUserArrayLocked();
2217
2218        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2219            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2220
2221        mConfiguration.setToDefaults();
2222        mConfiguration.setLocale(Locale.getDefault());
2223
2224        mConfigurationSeq = mConfiguration.seq = 1;
2225        mProcessCpuTracker.init();
2226
2227        mHasRecents = mContext.getResources().getBoolean(
2228                com.android.internal.R.bool.config_hasRecents);
2229
2230        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2231        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2232        mStackSupervisor = new ActivityStackSupervisor(this);
2233        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2234
2235        mProcessCpuThread = new Thread("CpuTracker") {
2236            @Override
2237            public void run() {
2238                while (true) {
2239                    try {
2240                        try {
2241                            synchronized(this) {
2242                                final long now = SystemClock.uptimeMillis();
2243                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2244                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2245                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2246                                //        + ", write delay=" + nextWriteDelay);
2247                                if (nextWriteDelay < nextCpuDelay) {
2248                                    nextCpuDelay = nextWriteDelay;
2249                                }
2250                                if (nextCpuDelay > 0) {
2251                                    mProcessCpuMutexFree.set(true);
2252                                    this.wait(nextCpuDelay);
2253                                }
2254                            }
2255                        } catch (InterruptedException e) {
2256                        }
2257                        updateCpuStatsNow();
2258                    } catch (Exception e) {
2259                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2260                    }
2261                }
2262            }
2263        };
2264
2265        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2266
2267        Watchdog.getInstance().addMonitor(this);
2268        Watchdog.getInstance().addThread(mHandler);
2269    }
2270
2271    public void setSystemServiceManager(SystemServiceManager mgr) {
2272        mSystemServiceManager = mgr;
2273    }
2274
2275    private void start() {
2276        Process.removeAllProcessGroups();
2277        mProcessCpuThread.start();
2278
2279        mBatteryStatsService.publish(mContext);
2280        mAppOpsService.publish(mContext);
2281        Slog.d("AppOps", "AppOpsService published");
2282        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2283    }
2284
2285    public void initPowerManagement() {
2286        mStackSupervisor.initPowerManagement();
2287        mBatteryStatsService.initPowerManagement();
2288    }
2289
2290    @Override
2291    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2292            throws RemoteException {
2293        if (code == SYSPROPS_TRANSACTION) {
2294            // We need to tell all apps about the system property change.
2295            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2296            synchronized(this) {
2297                final int NP = mProcessNames.getMap().size();
2298                for (int ip=0; ip<NP; ip++) {
2299                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2300                    final int NA = apps.size();
2301                    for (int ia=0; ia<NA; ia++) {
2302                        ProcessRecord app = apps.valueAt(ia);
2303                        if (app.thread != null) {
2304                            procs.add(app.thread.asBinder());
2305                        }
2306                    }
2307                }
2308            }
2309
2310            int N = procs.size();
2311            for (int i=0; i<N; i++) {
2312                Parcel data2 = Parcel.obtain();
2313                try {
2314                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2315                } catch (RemoteException e) {
2316                }
2317                data2.recycle();
2318            }
2319        }
2320        try {
2321            return super.onTransact(code, data, reply, flags);
2322        } catch (RuntimeException e) {
2323            // The activity manager only throws security exceptions, so let's
2324            // log all others.
2325            if (!(e instanceof SecurityException)) {
2326                Slog.wtf(TAG, "Activity Manager Crash", e);
2327            }
2328            throw e;
2329        }
2330    }
2331
2332    void updateCpuStats() {
2333        final long now = SystemClock.uptimeMillis();
2334        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2335            return;
2336        }
2337        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2338            synchronized (mProcessCpuThread) {
2339                mProcessCpuThread.notify();
2340            }
2341        }
2342    }
2343
2344    void updateCpuStatsNow() {
2345        synchronized (mProcessCpuThread) {
2346            mProcessCpuMutexFree.set(false);
2347            final long now = SystemClock.uptimeMillis();
2348            boolean haveNewCpuStats = false;
2349
2350            if (MONITOR_CPU_USAGE &&
2351                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2352                mLastCpuTime.set(now);
2353                haveNewCpuStats = true;
2354                mProcessCpuTracker.update();
2355                //Slog.i(TAG, mProcessCpu.printCurrentState());
2356                //Slog.i(TAG, "Total CPU usage: "
2357                //        + mProcessCpu.getTotalCpuPercent() + "%");
2358
2359                // Slog the cpu usage if the property is set.
2360                if ("true".equals(SystemProperties.get("events.cpu"))) {
2361                    int user = mProcessCpuTracker.getLastUserTime();
2362                    int system = mProcessCpuTracker.getLastSystemTime();
2363                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2364                    int irq = mProcessCpuTracker.getLastIrqTime();
2365                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2366                    int idle = mProcessCpuTracker.getLastIdleTime();
2367
2368                    int total = user + system + iowait + irq + softIrq + idle;
2369                    if (total == 0) total = 1;
2370
2371                    EventLog.writeEvent(EventLogTags.CPU,
2372                            ((user+system+iowait+irq+softIrq) * 100) / total,
2373                            (user * 100) / total,
2374                            (system * 100) / total,
2375                            (iowait * 100) / total,
2376                            (irq * 100) / total,
2377                            (softIrq * 100) / total);
2378                }
2379            }
2380
2381            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2382            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2383            synchronized(bstats) {
2384                synchronized(mPidsSelfLocked) {
2385                    if (haveNewCpuStats) {
2386                        if (mOnBattery) {
2387                            int perc = bstats.startAddingCpuLocked();
2388                            int totalUTime = 0;
2389                            int totalSTime = 0;
2390                            final int N = mProcessCpuTracker.countStats();
2391                            for (int i=0; i<N; i++) {
2392                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2393                                if (!st.working) {
2394                                    continue;
2395                                }
2396                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2397                                int otherUTime = (st.rel_utime*perc)/100;
2398                                int otherSTime = (st.rel_stime*perc)/100;
2399                                totalUTime += otherUTime;
2400                                totalSTime += otherSTime;
2401                                if (pr != null) {
2402                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2403                                    if (ps == null || !ps.isActive()) {
2404                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2405                                                pr.info.uid, pr.processName);
2406                                    }
2407                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2408                                            st.rel_stime-otherSTime);
2409                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2410                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2411                                } else {
2412                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2413                                    if (ps == null || !ps.isActive()) {
2414                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2415                                                bstats.mapUid(st.uid), st.name);
2416                                    }
2417                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2418                                            st.rel_stime-otherSTime);
2419                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2420                                }
2421                            }
2422                            bstats.finishAddingCpuLocked(perc, totalUTime,
2423                                    totalSTime, cpuSpeedTimes);
2424                        }
2425                    }
2426                }
2427
2428                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2429                    mLastWriteTime = now;
2430                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2431                }
2432            }
2433        }
2434    }
2435
2436    @Override
2437    public void batteryNeedsCpuUpdate() {
2438        updateCpuStatsNow();
2439    }
2440
2441    @Override
2442    public void batteryPowerChanged(boolean onBattery) {
2443        // When plugging in, update the CPU stats first before changing
2444        // the plug state.
2445        updateCpuStatsNow();
2446        synchronized (this) {
2447            synchronized(mPidsSelfLocked) {
2448                mOnBattery = DEBUG_POWER ? true : onBattery;
2449            }
2450        }
2451    }
2452
2453    /**
2454     * Initialize the application bind args. These are passed to each
2455     * process when the bindApplication() IPC is sent to the process. They're
2456     * lazily setup to make sure the services are running when they're asked for.
2457     */
2458    private HashMap<String, IBinder> getCommonServicesLocked() {
2459        if (mAppBindArgs == null) {
2460            mAppBindArgs = new HashMap<String, IBinder>();
2461
2462            // Setup the application init args
2463            mAppBindArgs.put("package", ServiceManager.getService("package"));
2464            mAppBindArgs.put("window", ServiceManager.getService("window"));
2465            mAppBindArgs.put(Context.ALARM_SERVICE,
2466                    ServiceManager.getService(Context.ALARM_SERVICE));
2467        }
2468        return mAppBindArgs;
2469    }
2470
2471    final void setFocusedActivityLocked(ActivityRecord r) {
2472        if (mFocusedActivity != r) {
2473            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2474            mFocusedActivity = r;
2475            if (r.task != null && r.task.voiceInteractor != null) {
2476                startRunningVoiceLocked();
2477            } else {
2478                finishRunningVoiceLocked();
2479            }
2480            mStackSupervisor.setFocusedStack(r);
2481            if (r != null) {
2482                mWindowManager.setFocusedApp(r.appToken, true);
2483            }
2484            applyUpdateLockStateLocked(r);
2485        }
2486    }
2487
2488    final void clearFocusedActivity(ActivityRecord r) {
2489        if (mFocusedActivity == r) {
2490            mFocusedActivity = null;
2491        }
2492    }
2493
2494    @Override
2495    public void setFocusedStack(int stackId) {
2496        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2497        synchronized (ActivityManagerService.this) {
2498            ActivityStack stack = mStackSupervisor.getStack(stackId);
2499            if (stack != null) {
2500                ActivityRecord r = stack.topRunningActivityLocked(null);
2501                if (r != null) {
2502                    setFocusedActivityLocked(r);
2503                }
2504            }
2505        }
2506    }
2507
2508    @Override
2509    public void notifyActivityDrawn(IBinder token) {
2510        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2511        synchronized (this) {
2512            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2513            if (r != null) {
2514                r.task.stack.notifyActivityDrawnLocked(r);
2515            }
2516        }
2517    }
2518
2519    final void applyUpdateLockStateLocked(ActivityRecord r) {
2520        // Modifications to the UpdateLock state are done on our handler, outside
2521        // the activity manager's locks.  The new state is determined based on the
2522        // state *now* of the relevant activity record.  The object is passed to
2523        // the handler solely for logging detail, not to be consulted/modified.
2524        final boolean nextState = r != null && r.immersive;
2525        mHandler.sendMessage(
2526                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2527    }
2528
2529    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2530        Message msg = Message.obtain();
2531        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2532        msg.obj = r.task.askedCompatMode ? null : r;
2533        mHandler.sendMessage(msg);
2534    }
2535
2536    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2537            String what, Object obj, ProcessRecord srcApp) {
2538        app.lastActivityTime = now;
2539
2540        if (app.activities.size() > 0) {
2541            // Don't want to touch dependent processes that are hosting activities.
2542            return index;
2543        }
2544
2545        int lrui = mLruProcesses.lastIndexOf(app);
2546        if (lrui < 0) {
2547            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2548                    + what + " " + obj + " from " + srcApp);
2549            return index;
2550        }
2551
2552        if (lrui >= index) {
2553            // Don't want to cause this to move dependent processes *back* in the
2554            // list as if they were less frequently used.
2555            return index;
2556        }
2557
2558        if (lrui >= mLruProcessActivityStart) {
2559            // Don't want to touch dependent processes that are hosting activities.
2560            return index;
2561        }
2562
2563        mLruProcesses.remove(lrui);
2564        if (index > 0) {
2565            index--;
2566        }
2567        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2568                + " in LRU list: " + app);
2569        mLruProcesses.add(index, app);
2570        return index;
2571    }
2572
2573    final void removeLruProcessLocked(ProcessRecord app) {
2574        int lrui = mLruProcesses.lastIndexOf(app);
2575        if (lrui >= 0) {
2576            if (lrui <= mLruProcessActivityStart) {
2577                mLruProcessActivityStart--;
2578            }
2579            if (lrui <= mLruProcessServiceStart) {
2580                mLruProcessServiceStart--;
2581            }
2582            mLruProcesses.remove(lrui);
2583        }
2584    }
2585
2586    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2587            ProcessRecord client) {
2588        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2589                || app.treatLikeActivity;
2590        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2591        if (!activityChange && hasActivity) {
2592            // The process has activities, so we are only allowing activity-based adjustments
2593            // to move it.  It should be kept in the front of the list with other
2594            // processes that have activities, and we don't want those to change their
2595            // order except due to activity operations.
2596            return;
2597        }
2598
2599        mLruSeq++;
2600        final long now = SystemClock.uptimeMillis();
2601        app.lastActivityTime = now;
2602
2603        // First a quick reject: if the app is already at the position we will
2604        // put it, then there is nothing to do.
2605        if (hasActivity) {
2606            final int N = mLruProcesses.size();
2607            if (N > 0 && mLruProcesses.get(N-1) == app) {
2608                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2609                return;
2610            }
2611        } else {
2612            if (mLruProcessServiceStart > 0
2613                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2614                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2615                return;
2616            }
2617        }
2618
2619        int lrui = mLruProcesses.lastIndexOf(app);
2620
2621        if (app.persistent && lrui >= 0) {
2622            // We don't care about the position of persistent processes, as long as
2623            // they are in the list.
2624            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2625            return;
2626        }
2627
2628        /* In progress: compute new position first, so we can avoid doing work
2629           if the process is not actually going to move.  Not yet working.
2630        int addIndex;
2631        int nextIndex;
2632        boolean inActivity = false, inService = false;
2633        if (hasActivity) {
2634            // Process has activities, put it at the very tipsy-top.
2635            addIndex = mLruProcesses.size();
2636            nextIndex = mLruProcessServiceStart;
2637            inActivity = true;
2638        } else if (hasService) {
2639            // Process has services, put it at the top of the service list.
2640            addIndex = mLruProcessActivityStart;
2641            nextIndex = mLruProcessServiceStart;
2642            inActivity = true;
2643            inService = true;
2644        } else  {
2645            // Process not otherwise of interest, it goes to the top of the non-service area.
2646            addIndex = mLruProcessServiceStart;
2647            if (client != null) {
2648                int clientIndex = mLruProcesses.lastIndexOf(client);
2649                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2650                        + app);
2651                if (clientIndex >= 0 && addIndex > clientIndex) {
2652                    addIndex = clientIndex;
2653                }
2654            }
2655            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2656        }
2657
2658        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2659                + mLruProcessActivityStart + "): " + app);
2660        */
2661
2662        if (lrui >= 0) {
2663            if (lrui < mLruProcessActivityStart) {
2664                mLruProcessActivityStart--;
2665            }
2666            if (lrui < mLruProcessServiceStart) {
2667                mLruProcessServiceStart--;
2668            }
2669            /*
2670            if (addIndex > lrui) {
2671                addIndex--;
2672            }
2673            if (nextIndex > lrui) {
2674                nextIndex--;
2675            }
2676            */
2677            mLruProcesses.remove(lrui);
2678        }
2679
2680        /*
2681        mLruProcesses.add(addIndex, app);
2682        if (inActivity) {
2683            mLruProcessActivityStart++;
2684        }
2685        if (inService) {
2686            mLruProcessActivityStart++;
2687        }
2688        */
2689
2690        int nextIndex;
2691        if (hasActivity) {
2692            final int N = mLruProcesses.size();
2693            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2694                // Process doesn't have activities, but has clients with
2695                // activities...  move it up, but one below the top (the top
2696                // should always have a real activity).
2697                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2698                mLruProcesses.add(N-1, app);
2699                // To keep it from spamming the LRU list (by making a bunch of clients),
2700                // we will push down any other entries owned by the app.
2701                final int uid = app.info.uid;
2702                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2703                    ProcessRecord subProc = mLruProcesses.get(i);
2704                    if (subProc.info.uid == uid) {
2705                        // We want to push this one down the list.  If the process after
2706                        // it is for the same uid, however, don't do so, because we don't
2707                        // want them internally to be re-ordered.
2708                        if (mLruProcesses.get(i-1).info.uid != uid) {
2709                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2710                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2711                            ProcessRecord tmp = mLruProcesses.get(i);
2712                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2713                            mLruProcesses.set(i-1, tmp);
2714                            i--;
2715                        }
2716                    } else {
2717                        // A gap, we can stop here.
2718                        break;
2719                    }
2720                }
2721            } else {
2722                // Process has activities, put it at the very tipsy-top.
2723                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2724                mLruProcesses.add(app);
2725            }
2726            nextIndex = mLruProcessServiceStart;
2727        } else if (hasService) {
2728            // Process has services, put it at the top of the service list.
2729            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2730            mLruProcesses.add(mLruProcessActivityStart, app);
2731            nextIndex = mLruProcessServiceStart;
2732            mLruProcessActivityStart++;
2733        } else  {
2734            // Process not otherwise of interest, it goes to the top of the non-service area.
2735            int index = mLruProcessServiceStart;
2736            if (client != null) {
2737                // If there is a client, don't allow the process to be moved up higher
2738                // in the list than that client.
2739                int clientIndex = mLruProcesses.lastIndexOf(client);
2740                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2741                        + " when updating " + app);
2742                if (clientIndex <= lrui) {
2743                    // Don't allow the client index restriction to push it down farther in the
2744                    // list than it already is.
2745                    clientIndex = lrui;
2746                }
2747                if (clientIndex >= 0 && index > clientIndex) {
2748                    index = clientIndex;
2749                }
2750            }
2751            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2752            mLruProcesses.add(index, app);
2753            nextIndex = index-1;
2754            mLruProcessActivityStart++;
2755            mLruProcessServiceStart++;
2756        }
2757
2758        // If the app is currently using a content provider or service,
2759        // bump those processes as well.
2760        for (int j=app.connections.size()-1; j>=0; j--) {
2761            ConnectionRecord cr = app.connections.valueAt(j);
2762            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2763                    && cr.binding.service.app != null
2764                    && cr.binding.service.app.lruSeq != mLruSeq
2765                    && !cr.binding.service.app.persistent) {
2766                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2767                        "service connection", cr, app);
2768            }
2769        }
2770        for (int j=app.conProviders.size()-1; j>=0; j--) {
2771            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2772            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2773                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2774                        "provider reference", cpr, app);
2775            }
2776        }
2777    }
2778
2779    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2780        if (uid == Process.SYSTEM_UID) {
2781            // The system gets to run in any process.  If there are multiple
2782            // processes with the same uid, just pick the first (this
2783            // should never happen).
2784            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2785            if (procs == null) return null;
2786            final int N = procs.size();
2787            for (int i = 0; i < N; i++) {
2788                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2789            }
2790        }
2791        ProcessRecord proc = mProcessNames.get(processName, uid);
2792        if (false && proc != null && !keepIfLarge
2793                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2794                && proc.lastCachedPss >= 4000) {
2795            // Turn this condition on to cause killing to happen regularly, for testing.
2796            if (proc.baseProcessTracker != null) {
2797                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2798            }
2799            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2800                    + "k from cached");
2801        } else if (proc != null && !keepIfLarge
2802                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2803                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2804            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2805            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2806                if (proc.baseProcessTracker != null) {
2807                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2808                }
2809                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2810                        + "k from cached");
2811            }
2812        }
2813        return proc;
2814    }
2815
2816    void ensurePackageDexOpt(String packageName) {
2817        IPackageManager pm = AppGlobals.getPackageManager();
2818        try {
2819            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2820                mDidDexOpt = true;
2821            }
2822        } catch (RemoteException e) {
2823        }
2824    }
2825
2826    boolean isNextTransitionForward() {
2827        int transit = mWindowManager.getPendingAppTransition();
2828        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2829                || transit == AppTransition.TRANSIT_TASK_OPEN
2830                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2831    }
2832
2833    final ProcessRecord startProcessLocked(String processName,
2834            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2835            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2836            boolean isolated, boolean keepIfLarge) {
2837        ProcessRecord app;
2838        if (!isolated) {
2839            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2840        } else {
2841            // If this is an isolated process, it can't re-use an existing process.
2842            app = null;
2843        }
2844        // We don't have to do anything more if:
2845        // (1) There is an existing application record; and
2846        // (2) The caller doesn't think it is dead, OR there is no thread
2847        //     object attached to it so we know it couldn't have crashed; and
2848        // (3) There is a pid assigned to it, so it is either starting or
2849        //     already running.
2850        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2851                + " app=" + app + " knownToBeDead=" + knownToBeDead
2852                + " thread=" + (app != null ? app.thread : null)
2853                + " pid=" + (app != null ? app.pid : -1));
2854        if (app != null && app.pid > 0) {
2855            if (!knownToBeDead || app.thread == null) {
2856                // We already have the app running, or are waiting for it to
2857                // come up (we have a pid but not yet its thread), so keep it.
2858                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2859                // If this is a new package in the process, add the package to the list
2860                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2861                return app;
2862            }
2863
2864            // An application record is attached to a previous process,
2865            // clean it up now.
2866            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2867            Process.killProcessGroup(app.info.uid, app.pid);
2868            handleAppDiedLocked(app, true, true);
2869        }
2870
2871        String hostingNameStr = hostingName != null
2872                ? hostingName.flattenToShortString() : null;
2873
2874        if (!isolated) {
2875            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2876                // If we are in the background, then check to see if this process
2877                // is bad.  If so, we will just silently fail.
2878                if (mBadProcesses.get(info.processName, info.uid) != null) {
2879                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2880                            + "/" + info.processName);
2881                    return null;
2882                }
2883            } else {
2884                // When the user is explicitly starting a process, then clear its
2885                // crash count so that we won't make it bad until they see at
2886                // least one crash dialog again, and make the process good again
2887                // if it had been bad.
2888                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2889                        + "/" + info.processName);
2890                mProcessCrashTimes.remove(info.processName, info.uid);
2891                if (mBadProcesses.get(info.processName, info.uid) != null) {
2892                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2893                            UserHandle.getUserId(info.uid), info.uid,
2894                            info.processName);
2895                    mBadProcesses.remove(info.processName, info.uid);
2896                    if (app != null) {
2897                        app.bad = false;
2898                    }
2899                }
2900            }
2901        }
2902
2903        if (app == null) {
2904            app = newProcessRecordLocked(info, processName, isolated);
2905            if (app == null) {
2906                Slog.w(TAG, "Failed making new process record for "
2907                        + processName + "/" + info.uid + " isolated=" + isolated);
2908                return null;
2909            }
2910            mProcessNames.put(processName, app.uid, app);
2911            if (isolated) {
2912                mIsolatedProcesses.put(app.uid, app);
2913            }
2914        } else {
2915            // If this is a new package in the process, add the package to the list
2916            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2917        }
2918
2919        // If the system is not ready yet, then hold off on starting this
2920        // process until it is.
2921        if (!mProcessesReady
2922                && !isAllowedWhileBooting(info)
2923                && !allowWhileBooting) {
2924            if (!mProcessesOnHold.contains(app)) {
2925                mProcessesOnHold.add(app);
2926            }
2927            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2928            return app;
2929        }
2930
2931        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2932        return (app.pid != 0) ? app : null;
2933    }
2934
2935    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2936        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2937    }
2938
2939    private final void startProcessLocked(ProcessRecord app,
2940            String hostingType, String hostingNameStr, String abiOverride) {
2941        if (app.pid > 0 && app.pid != MY_PID) {
2942            synchronized (mPidsSelfLocked) {
2943                mPidsSelfLocked.remove(app.pid);
2944                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2945            }
2946            app.setPid(0);
2947        }
2948
2949        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2950                "startProcessLocked removing on hold: " + app);
2951        mProcessesOnHold.remove(app);
2952
2953        updateCpuStats();
2954
2955        try {
2956            int uid = app.uid;
2957
2958            int[] gids = null;
2959            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2960            if (!app.isolated) {
2961                int[] permGids = null;
2962                try {
2963                    final PackageManager pm = mContext.getPackageManager();
2964                    permGids = pm.getPackageGids(app.info.packageName);
2965
2966                    if (Environment.isExternalStorageEmulated()) {
2967                        if (pm.checkPermission(
2968                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2969                                app.info.packageName) == PERMISSION_GRANTED) {
2970                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2971                        } else {
2972                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2973                        }
2974                    }
2975                } catch (PackageManager.NameNotFoundException e) {
2976                    Slog.w(TAG, "Unable to retrieve gids", e);
2977                }
2978
2979                /*
2980                 * Add shared application and profile GIDs so applications can share some
2981                 * resources like shared libraries and access user-wide resources
2982                 */
2983                if (permGids == null) {
2984                    gids = new int[2];
2985                } else {
2986                    gids = new int[permGids.length + 2];
2987                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2988                }
2989                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2990                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2991            }
2992            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2993                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2994                        && mTopComponent != null
2995                        && app.processName.equals(mTopComponent.getPackageName())) {
2996                    uid = 0;
2997                }
2998                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2999                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3000                    uid = 0;
3001                }
3002            }
3003            int debugFlags = 0;
3004            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3005                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3006                // Also turn on CheckJNI for debuggable apps. It's quite
3007                // awkward to turn on otherwise.
3008                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3009            }
3010            // Run the app in safe mode if its manifest requests so or the
3011            // system is booted in safe mode.
3012            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3013                mSafeMode == true) {
3014                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3015            }
3016            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3017                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3018            }
3019            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3020                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3021            }
3022            if ("1".equals(SystemProperties.get("debug.assert"))) {
3023                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3024            }
3025
3026            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3027            if (requiredAbi == null) {
3028                requiredAbi = Build.SUPPORTED_ABIS[0];
3029            }
3030
3031            // Start the process.  It will either succeed and return a result containing
3032            // the PID of the new process, or else throw a RuntimeException.
3033            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3034                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3035                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3036
3037            if (app.isolated) {
3038                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3039            }
3040            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3041
3042            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3043                    UserHandle.getUserId(uid), startResult.pid, uid,
3044                    app.processName, hostingType,
3045                    hostingNameStr != null ? hostingNameStr : "");
3046
3047            if (app.persistent) {
3048                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3049            }
3050
3051            StringBuilder buf = mStringBuilder;
3052            buf.setLength(0);
3053            buf.append("Start proc ");
3054            buf.append(app.processName);
3055            buf.append(" for ");
3056            buf.append(hostingType);
3057            if (hostingNameStr != null) {
3058                buf.append(" ");
3059                buf.append(hostingNameStr);
3060            }
3061            buf.append(": pid=");
3062            buf.append(startResult.pid);
3063            buf.append(" uid=");
3064            buf.append(uid);
3065            buf.append(" gids={");
3066            if (gids != null) {
3067                for (int gi=0; gi<gids.length; gi++) {
3068                    if (gi != 0) buf.append(", ");
3069                    buf.append(gids[gi]);
3070
3071                }
3072            }
3073            buf.append("}");
3074            if (requiredAbi != null) {
3075                buf.append(" abi=");
3076                buf.append(requiredAbi);
3077            }
3078            Slog.i(TAG, buf.toString());
3079            app.setPid(startResult.pid);
3080            app.usingWrapper = startResult.usingWrapper;
3081            app.removed = false;
3082            app.killedByAm = false;
3083            synchronized (mPidsSelfLocked) {
3084                this.mPidsSelfLocked.put(startResult.pid, app);
3085                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3086                msg.obj = app;
3087                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3088                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3089            }
3090        } catch (RuntimeException e) {
3091            // XXX do better error recovery.
3092            app.setPid(0);
3093            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3094            if (app.isolated) {
3095                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3096            }
3097            Slog.e(TAG, "Failure starting process " + app.processName, e);
3098        }
3099    }
3100
3101    void updateUsageStats(ActivityRecord component, boolean resumed) {
3102        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3103        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3104        if (resumed) {
3105            if (mUsageStatsService != null) {
3106                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3107                        System.currentTimeMillis(),
3108                        UsageStats.Event.MOVE_TO_FOREGROUND);
3109            }
3110            synchronized (stats) {
3111                stats.noteActivityResumedLocked(component.app.uid);
3112            }
3113        } else {
3114            if (mUsageStatsService != null) {
3115                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3116                        System.currentTimeMillis(),
3117                        UsageStats.Event.MOVE_TO_BACKGROUND);
3118            }
3119            synchronized (stats) {
3120                stats.noteActivityPausedLocked(component.app.uid);
3121            }
3122        }
3123    }
3124
3125    Intent getHomeIntent() {
3126        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3127        intent.setComponent(mTopComponent);
3128        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3129            intent.addCategory(Intent.CATEGORY_HOME);
3130        }
3131        return intent;
3132    }
3133
3134    boolean startHomeActivityLocked(int userId) {
3135        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3136                && mTopAction == null) {
3137            // We are running in factory test mode, but unable to find
3138            // the factory test app, so just sit around displaying the
3139            // error message and don't try to start anything.
3140            return false;
3141        }
3142        Intent intent = getHomeIntent();
3143        ActivityInfo aInfo =
3144            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3145        if (aInfo != null) {
3146            intent.setComponent(new ComponentName(
3147                    aInfo.applicationInfo.packageName, aInfo.name));
3148            // Don't do this if the home app is currently being
3149            // instrumented.
3150            aInfo = new ActivityInfo(aInfo);
3151            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3152            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3153                    aInfo.applicationInfo.uid, true);
3154            if (app == null || app.instrumentationClass == null) {
3155                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3156                mStackSupervisor.startHomeActivity(intent, aInfo);
3157            }
3158        }
3159
3160        return true;
3161    }
3162
3163    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3164        ActivityInfo ai = null;
3165        ComponentName comp = intent.getComponent();
3166        try {
3167            if (comp != null) {
3168                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3169            } else {
3170                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3171                        intent,
3172                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3173                            flags, userId);
3174
3175                if (info != null) {
3176                    ai = info.activityInfo;
3177                }
3178            }
3179        } catch (RemoteException e) {
3180            // ignore
3181        }
3182
3183        return ai;
3184    }
3185
3186    /**
3187     * Starts the "new version setup screen" if appropriate.
3188     */
3189    void startSetupActivityLocked() {
3190        // Only do this once per boot.
3191        if (mCheckedForSetup) {
3192            return;
3193        }
3194
3195        // We will show this screen if the current one is a different
3196        // version than the last one shown, and we are not running in
3197        // low-level factory test mode.
3198        final ContentResolver resolver = mContext.getContentResolver();
3199        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3200                Settings.Global.getInt(resolver,
3201                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3202            mCheckedForSetup = true;
3203
3204            // See if we should be showing the platform update setup UI.
3205            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3206            List<ResolveInfo> ris = mContext.getPackageManager()
3207                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3208
3209            // We don't allow third party apps to replace this.
3210            ResolveInfo ri = null;
3211            for (int i=0; ris != null && i<ris.size(); i++) {
3212                if ((ris.get(i).activityInfo.applicationInfo.flags
3213                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3214                    ri = ris.get(i);
3215                    break;
3216                }
3217            }
3218
3219            if (ri != null) {
3220                String vers = ri.activityInfo.metaData != null
3221                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3222                        : null;
3223                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3224                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3225                            Intent.METADATA_SETUP_VERSION);
3226                }
3227                String lastVers = Settings.Secure.getString(
3228                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3229                if (vers != null && !vers.equals(lastVers)) {
3230                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3231                    intent.setComponent(new ComponentName(
3232                            ri.activityInfo.packageName, ri.activityInfo.name));
3233                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3234                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3235                }
3236            }
3237        }
3238    }
3239
3240    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3241        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3242    }
3243
3244    void enforceNotIsolatedCaller(String caller) {
3245        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3246            throw new SecurityException("Isolated process not allowed to call " + caller);
3247        }
3248    }
3249
3250    @Override
3251    public int getFrontActivityScreenCompatMode() {
3252        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3253        synchronized (this) {
3254            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3255        }
3256    }
3257
3258    @Override
3259    public void setFrontActivityScreenCompatMode(int mode) {
3260        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3261                "setFrontActivityScreenCompatMode");
3262        synchronized (this) {
3263            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3264        }
3265    }
3266
3267    @Override
3268    public int getPackageScreenCompatMode(String packageName) {
3269        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3270        synchronized (this) {
3271            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3272        }
3273    }
3274
3275    @Override
3276    public void setPackageScreenCompatMode(String packageName, int mode) {
3277        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3278                "setPackageScreenCompatMode");
3279        synchronized (this) {
3280            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3281        }
3282    }
3283
3284    @Override
3285    public boolean getPackageAskScreenCompat(String packageName) {
3286        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3287        synchronized (this) {
3288            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3289        }
3290    }
3291
3292    @Override
3293    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3294        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3295                "setPackageAskScreenCompat");
3296        synchronized (this) {
3297            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3298        }
3299    }
3300
3301    private void dispatchProcessesChanged() {
3302        int N;
3303        synchronized (this) {
3304            N = mPendingProcessChanges.size();
3305            if (mActiveProcessChanges.length < N) {
3306                mActiveProcessChanges = new ProcessChangeItem[N];
3307            }
3308            mPendingProcessChanges.toArray(mActiveProcessChanges);
3309            mAvailProcessChanges.addAll(mPendingProcessChanges);
3310            mPendingProcessChanges.clear();
3311            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3312        }
3313
3314        int i = mProcessObservers.beginBroadcast();
3315        while (i > 0) {
3316            i--;
3317            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3318            if (observer != null) {
3319                try {
3320                    for (int j=0; j<N; j++) {
3321                        ProcessChangeItem item = mActiveProcessChanges[j];
3322                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": "
3325                                    + item.foregroundActivities);
3326                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3327                                    item.foregroundActivities);
3328                        }
3329                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3330                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3331                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3332                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3333                        }
3334                    }
3335                } catch (RemoteException e) {
3336                }
3337            }
3338        }
3339        mProcessObservers.finishBroadcast();
3340    }
3341
3342    private void dispatchProcessDied(int pid, int uid) {
3343        int i = mProcessObservers.beginBroadcast();
3344        while (i > 0) {
3345            i--;
3346            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3347            if (observer != null) {
3348                try {
3349                    observer.onProcessDied(pid, uid);
3350                } catch (RemoteException e) {
3351                }
3352            }
3353        }
3354        mProcessObservers.finishBroadcast();
3355    }
3356
3357    @Override
3358    public final int startActivity(IApplicationThread caller, String callingPackage,
3359            Intent intent, String resolvedType, IBinder resultTo,
3360            String resultWho, int requestCode, int startFlags,
3361            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3362        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3363                resultWho, requestCode,
3364                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3365    }
3366
3367    @Override
3368    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3369            Intent intent, String resolvedType, IBinder resultTo,
3370            String resultWho, int requestCode, int startFlags,
3371            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3372        enforceNotIsolatedCaller("startActivity");
3373        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3374                false, ALLOW_FULL_ONLY, "startActivity", null);
3375        // TODO: Switch to user app stacks here.
3376        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3377                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3378                null, null, options, userId, null);
3379    }
3380
3381    @Override
3382    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3383            Intent intent, String resolvedType, IBinder resultTo,
3384            String resultWho, int requestCode, int startFlags, String profileFile,
3385            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3386        enforceNotIsolatedCaller("startActivityAndWait");
3387        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3388                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3389        WaitResult res = new WaitResult();
3390        // TODO: Switch to user app stacks here.
3391        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3392                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3393                res, null, options, userId, null);
3394        return res;
3395    }
3396
3397    @Override
3398    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3399            Intent intent, String resolvedType, IBinder resultTo,
3400            String resultWho, int requestCode, int startFlags, Configuration config,
3401            Bundle options, int userId) {
3402        enforceNotIsolatedCaller("startActivityWithConfig");
3403        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3404                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3405        // TODO: Switch to user app stacks here.
3406        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3407                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3408                null, null, null, config, options, userId, null);
3409        return ret;
3410    }
3411
3412    @Override
3413    public int startActivityIntentSender(IApplicationThread caller,
3414            IntentSender intent, Intent fillInIntent, String resolvedType,
3415            IBinder resultTo, String resultWho, int requestCode,
3416            int flagsMask, int flagsValues, Bundle options) {
3417        enforceNotIsolatedCaller("startActivityIntentSender");
3418        // Refuse possible leaked file descriptors
3419        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3420            throw new IllegalArgumentException("File descriptors passed in Intent");
3421        }
3422
3423        IIntentSender sender = intent.getTarget();
3424        if (!(sender instanceof PendingIntentRecord)) {
3425            throw new IllegalArgumentException("Bad PendingIntent object");
3426        }
3427
3428        PendingIntentRecord pir = (PendingIntentRecord)sender;
3429
3430        synchronized (this) {
3431            // If this is coming from the currently resumed activity, it is
3432            // effectively saying that app switches are allowed at this point.
3433            final ActivityStack stack = getFocusedStack();
3434            if (stack.mResumedActivity != null &&
3435                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3436                mAppSwitchesAllowedTime = 0;
3437            }
3438        }
3439        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3440                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3441        return ret;
3442    }
3443
3444    @Override
3445    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3446            Intent intent, String resolvedType, IVoiceInteractionSession session,
3447            IVoiceInteractor interactor, int startFlags, String profileFile,
3448            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3449        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3450                != PackageManager.PERMISSION_GRANTED) {
3451            String msg = "Permission Denial: startVoiceActivity() from pid="
3452                    + Binder.getCallingPid()
3453                    + ", uid=" + Binder.getCallingUid()
3454                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3455            Slog.w(TAG, msg);
3456            throw new SecurityException(msg);
3457        }
3458        if (session == null || interactor == null) {
3459            throw new NullPointerException("null session or interactor");
3460        }
3461        userId = handleIncomingUser(callingPid, callingUid, userId,
3462                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3463        // TODO: Switch to user app stacks here.
3464        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3465                resolvedType, session, interactor, null, null, 0, startFlags,
3466                profileFile, profileFd, null, null, options, userId, null);
3467    }
3468
3469    @Override
3470    public boolean startNextMatchingActivity(IBinder callingActivity,
3471            Intent intent, Bundle options) {
3472        // Refuse possible leaked file descriptors
3473        if (intent != null && intent.hasFileDescriptors() == true) {
3474            throw new IllegalArgumentException("File descriptors passed in Intent");
3475        }
3476
3477        synchronized (this) {
3478            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3479            if (r == null) {
3480                ActivityOptions.abort(options);
3481                return false;
3482            }
3483            if (r.app == null || r.app.thread == null) {
3484                // The caller is not running...  d'oh!
3485                ActivityOptions.abort(options);
3486                return false;
3487            }
3488            intent = new Intent(intent);
3489            // The caller is not allowed to change the data.
3490            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3491            // And we are resetting to find the next component...
3492            intent.setComponent(null);
3493
3494            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3495
3496            ActivityInfo aInfo = null;
3497            try {
3498                List<ResolveInfo> resolves =
3499                    AppGlobals.getPackageManager().queryIntentActivities(
3500                            intent, r.resolvedType,
3501                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3502                            UserHandle.getCallingUserId());
3503
3504                // Look for the original activity in the list...
3505                final int N = resolves != null ? resolves.size() : 0;
3506                for (int i=0; i<N; i++) {
3507                    ResolveInfo rInfo = resolves.get(i);
3508                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3509                            && rInfo.activityInfo.name.equals(r.info.name)) {
3510                        // We found the current one...  the next matching is
3511                        // after it.
3512                        i++;
3513                        if (i<N) {
3514                            aInfo = resolves.get(i).activityInfo;
3515                        }
3516                        if (debug) {
3517                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3518                                    + "/" + r.info.name);
3519                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3520                                    + "/" + aInfo.name);
3521                        }
3522                        break;
3523                    }
3524                }
3525            } catch (RemoteException e) {
3526            }
3527
3528            if (aInfo == null) {
3529                // Nobody who is next!
3530                ActivityOptions.abort(options);
3531                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3532                return false;
3533            }
3534
3535            intent.setComponent(new ComponentName(
3536                    aInfo.applicationInfo.packageName, aInfo.name));
3537            intent.setFlags(intent.getFlags()&~(
3538                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3539                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3540                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3541                    Intent.FLAG_ACTIVITY_NEW_TASK));
3542
3543            // Okay now we need to start the new activity, replacing the
3544            // currently running activity.  This is a little tricky because
3545            // we want to start the new one as if the current one is finished,
3546            // but not finish the current one first so that there is no flicker.
3547            // And thus...
3548            final boolean wasFinishing = r.finishing;
3549            r.finishing = true;
3550
3551            // Propagate reply information over to the new activity.
3552            final ActivityRecord resultTo = r.resultTo;
3553            final String resultWho = r.resultWho;
3554            final int requestCode = r.requestCode;
3555            r.resultTo = null;
3556            if (resultTo != null) {
3557                resultTo.removeResultsLocked(r, resultWho, requestCode);
3558            }
3559
3560            final long origId = Binder.clearCallingIdentity();
3561            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3562                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3563                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3564                    options, false, null, null);
3565            Binder.restoreCallingIdentity(origId);
3566
3567            r.finishing = wasFinishing;
3568            if (res != ActivityManager.START_SUCCESS) {
3569                return false;
3570            }
3571            return true;
3572        }
3573    }
3574
3575    @Override
3576    public final int startActivityFromRecents(int taskId, Bundle options) {
3577        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3578            String msg = "Permission Denial: startActivityFromRecents called without " +
3579                    START_TASKS_FROM_RECENTS;
3580            Slog.w(TAG, msg);
3581            throw new SecurityException(msg);
3582        }
3583        final int callingUid;
3584        final String callingPackage;
3585        final Intent intent;
3586        final int userId;
3587        synchronized (this) {
3588            final TaskRecord task = recentTaskForIdLocked(taskId);
3589            if (task == null) {
3590                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3591            }
3592            callingUid = task.mCallingUid;
3593            callingPackage = task.mCallingPackage;
3594            intent = task.intent;
3595            userId = task.userId;
3596        }
3597        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3598                options, userId, null);
3599    }
3600
3601    final int startActivityInPackage(int uid, String callingPackage,
3602            Intent intent, String resolvedType, IBinder resultTo,
3603            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3604                    IActivityContainer container) {
3605
3606        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3607                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3608
3609        // TODO: Switch to user app stacks here.
3610        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3611                null, null, resultTo, resultWho, requestCode, startFlags,
3612                null, null, null, null, options, userId, container);
3613        return ret;
3614    }
3615
3616    @Override
3617    public final int startActivities(IApplicationThread caller, String callingPackage,
3618            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3619            int userId) {
3620        enforceNotIsolatedCaller("startActivities");
3621        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3622                false, ALLOW_FULL_ONLY, "startActivity", null);
3623        // TODO: Switch to user app stacks here.
3624        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3625                resolvedTypes, resultTo, options, userId);
3626        return ret;
3627    }
3628
3629    final int startActivitiesInPackage(int uid, String callingPackage,
3630            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3631            Bundle options, int userId) {
3632
3633        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3634                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3635        // TODO: Switch to user app stacks here.
3636        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3637                resultTo, options, userId);
3638        return ret;
3639    }
3640
3641    final void addRecentTaskLocked(TaskRecord task) {
3642        int N = mRecentTasks.size();
3643        // Quick case: check if the top-most recent task is the same.
3644        if (N > 0 && mRecentTasks.get(0) == task) {
3645            return;
3646        }
3647        // Another quick case: never add voice sessions.
3648        if (task.voiceSession != null) {
3649            return;
3650        }
3651        // Remove any existing entries that are the same kind of task.
3652        final Intent intent = task.intent;
3653        final boolean document = intent != null && intent.isDocument();
3654        final ComponentName comp = intent.getComponent();
3655
3656        int maxRecents = task.maxRecents - 1;
3657        for (int i=0; i<N; i++) {
3658            final TaskRecord tr = mRecentTasks.get(i);
3659            if (task != tr) {
3660                if (task.userId != tr.userId) {
3661                    continue;
3662                }
3663                if (i > MAX_RECENT_BITMAPS) {
3664                    tr.freeLastThumbnail();
3665                }
3666                final Intent trIntent = tr.intent;
3667                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3668                    (intent == null || !intent.filterEquals(trIntent))) {
3669                    continue;
3670                }
3671                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3672                if (document && trIsDocument) {
3673                    // These are the same document activity (not necessarily the same doc).
3674                    if (maxRecents > 0) {
3675                        --maxRecents;
3676                        continue;
3677                    }
3678                    // Hit the maximum number of documents for this task. Fall through
3679                    // and remove this document from recents.
3680                } else if (document || trIsDocument) {
3681                    // Only one of these is a document. Not the droid we're looking for.
3682                    continue;
3683                }
3684            }
3685
3686            // Either task and tr are the same or, their affinities match or their intents match
3687            // and neither of them is a document, or they are documents using the same activity
3688            // and their maxRecents has been reached.
3689            tr.disposeThumbnail();
3690            mRecentTasks.remove(i);
3691            if (task != tr) {
3692                tr.closeRecentsChain();
3693            }
3694            i--;
3695            N--;
3696            if (task.intent == null) {
3697                // If the new recent task we are adding is not fully
3698                // specified, then replace it with the existing recent task.
3699                task = tr;
3700            }
3701            mTaskPersister.notify(tr, false);
3702        }
3703        if (N >= MAX_RECENT_TASKS) {
3704            final TaskRecord tr = mRecentTasks.remove(N - 1);
3705            tr.disposeThumbnail();
3706            tr.closeRecentsChain();
3707        }
3708        mRecentTasks.add(0, task);
3709    }
3710
3711    @Override
3712    public void reportActivityFullyDrawn(IBinder token) {
3713        synchronized (this) {
3714            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3715            if (r == null) {
3716                return;
3717            }
3718            r.reportFullyDrawnLocked();
3719        }
3720    }
3721
3722    @Override
3723    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3724        synchronized (this) {
3725            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3726            if (r == null) {
3727                return;
3728            }
3729            final long origId = Binder.clearCallingIdentity();
3730            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3731            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3732                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3733            if (config != null) {
3734                r.frozenBeforeDestroy = true;
3735                if (!updateConfigurationLocked(config, r, false, false)) {
3736                    mStackSupervisor.resumeTopActivitiesLocked();
3737                }
3738            }
3739            Binder.restoreCallingIdentity(origId);
3740        }
3741    }
3742
3743    @Override
3744    public int getRequestedOrientation(IBinder token) {
3745        synchronized (this) {
3746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3747            if (r == null) {
3748                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3749            }
3750            return mWindowManager.getAppOrientation(r.appToken);
3751        }
3752    }
3753
3754    /**
3755     * This is the internal entry point for handling Activity.finish().
3756     *
3757     * @param token The Binder token referencing the Activity we want to finish.
3758     * @param resultCode Result code, if any, from this Activity.
3759     * @param resultData Result data (Intent), if any, from this Activity.
3760     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3761     *            the root Activity in the task.
3762     *
3763     * @return Returns true if the activity successfully finished, or false if it is still running.
3764     */
3765    @Override
3766    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3767            boolean finishTask) {
3768        // Refuse possible leaked file descriptors
3769        if (resultData != null && resultData.hasFileDescriptors() == true) {
3770            throw new IllegalArgumentException("File descriptors passed in Intent");
3771        }
3772
3773        synchronized(this) {
3774            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3775            if (r == null) {
3776                return true;
3777            }
3778            // Keep track of the root activity of the task before we finish it
3779            TaskRecord tr = r.task;
3780            ActivityRecord rootR = tr.getRootActivity();
3781            // Do not allow task to finish in Lock Task mode.
3782            if (tr == mStackSupervisor.mLockTaskModeTask) {
3783                if (rootR == r) {
3784                    mStackSupervisor.showLockTaskToast();
3785                    return false;
3786                }
3787            }
3788            if (mController != null) {
3789                // Find the first activity that is not finishing.
3790                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3791                if (next != null) {
3792                    // ask watcher if this is allowed
3793                    boolean resumeOK = true;
3794                    try {
3795                        resumeOK = mController.activityResuming(next.packageName);
3796                    } catch (RemoteException e) {
3797                        mController = null;
3798                        Watchdog.getInstance().setActivityController(null);
3799                    }
3800
3801                    if (!resumeOK) {
3802                        return false;
3803                    }
3804                }
3805            }
3806            final long origId = Binder.clearCallingIdentity();
3807            try {
3808                boolean res;
3809                if (finishTask && r == rootR) {
3810                    // If requested, remove the task that is associated to this activity only if it
3811                    // was the root activity in the task.  The result code and data is ignored because
3812                    // we don't support returning them across task boundaries.
3813                    res = removeTaskByIdLocked(tr.taskId, 0);
3814                } else {
3815                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3816                            resultData, "app-request", true);
3817                }
3818                return res;
3819            } finally {
3820                Binder.restoreCallingIdentity(origId);
3821            }
3822        }
3823    }
3824
3825    @Override
3826    public final void finishHeavyWeightApp() {
3827        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3828                != PackageManager.PERMISSION_GRANTED) {
3829            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3830                    + Binder.getCallingPid()
3831                    + ", uid=" + Binder.getCallingUid()
3832                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3833            Slog.w(TAG, msg);
3834            throw new SecurityException(msg);
3835        }
3836
3837        synchronized(this) {
3838            if (mHeavyWeightProcess == null) {
3839                return;
3840            }
3841
3842            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3843                    mHeavyWeightProcess.activities);
3844            for (int i=0; i<activities.size(); i++) {
3845                ActivityRecord r = activities.get(i);
3846                if (!r.finishing) {
3847                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3848                            null, "finish-heavy", true);
3849                }
3850            }
3851
3852            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3853                    mHeavyWeightProcess.userId, 0));
3854            mHeavyWeightProcess = null;
3855        }
3856    }
3857
3858    @Override
3859    public void crashApplication(int uid, int initialPid, String packageName,
3860            String message) {
3861        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3862                != PackageManager.PERMISSION_GRANTED) {
3863            String msg = "Permission Denial: crashApplication() from pid="
3864                    + Binder.getCallingPid()
3865                    + ", uid=" + Binder.getCallingUid()
3866                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3867            Slog.w(TAG, msg);
3868            throw new SecurityException(msg);
3869        }
3870
3871        synchronized(this) {
3872            ProcessRecord proc = null;
3873
3874            // Figure out which process to kill.  We don't trust that initialPid
3875            // still has any relation to current pids, so must scan through the
3876            // list.
3877            synchronized (mPidsSelfLocked) {
3878                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3879                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3880                    if (p.uid != uid) {
3881                        continue;
3882                    }
3883                    if (p.pid == initialPid) {
3884                        proc = p;
3885                        break;
3886                    }
3887                    if (p.pkgList.containsKey(packageName)) {
3888                        proc = p;
3889                    }
3890                }
3891            }
3892
3893            if (proc == null) {
3894                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3895                        + " initialPid=" + initialPid
3896                        + " packageName=" + packageName);
3897                return;
3898            }
3899
3900            if (proc.thread != null) {
3901                if (proc.pid == Process.myPid()) {
3902                    Log.w(TAG, "crashApplication: trying to crash self!");
3903                    return;
3904                }
3905                long ident = Binder.clearCallingIdentity();
3906                try {
3907                    proc.thread.scheduleCrash(message);
3908                } catch (RemoteException e) {
3909                }
3910                Binder.restoreCallingIdentity(ident);
3911            }
3912        }
3913    }
3914
3915    @Override
3916    public final void finishSubActivity(IBinder token, String resultWho,
3917            int requestCode) {
3918        synchronized(this) {
3919            final long origId = Binder.clearCallingIdentity();
3920            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3921            if (r != null) {
3922                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3923            }
3924            Binder.restoreCallingIdentity(origId);
3925        }
3926    }
3927
3928    @Override
3929    public boolean finishActivityAffinity(IBinder token) {
3930        synchronized(this) {
3931            final long origId = Binder.clearCallingIdentity();
3932            try {
3933                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3934
3935                ActivityRecord rootR = r.task.getRootActivity();
3936                // Do not allow task to finish in Lock Task mode.
3937                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3938                    if (rootR == r) {
3939                        mStackSupervisor.showLockTaskToast();
3940                        return false;
3941                    }
3942                }
3943                boolean res = false;
3944                if (r != null) {
3945                    res = r.task.stack.finishActivityAffinityLocked(r);
3946                }
3947                return res;
3948            } finally {
3949                Binder.restoreCallingIdentity(origId);
3950            }
3951        }
3952    }
3953
3954    @Override
3955    public void finishVoiceTask(IVoiceInteractionSession session) {
3956        synchronized(this) {
3957            final long origId = Binder.clearCallingIdentity();
3958            try {
3959                mStackSupervisor.finishVoiceTask(session);
3960            } finally {
3961                Binder.restoreCallingIdentity(origId);
3962            }
3963        }
3964
3965    }
3966
3967    @Override
3968    public boolean willActivityBeVisible(IBinder token) {
3969        synchronized(this) {
3970            ActivityStack stack = ActivityRecord.getStackLocked(token);
3971            if (stack != null) {
3972                return stack.willActivityBeVisibleLocked(token);
3973            }
3974            return false;
3975        }
3976    }
3977
3978    @Override
3979    public void overridePendingTransition(IBinder token, String packageName,
3980            int enterAnim, int exitAnim) {
3981        synchronized(this) {
3982            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3983            if (self == null) {
3984                return;
3985            }
3986
3987            final long origId = Binder.clearCallingIdentity();
3988
3989            if (self.state == ActivityState.RESUMED
3990                    || self.state == ActivityState.PAUSING) {
3991                mWindowManager.overridePendingAppTransition(packageName,
3992                        enterAnim, exitAnim, null);
3993            }
3994
3995            Binder.restoreCallingIdentity(origId);
3996        }
3997    }
3998
3999    /**
4000     * Main function for removing an existing process from the activity manager
4001     * as a result of that process going away.  Clears out all connections
4002     * to the process.
4003     */
4004    private final void handleAppDiedLocked(ProcessRecord app,
4005            boolean restarting, boolean allowRestart) {
4006        int pid = app.pid;
4007        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4008        if (!restarting) {
4009            removeLruProcessLocked(app);
4010            if (pid > 0) {
4011                ProcessList.remove(pid);
4012            }
4013        }
4014
4015        if (mProfileProc == app) {
4016            clearProfilerLocked();
4017        }
4018
4019        // Remove this application's activities from active lists.
4020        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4021
4022        app.activities.clear();
4023
4024        if (app.instrumentationClass != null) {
4025            Slog.w(TAG, "Crash of app " + app.processName
4026                  + " running instrumentation " + app.instrumentationClass);
4027            Bundle info = new Bundle();
4028            info.putString("shortMsg", "Process crashed.");
4029            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4030        }
4031
4032        if (!restarting) {
4033            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4034                // If there was nothing to resume, and we are not already
4035                // restarting this process, but there is a visible activity that
4036                // is hosted by the process...  then make sure all visible
4037                // activities are running, taking care of restarting this
4038                // process.
4039                if (hasVisibleActivities) {
4040                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4041                }
4042            }
4043        }
4044    }
4045
4046    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4047        IBinder threadBinder = thread.asBinder();
4048        // Find the application record.
4049        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4050            ProcessRecord rec = mLruProcesses.get(i);
4051            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4052                return i;
4053            }
4054        }
4055        return -1;
4056    }
4057
4058    final ProcessRecord getRecordForAppLocked(
4059            IApplicationThread thread) {
4060        if (thread == null) {
4061            return null;
4062        }
4063
4064        int appIndex = getLRURecordIndexForAppLocked(thread);
4065        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4066    }
4067
4068    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4069        // If there are no longer any background processes running,
4070        // and the app that died was not running instrumentation,
4071        // then tell everyone we are now low on memory.
4072        boolean haveBg = false;
4073        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4074            ProcessRecord rec = mLruProcesses.get(i);
4075            if (rec.thread != null
4076                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4077                haveBg = true;
4078                break;
4079            }
4080        }
4081
4082        if (!haveBg) {
4083            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4084            if (doReport) {
4085                long now = SystemClock.uptimeMillis();
4086                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4087                    doReport = false;
4088                } else {
4089                    mLastMemUsageReportTime = now;
4090                }
4091            }
4092            final ArrayList<ProcessMemInfo> memInfos
4093                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4094            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4095            long now = SystemClock.uptimeMillis();
4096            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4097                ProcessRecord rec = mLruProcesses.get(i);
4098                if (rec == dyingProc || rec.thread == null) {
4099                    continue;
4100                }
4101                if (doReport) {
4102                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4103                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4104                }
4105                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4106                    // The low memory report is overriding any current
4107                    // state for a GC request.  Make sure to do
4108                    // heavy/important/visible/foreground processes first.
4109                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4110                        rec.lastRequestedGc = 0;
4111                    } else {
4112                        rec.lastRequestedGc = rec.lastLowMemory;
4113                    }
4114                    rec.reportLowMemory = true;
4115                    rec.lastLowMemory = now;
4116                    mProcessesToGc.remove(rec);
4117                    addProcessToGcListLocked(rec);
4118                }
4119            }
4120            if (doReport) {
4121                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4122                mHandler.sendMessage(msg);
4123            }
4124            scheduleAppGcsLocked();
4125        }
4126    }
4127
4128    final void appDiedLocked(ProcessRecord app, int pid,
4129            IApplicationThread thread) {
4130
4131        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4132        synchronized (stats) {
4133            stats.noteProcessDiedLocked(app.info.uid, pid);
4134        }
4135
4136        Process.killProcessGroup(app.info.uid, pid);
4137
4138        // Clean up already done if the process has been re-started.
4139        if (app.pid == pid && app.thread != null &&
4140                app.thread.asBinder() == thread.asBinder()) {
4141            boolean doLowMem = app.instrumentationClass == null;
4142            boolean doOomAdj = doLowMem;
4143            if (!app.killedByAm) {
4144                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4145                        + ") has died.");
4146                mAllowLowerMemLevel = true;
4147            } else {
4148                // Note that we always want to do oom adj to update our state with the
4149                // new number of procs.
4150                mAllowLowerMemLevel = false;
4151                doLowMem = false;
4152            }
4153            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4154            if (DEBUG_CLEANUP) Slog.v(
4155                TAG, "Dying app: " + app + ", pid: " + pid
4156                + ", thread: " + thread.asBinder());
4157            handleAppDiedLocked(app, false, true);
4158
4159            if (doOomAdj) {
4160                updateOomAdjLocked();
4161            }
4162            if (doLowMem) {
4163                doLowMemReportIfNeededLocked(app);
4164            }
4165        } else if (app.pid != pid) {
4166            // A new process has already been started.
4167            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4168                    + ") has died and restarted (pid " + app.pid + ").");
4169            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4170        } else if (DEBUG_PROCESSES) {
4171            Slog.d(TAG, "Received spurious death notification for thread "
4172                    + thread.asBinder());
4173        }
4174    }
4175
4176    /**
4177     * If a stack trace dump file is configured, dump process stack traces.
4178     * @param clearTraces causes the dump file to be erased prior to the new
4179     *    traces being written, if true; when false, the new traces will be
4180     *    appended to any existing file content.
4181     * @param firstPids of dalvik VM processes to dump stack traces for first
4182     * @param lastPids of dalvik VM processes to dump stack traces for last
4183     * @param nativeProcs optional list of native process names to dump stack crawls
4184     * @return file containing stack traces, or null if no dump file is configured
4185     */
4186    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4187            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4188        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4189        if (tracesPath == null || tracesPath.length() == 0) {
4190            return null;
4191        }
4192
4193        File tracesFile = new File(tracesPath);
4194        try {
4195            File tracesDir = tracesFile.getParentFile();
4196            if (!tracesDir.exists()) {
4197                tracesFile.mkdirs();
4198                if (!SELinux.restorecon(tracesDir)) {
4199                    return null;
4200                }
4201            }
4202            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4203
4204            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4205            tracesFile.createNewFile();
4206            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4207        } catch (IOException e) {
4208            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4209            return null;
4210        }
4211
4212        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4213        return tracesFile;
4214    }
4215
4216    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4217            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4218        // Use a FileObserver to detect when traces finish writing.
4219        // The order of traces is considered important to maintain for legibility.
4220        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4221            @Override
4222            public synchronized void onEvent(int event, String path) { notify(); }
4223        };
4224
4225        try {
4226            observer.startWatching();
4227
4228            // First collect all of the stacks of the most important pids.
4229            if (firstPids != null) {
4230                try {
4231                    int num = firstPids.size();
4232                    for (int i = 0; i < num; i++) {
4233                        synchronized (observer) {
4234                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4235                            observer.wait(200);  // Wait for write-close, give up after 200msec
4236                        }
4237                    }
4238                } catch (InterruptedException e) {
4239                    Log.wtf(TAG, e);
4240                }
4241            }
4242
4243            // Next collect the stacks of the native pids
4244            if (nativeProcs != null) {
4245                int[] pids = Process.getPidsForCommands(nativeProcs);
4246                if (pids != null) {
4247                    for (int pid : pids) {
4248                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4249                    }
4250                }
4251            }
4252
4253            // Lastly, measure CPU usage.
4254            if (processCpuTracker != null) {
4255                processCpuTracker.init();
4256                System.gc();
4257                processCpuTracker.update();
4258                try {
4259                    synchronized (processCpuTracker) {
4260                        processCpuTracker.wait(500); // measure over 1/2 second.
4261                    }
4262                } catch (InterruptedException e) {
4263                }
4264                processCpuTracker.update();
4265
4266                // We'll take the stack crawls of just the top apps using CPU.
4267                final int N = processCpuTracker.countWorkingStats();
4268                int numProcs = 0;
4269                for (int i=0; i<N && numProcs<5; i++) {
4270                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4271                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4272                        numProcs++;
4273                        try {
4274                            synchronized (observer) {
4275                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4276                                observer.wait(200);  // Wait for write-close, give up after 200msec
4277                            }
4278                        } catch (InterruptedException e) {
4279                            Log.wtf(TAG, e);
4280                        }
4281
4282                    }
4283                }
4284            }
4285        } finally {
4286            observer.stopWatching();
4287        }
4288    }
4289
4290    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4291        if (true || IS_USER_BUILD) {
4292            return;
4293        }
4294        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4295        if (tracesPath == null || tracesPath.length() == 0) {
4296            return;
4297        }
4298
4299        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4300        StrictMode.allowThreadDiskWrites();
4301        try {
4302            final File tracesFile = new File(tracesPath);
4303            final File tracesDir = tracesFile.getParentFile();
4304            final File tracesTmp = new File(tracesDir, "__tmp__");
4305            try {
4306                if (!tracesDir.exists()) {
4307                    tracesFile.mkdirs();
4308                    if (!SELinux.restorecon(tracesDir.getPath())) {
4309                        return;
4310                    }
4311                }
4312                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4313
4314                if (tracesFile.exists()) {
4315                    tracesTmp.delete();
4316                    tracesFile.renameTo(tracesTmp);
4317                }
4318                StringBuilder sb = new StringBuilder();
4319                Time tobj = new Time();
4320                tobj.set(System.currentTimeMillis());
4321                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4322                sb.append(": ");
4323                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4324                sb.append(" since ");
4325                sb.append(msg);
4326                FileOutputStream fos = new FileOutputStream(tracesFile);
4327                fos.write(sb.toString().getBytes());
4328                if (app == null) {
4329                    fos.write("\n*** No application process!".getBytes());
4330                }
4331                fos.close();
4332                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4333            } catch (IOException e) {
4334                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4335                return;
4336            }
4337
4338            if (app != null) {
4339                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4340                firstPids.add(app.pid);
4341                dumpStackTraces(tracesPath, firstPids, null, null, null);
4342            }
4343
4344            File lastTracesFile = null;
4345            File curTracesFile = null;
4346            for (int i=9; i>=0; i--) {
4347                String name = String.format(Locale.US, "slow%02d.txt", i);
4348                curTracesFile = new File(tracesDir, name);
4349                if (curTracesFile.exists()) {
4350                    if (lastTracesFile != null) {
4351                        curTracesFile.renameTo(lastTracesFile);
4352                    } else {
4353                        curTracesFile.delete();
4354                    }
4355                }
4356                lastTracesFile = curTracesFile;
4357            }
4358            tracesFile.renameTo(curTracesFile);
4359            if (tracesTmp.exists()) {
4360                tracesTmp.renameTo(tracesFile);
4361            }
4362        } finally {
4363            StrictMode.setThreadPolicy(oldPolicy);
4364        }
4365    }
4366
4367    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4368            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4369        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4370        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4371
4372        if (mController != null) {
4373            try {
4374                // 0 == continue, -1 = kill process immediately
4375                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4376                if (res < 0 && app.pid != MY_PID) {
4377                    Process.killProcess(app.pid);
4378                    Process.killProcessGroup(app.info.uid, app.pid);
4379                }
4380            } catch (RemoteException e) {
4381                mController = null;
4382                Watchdog.getInstance().setActivityController(null);
4383            }
4384        }
4385
4386        long anrTime = SystemClock.uptimeMillis();
4387        if (MONITOR_CPU_USAGE) {
4388            updateCpuStatsNow();
4389        }
4390
4391        synchronized (this) {
4392            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4393            if (mShuttingDown) {
4394                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4395                return;
4396            } else if (app.notResponding) {
4397                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4398                return;
4399            } else if (app.crashing) {
4400                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4401                return;
4402            }
4403
4404            // In case we come through here for the same app before completing
4405            // this one, mark as anring now so we will bail out.
4406            app.notResponding = true;
4407
4408            // Log the ANR to the event log.
4409            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4410                    app.processName, app.info.flags, annotation);
4411
4412            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4413            firstPids.add(app.pid);
4414
4415            int parentPid = app.pid;
4416            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4417            if (parentPid != app.pid) firstPids.add(parentPid);
4418
4419            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4420
4421            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4422                ProcessRecord r = mLruProcesses.get(i);
4423                if (r != null && r.thread != null) {
4424                    int pid = r.pid;
4425                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4426                        if (r.persistent) {
4427                            firstPids.add(pid);
4428                        } else {
4429                            lastPids.put(pid, Boolean.TRUE);
4430                        }
4431                    }
4432                }
4433            }
4434        }
4435
4436        // Log the ANR to the main log.
4437        StringBuilder info = new StringBuilder();
4438        info.setLength(0);
4439        info.append("ANR in ").append(app.processName);
4440        if (activity != null && activity.shortComponentName != null) {
4441            info.append(" (").append(activity.shortComponentName).append(")");
4442        }
4443        info.append("\n");
4444        info.append("PID: ").append(app.pid).append("\n");
4445        if (annotation != null) {
4446            info.append("Reason: ").append(annotation).append("\n");
4447        }
4448        if (parent != null && parent != activity) {
4449            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4450        }
4451
4452        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4453
4454        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4455                NATIVE_STACKS_OF_INTEREST);
4456
4457        String cpuInfo = null;
4458        if (MONITOR_CPU_USAGE) {
4459            updateCpuStatsNow();
4460            synchronized (mProcessCpuThread) {
4461                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4462            }
4463            info.append(processCpuTracker.printCurrentLoad());
4464            info.append(cpuInfo);
4465        }
4466
4467        info.append(processCpuTracker.printCurrentState(anrTime));
4468
4469        Slog.e(TAG, info.toString());
4470        if (tracesFile == null) {
4471            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4472            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4473        }
4474
4475        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4476                cpuInfo, tracesFile, null);
4477
4478        if (mController != null) {
4479            try {
4480                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4481                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4482                if (res != 0) {
4483                    if (res < 0 && app.pid != MY_PID) {
4484                        Process.killProcess(app.pid);
4485                        Process.killProcessGroup(app.info.uid, app.pid);
4486                    } else {
4487                        synchronized (this) {
4488                            mServices.scheduleServiceTimeoutLocked(app);
4489                        }
4490                    }
4491                    return;
4492                }
4493            } catch (RemoteException e) {
4494                mController = null;
4495                Watchdog.getInstance().setActivityController(null);
4496            }
4497        }
4498
4499        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4500        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4501                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4502
4503        synchronized (this) {
4504            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4505                killUnneededProcessLocked(app, "background ANR");
4506                return;
4507            }
4508
4509            // Set the app's notResponding state, and look up the errorReportReceiver
4510            makeAppNotRespondingLocked(app,
4511                    activity != null ? activity.shortComponentName : null,
4512                    annotation != null ? "ANR " + annotation : "ANR",
4513                    info.toString());
4514
4515            // Bring up the infamous App Not Responding dialog
4516            Message msg = Message.obtain();
4517            HashMap<String, Object> map = new HashMap<String, Object>();
4518            msg.what = SHOW_NOT_RESPONDING_MSG;
4519            msg.obj = map;
4520            msg.arg1 = aboveSystem ? 1 : 0;
4521            map.put("app", app);
4522            if (activity != null) {
4523                map.put("activity", activity);
4524            }
4525
4526            mHandler.sendMessage(msg);
4527        }
4528    }
4529
4530    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4531        if (!mLaunchWarningShown) {
4532            mLaunchWarningShown = true;
4533            mHandler.post(new Runnable() {
4534                @Override
4535                public void run() {
4536                    synchronized (ActivityManagerService.this) {
4537                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4538                        d.show();
4539                        mHandler.postDelayed(new Runnable() {
4540                            @Override
4541                            public void run() {
4542                                synchronized (ActivityManagerService.this) {
4543                                    d.dismiss();
4544                                    mLaunchWarningShown = false;
4545                                }
4546                            }
4547                        }, 4000);
4548                    }
4549                }
4550            });
4551        }
4552    }
4553
4554    @Override
4555    public boolean clearApplicationUserData(final String packageName,
4556            final IPackageDataObserver observer, int userId) {
4557        enforceNotIsolatedCaller("clearApplicationUserData");
4558        int uid = Binder.getCallingUid();
4559        int pid = Binder.getCallingPid();
4560        userId = handleIncomingUser(pid, uid,
4561                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4562        long callingId = Binder.clearCallingIdentity();
4563        try {
4564            IPackageManager pm = AppGlobals.getPackageManager();
4565            int pkgUid = -1;
4566            synchronized(this) {
4567                try {
4568                    pkgUid = pm.getPackageUid(packageName, userId);
4569                } catch (RemoteException e) {
4570                }
4571                if (pkgUid == -1) {
4572                    Slog.w(TAG, "Invalid packageName: " + packageName);
4573                    if (observer != null) {
4574                        try {
4575                            observer.onRemoveCompleted(packageName, false);
4576                        } catch (RemoteException e) {
4577                            Slog.i(TAG, "Observer no longer exists.");
4578                        }
4579                    }
4580                    return false;
4581                }
4582                if (uid == pkgUid || checkComponentPermission(
4583                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4584                        pid, uid, -1, true)
4585                        == PackageManager.PERMISSION_GRANTED) {
4586                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4587                } else {
4588                    throw new SecurityException("PID " + pid + " does not have permission "
4589                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4590                                    + " of package " + packageName);
4591                }
4592            }
4593
4594            try {
4595                // Clear application user data
4596                pm.clearApplicationUserData(packageName, observer, userId);
4597
4598                // Remove all permissions granted from/to this package
4599                removeUriPermissionsForPackageLocked(packageName, userId, true);
4600
4601                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4602                        Uri.fromParts("package", packageName, null));
4603                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4604                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4605                        null, null, 0, null, null, null, false, false, userId);
4606            } catch (RemoteException e) {
4607            }
4608        } finally {
4609            Binder.restoreCallingIdentity(callingId);
4610        }
4611        return true;
4612    }
4613
4614    @Override
4615    public void killBackgroundProcesses(final String packageName, int userId) {
4616        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4617                != PackageManager.PERMISSION_GRANTED &&
4618                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4619                        != PackageManager.PERMISSION_GRANTED) {
4620            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4621                    + Binder.getCallingPid()
4622                    + ", uid=" + Binder.getCallingUid()
4623                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4624            Slog.w(TAG, msg);
4625            throw new SecurityException(msg);
4626        }
4627
4628        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4630        long callingId = Binder.clearCallingIdentity();
4631        try {
4632            IPackageManager pm = AppGlobals.getPackageManager();
4633            synchronized(this) {
4634                int appId = -1;
4635                try {
4636                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4637                } catch (RemoteException e) {
4638                }
4639                if (appId == -1) {
4640                    Slog.w(TAG, "Invalid packageName: " + packageName);
4641                    return;
4642                }
4643                killPackageProcessesLocked(packageName, appId, userId,
4644                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4645            }
4646        } finally {
4647            Binder.restoreCallingIdentity(callingId);
4648        }
4649    }
4650
4651    @Override
4652    public void killAllBackgroundProcesses() {
4653        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4654                != PackageManager.PERMISSION_GRANTED) {
4655            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4656                    + Binder.getCallingPid()
4657                    + ", uid=" + Binder.getCallingUid()
4658                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4659            Slog.w(TAG, msg);
4660            throw new SecurityException(msg);
4661        }
4662
4663        long callingId = Binder.clearCallingIdentity();
4664        try {
4665            synchronized(this) {
4666                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4667                final int NP = mProcessNames.getMap().size();
4668                for (int ip=0; ip<NP; ip++) {
4669                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4670                    final int NA = apps.size();
4671                    for (int ia=0; ia<NA; ia++) {
4672                        ProcessRecord app = apps.valueAt(ia);
4673                        if (app.persistent) {
4674                            // we don't kill persistent processes
4675                            continue;
4676                        }
4677                        if (app.removed) {
4678                            procs.add(app);
4679                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4680                            app.removed = true;
4681                            procs.add(app);
4682                        }
4683                    }
4684                }
4685
4686                int N = procs.size();
4687                for (int i=0; i<N; i++) {
4688                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4689                }
4690                mAllowLowerMemLevel = true;
4691                updateOomAdjLocked();
4692                doLowMemReportIfNeededLocked(null);
4693            }
4694        } finally {
4695            Binder.restoreCallingIdentity(callingId);
4696        }
4697    }
4698
4699    @Override
4700    public void forceStopPackage(final String packageName, int userId) {
4701        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4702                != PackageManager.PERMISSION_GRANTED) {
4703            String msg = "Permission Denial: forceStopPackage() from pid="
4704                    + Binder.getCallingPid()
4705                    + ", uid=" + Binder.getCallingUid()
4706                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4707            Slog.w(TAG, msg);
4708            throw new SecurityException(msg);
4709        }
4710        final int callingPid = Binder.getCallingPid();
4711        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4712                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4713        long callingId = Binder.clearCallingIdentity();
4714        try {
4715            IPackageManager pm = AppGlobals.getPackageManager();
4716            synchronized(this) {
4717                int[] users = userId == UserHandle.USER_ALL
4718                        ? getUsersLocked() : new int[] { userId };
4719                for (int user : users) {
4720                    int pkgUid = -1;
4721                    try {
4722                        pkgUid = pm.getPackageUid(packageName, user);
4723                    } catch (RemoteException e) {
4724                    }
4725                    if (pkgUid == -1) {
4726                        Slog.w(TAG, "Invalid packageName: " + packageName);
4727                        continue;
4728                    }
4729                    try {
4730                        pm.setPackageStoppedState(packageName, true, user);
4731                    } catch (RemoteException e) {
4732                    } catch (IllegalArgumentException e) {
4733                        Slog.w(TAG, "Failed trying to unstop package "
4734                                + packageName + ": " + e);
4735                    }
4736                    if (isUserRunningLocked(user, false)) {
4737                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4738                    }
4739                }
4740            }
4741        } finally {
4742            Binder.restoreCallingIdentity(callingId);
4743        }
4744    }
4745
4746    @Override
4747    public void addPackageDependency(String packageName) {
4748        synchronized (this) {
4749            int callingPid = Binder.getCallingPid();
4750            if (callingPid == Process.myPid()) {
4751                //  Yeah, um, no.
4752                Slog.w(TAG, "Can't addPackageDependency on system process");
4753                return;
4754            }
4755            ProcessRecord proc;
4756            synchronized (mPidsSelfLocked) {
4757                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4758            }
4759            if (proc != null) {
4760                if (proc.pkgDeps == null) {
4761                    proc.pkgDeps = new ArraySet<String>(1);
4762                }
4763                proc.pkgDeps.add(packageName);
4764            }
4765        }
4766    }
4767
4768    /*
4769     * The pkg name and app id have to be specified.
4770     */
4771    @Override
4772    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4773        if (pkg == null) {
4774            return;
4775        }
4776        // Make sure the uid is valid.
4777        if (appid < 0) {
4778            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4779            return;
4780        }
4781        int callerUid = Binder.getCallingUid();
4782        // Only the system server can kill an application
4783        if (callerUid == Process.SYSTEM_UID) {
4784            // Post an aysnc message to kill the application
4785            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4786            msg.arg1 = appid;
4787            msg.arg2 = 0;
4788            Bundle bundle = new Bundle();
4789            bundle.putString("pkg", pkg);
4790            bundle.putString("reason", reason);
4791            msg.obj = bundle;
4792            mHandler.sendMessage(msg);
4793        } else {
4794            throw new SecurityException(callerUid + " cannot kill pkg: " +
4795                    pkg);
4796        }
4797    }
4798
4799    @Override
4800    public void closeSystemDialogs(String reason) {
4801        enforceNotIsolatedCaller("closeSystemDialogs");
4802
4803        final int pid = Binder.getCallingPid();
4804        final int uid = Binder.getCallingUid();
4805        final long origId = Binder.clearCallingIdentity();
4806        try {
4807            synchronized (this) {
4808                // Only allow this from foreground processes, so that background
4809                // applications can't abuse it to prevent system UI from being shown.
4810                if (uid >= Process.FIRST_APPLICATION_UID) {
4811                    ProcessRecord proc;
4812                    synchronized (mPidsSelfLocked) {
4813                        proc = mPidsSelfLocked.get(pid);
4814                    }
4815                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4816                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4817                                + " from background process " + proc);
4818                        return;
4819                    }
4820                }
4821                closeSystemDialogsLocked(reason);
4822            }
4823        } finally {
4824            Binder.restoreCallingIdentity(origId);
4825        }
4826    }
4827
4828    void closeSystemDialogsLocked(String reason) {
4829        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4830        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4831                | Intent.FLAG_RECEIVER_FOREGROUND);
4832        if (reason != null) {
4833            intent.putExtra("reason", reason);
4834        }
4835        mWindowManager.closeSystemDialogs(reason);
4836
4837        mStackSupervisor.closeSystemDialogsLocked();
4838
4839        broadcastIntentLocked(null, null, intent, null,
4840                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4841                Process.SYSTEM_UID, UserHandle.USER_ALL);
4842    }
4843
4844    @Override
4845    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4846        enforceNotIsolatedCaller("getProcessMemoryInfo");
4847        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4848        for (int i=pids.length-1; i>=0; i--) {
4849            ProcessRecord proc;
4850            int oomAdj;
4851            synchronized (this) {
4852                synchronized (mPidsSelfLocked) {
4853                    proc = mPidsSelfLocked.get(pids[i]);
4854                    oomAdj = proc != null ? proc.setAdj : 0;
4855                }
4856            }
4857            infos[i] = new Debug.MemoryInfo();
4858            Debug.getMemoryInfo(pids[i], infos[i]);
4859            if (proc != null) {
4860                synchronized (this) {
4861                    if (proc.thread != null && proc.setAdj == oomAdj) {
4862                        // Record this for posterity if the process has been stable.
4863                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4864                                infos[i].getTotalUss(), false, proc.pkgList);
4865                    }
4866                }
4867            }
4868        }
4869        return infos;
4870    }
4871
4872    @Override
4873    public long[] getProcessPss(int[] pids) {
4874        enforceNotIsolatedCaller("getProcessPss");
4875        long[] pss = new long[pids.length];
4876        for (int i=pids.length-1; i>=0; i--) {
4877            ProcessRecord proc;
4878            int oomAdj;
4879            synchronized (this) {
4880                synchronized (mPidsSelfLocked) {
4881                    proc = mPidsSelfLocked.get(pids[i]);
4882                    oomAdj = proc != null ? proc.setAdj : 0;
4883                }
4884            }
4885            long[] tmpUss = new long[1];
4886            pss[i] = Debug.getPss(pids[i], tmpUss);
4887            if (proc != null) {
4888                synchronized (this) {
4889                    if (proc.thread != null && proc.setAdj == oomAdj) {
4890                        // Record this for posterity if the process has been stable.
4891                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4892                    }
4893                }
4894            }
4895        }
4896        return pss;
4897    }
4898
4899    @Override
4900    public void killApplicationProcess(String processName, int uid) {
4901        if (processName == null) {
4902            return;
4903        }
4904
4905        int callerUid = Binder.getCallingUid();
4906        // Only the system server can kill an application
4907        if (callerUid == Process.SYSTEM_UID) {
4908            synchronized (this) {
4909                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4910                if (app != null && app.thread != null) {
4911                    try {
4912                        app.thread.scheduleSuicide();
4913                    } catch (RemoteException e) {
4914                        // If the other end already died, then our work here is done.
4915                    }
4916                } else {
4917                    Slog.w(TAG, "Process/uid not found attempting kill of "
4918                            + processName + " / " + uid);
4919                }
4920            }
4921        } else {
4922            throw new SecurityException(callerUid + " cannot kill app process: " +
4923                    processName);
4924        }
4925    }
4926
4927    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4928        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4929                false, true, false, false, UserHandle.getUserId(uid), reason);
4930        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4931                Uri.fromParts("package", packageName, null));
4932        if (!mProcessesReady) {
4933            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4934                    | Intent.FLAG_RECEIVER_FOREGROUND);
4935        }
4936        intent.putExtra(Intent.EXTRA_UID, uid);
4937        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4938        broadcastIntentLocked(null, null, intent,
4939                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4940                false, false,
4941                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4942    }
4943
4944    private void forceStopUserLocked(int userId, String reason) {
4945        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4946        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4947        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4948                | Intent.FLAG_RECEIVER_FOREGROUND);
4949        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4950        broadcastIntentLocked(null, null, intent,
4951                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4952                false, false,
4953                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4954    }
4955
4956    private final boolean killPackageProcessesLocked(String packageName, int appId,
4957            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4958            boolean doit, boolean evenPersistent, String reason) {
4959        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4960
4961        // Remove all processes this package may have touched: all with the
4962        // same UID (except for the system or root user), and all whose name
4963        // matches the package name.
4964        final int NP = mProcessNames.getMap().size();
4965        for (int ip=0; ip<NP; ip++) {
4966            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4967            final int NA = apps.size();
4968            for (int ia=0; ia<NA; ia++) {
4969                ProcessRecord app = apps.valueAt(ia);
4970                if (app.persistent && !evenPersistent) {
4971                    // we don't kill persistent processes
4972                    continue;
4973                }
4974                if (app.removed) {
4975                    if (doit) {
4976                        procs.add(app);
4977                    }
4978                    continue;
4979                }
4980
4981                // Skip process if it doesn't meet our oom adj requirement.
4982                if (app.setAdj < minOomAdj) {
4983                    continue;
4984                }
4985
4986                // If no package is specified, we call all processes under the
4987                // give user id.
4988                if (packageName == null) {
4989                    if (app.userId != userId) {
4990                        continue;
4991                    }
4992                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4993                        continue;
4994                    }
4995                // Package has been specified, we want to hit all processes
4996                // that match it.  We need to qualify this by the processes
4997                // that are running under the specified app and user ID.
4998                } else {
4999                    final boolean isDep = app.pkgDeps != null
5000                            && app.pkgDeps.contains(packageName);
5001                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5002                        continue;
5003                    }
5004                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5005                        continue;
5006                    }
5007                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5008                        continue;
5009                    }
5010                }
5011
5012                // Process has passed all conditions, kill it!
5013                if (!doit) {
5014                    return true;
5015                }
5016                app.removed = true;
5017                procs.add(app);
5018            }
5019        }
5020
5021        int N = procs.size();
5022        for (int i=0; i<N; i++) {
5023            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5024        }
5025        updateOomAdjLocked();
5026        return N > 0;
5027    }
5028
5029    private final boolean forceStopPackageLocked(String name, int appId,
5030            boolean callerWillRestart, boolean purgeCache, boolean doit,
5031            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5032        int i;
5033        int N;
5034
5035        if (userId == UserHandle.USER_ALL && name == null) {
5036            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5037        }
5038
5039        if (appId < 0 && name != null) {
5040            try {
5041                appId = UserHandle.getAppId(
5042                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5043            } catch (RemoteException e) {
5044            }
5045        }
5046
5047        if (doit) {
5048            if (name != null) {
5049                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5050                        + " user=" + userId + ": " + reason);
5051            } else {
5052                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5053            }
5054
5055            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5056            for (int ip=pmap.size()-1; ip>=0; ip--) {
5057                SparseArray<Long> ba = pmap.valueAt(ip);
5058                for (i=ba.size()-1; i>=0; i--) {
5059                    boolean remove = false;
5060                    final int entUid = ba.keyAt(i);
5061                    if (name != null) {
5062                        if (userId == UserHandle.USER_ALL) {
5063                            if (UserHandle.getAppId(entUid) == appId) {
5064                                remove = true;
5065                            }
5066                        } else {
5067                            if (entUid == UserHandle.getUid(userId, appId)) {
5068                                remove = true;
5069                            }
5070                        }
5071                    } else if (UserHandle.getUserId(entUid) == userId) {
5072                        remove = true;
5073                    }
5074                    if (remove) {
5075                        ba.removeAt(i);
5076                    }
5077                }
5078                if (ba.size() == 0) {
5079                    pmap.removeAt(ip);
5080                }
5081            }
5082        }
5083
5084        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5085                -100, callerWillRestart, true, doit, evenPersistent,
5086                name == null ? ("stop user " + userId) : ("stop " + name));
5087
5088        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5089            if (!doit) {
5090                return true;
5091            }
5092            didSomething = true;
5093        }
5094
5095        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5096            if (!doit) {
5097                return true;
5098            }
5099            didSomething = true;
5100        }
5101
5102        if (name == null) {
5103            // Remove all sticky broadcasts from this user.
5104            mStickyBroadcasts.remove(userId);
5105        }
5106
5107        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5108        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5109                userId, providers)) {
5110            if (!doit) {
5111                return true;
5112            }
5113            didSomething = true;
5114        }
5115        N = providers.size();
5116        for (i=0; i<N; i++) {
5117            removeDyingProviderLocked(null, providers.get(i), true);
5118        }
5119
5120        // Remove transient permissions granted from/to this package/user
5121        removeUriPermissionsForPackageLocked(name, userId, false);
5122
5123        if (name == null || uninstalling) {
5124            // Remove pending intents.  For now we only do this when force
5125            // stopping users, because we have some problems when doing this
5126            // for packages -- app widgets are not currently cleaned up for
5127            // such packages, so they can be left with bad pending intents.
5128            if (mIntentSenderRecords.size() > 0) {
5129                Iterator<WeakReference<PendingIntentRecord>> it
5130                        = mIntentSenderRecords.values().iterator();
5131                while (it.hasNext()) {
5132                    WeakReference<PendingIntentRecord> wpir = it.next();
5133                    if (wpir == null) {
5134                        it.remove();
5135                        continue;
5136                    }
5137                    PendingIntentRecord pir = wpir.get();
5138                    if (pir == null) {
5139                        it.remove();
5140                        continue;
5141                    }
5142                    if (name == null) {
5143                        // Stopping user, remove all objects for the user.
5144                        if (pir.key.userId != userId) {
5145                            // Not the same user, skip it.
5146                            continue;
5147                        }
5148                    } else {
5149                        if (UserHandle.getAppId(pir.uid) != appId) {
5150                            // Different app id, skip it.
5151                            continue;
5152                        }
5153                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5154                            // Different user, skip it.
5155                            continue;
5156                        }
5157                        if (!pir.key.packageName.equals(name)) {
5158                            // Different package, skip it.
5159                            continue;
5160                        }
5161                    }
5162                    if (!doit) {
5163                        return true;
5164                    }
5165                    didSomething = true;
5166                    it.remove();
5167                    pir.canceled = true;
5168                    if (pir.key.activity != null) {
5169                        pir.key.activity.pendingResults.remove(pir.ref);
5170                    }
5171                }
5172            }
5173        }
5174
5175        if (doit) {
5176            if (purgeCache && name != null) {
5177                AttributeCache ac = AttributeCache.instance();
5178                if (ac != null) {
5179                    ac.removePackage(name);
5180                }
5181            }
5182            if (mBooted) {
5183                mStackSupervisor.resumeTopActivitiesLocked();
5184                mStackSupervisor.scheduleIdleLocked();
5185            }
5186        }
5187
5188        return didSomething;
5189    }
5190
5191    private final boolean removeProcessLocked(ProcessRecord app,
5192            boolean callerWillRestart, boolean allowRestart, String reason) {
5193        final String name = app.processName;
5194        final int uid = app.uid;
5195        if (DEBUG_PROCESSES) Slog.d(
5196            TAG, "Force removing proc " + app.toShortString() + " (" + name
5197            + "/" + uid + ")");
5198
5199        mProcessNames.remove(name, uid);
5200        mIsolatedProcesses.remove(app.uid);
5201        if (mHeavyWeightProcess == app) {
5202            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5203                    mHeavyWeightProcess.userId, 0));
5204            mHeavyWeightProcess = null;
5205        }
5206        boolean needRestart = false;
5207        if (app.pid > 0 && app.pid != MY_PID) {
5208            int pid = app.pid;
5209            synchronized (mPidsSelfLocked) {
5210                mPidsSelfLocked.remove(pid);
5211                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5212            }
5213            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5214            if (app.isolated) {
5215                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5216            }
5217            killUnneededProcessLocked(app, reason);
5218            Process.killProcessGroup(app.info.uid, app.pid);
5219            handleAppDiedLocked(app, true, allowRestart);
5220            removeLruProcessLocked(app);
5221
5222            if (app.persistent && !app.isolated) {
5223                if (!callerWillRestart) {
5224                    addAppLocked(app.info, false, null /* ABI override */);
5225                } else {
5226                    needRestart = true;
5227                }
5228            }
5229        } else {
5230            mRemovedProcesses.add(app);
5231        }
5232
5233        return needRestart;
5234    }
5235
5236    private final void processStartTimedOutLocked(ProcessRecord app) {
5237        final int pid = app.pid;
5238        boolean gone = false;
5239        synchronized (mPidsSelfLocked) {
5240            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5241            if (knownApp != null && knownApp.thread == null) {
5242                mPidsSelfLocked.remove(pid);
5243                gone = true;
5244            }
5245        }
5246
5247        if (gone) {
5248            Slog.w(TAG, "Process " + app + " failed to attach");
5249            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5250                    pid, app.uid, app.processName);
5251            mProcessNames.remove(app.processName, app.uid);
5252            mIsolatedProcesses.remove(app.uid);
5253            if (mHeavyWeightProcess == app) {
5254                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5255                        mHeavyWeightProcess.userId, 0));
5256                mHeavyWeightProcess = null;
5257            }
5258            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5259            if (app.isolated) {
5260                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5261            }
5262            // Take care of any launching providers waiting for this process.
5263            checkAppInLaunchingProvidersLocked(app, true);
5264            // Take care of any services that are waiting for the process.
5265            mServices.processStartTimedOutLocked(app);
5266            killUnneededProcessLocked(app, "start timeout");
5267            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5268                Slog.w(TAG, "Unattached app died before backup, skipping");
5269                try {
5270                    IBackupManager bm = IBackupManager.Stub.asInterface(
5271                            ServiceManager.getService(Context.BACKUP_SERVICE));
5272                    bm.agentDisconnected(app.info.packageName);
5273                } catch (RemoteException e) {
5274                    // Can't happen; the backup manager is local
5275                }
5276            }
5277            if (isPendingBroadcastProcessLocked(pid)) {
5278                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5279                skipPendingBroadcastLocked(pid);
5280            }
5281        } else {
5282            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5283        }
5284    }
5285
5286    private final boolean attachApplicationLocked(IApplicationThread thread,
5287            int pid) {
5288
5289        // Find the application record that is being attached...  either via
5290        // the pid if we are running in multiple processes, or just pull the
5291        // next app record if we are emulating process with anonymous threads.
5292        ProcessRecord app;
5293        if (pid != MY_PID && pid >= 0) {
5294            synchronized (mPidsSelfLocked) {
5295                app = mPidsSelfLocked.get(pid);
5296            }
5297        } else {
5298            app = null;
5299        }
5300
5301        if (app == null) {
5302            Slog.w(TAG, "No pending application record for pid " + pid
5303                    + " (IApplicationThread " + thread + "); dropping process");
5304            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5305            if (pid > 0 && pid != MY_PID) {
5306                Process.killProcessQuiet(pid);
5307                //TODO: Process.killProcessGroup(app.info.uid, pid);
5308            } else {
5309                try {
5310                    thread.scheduleExit();
5311                } catch (Exception e) {
5312                    // Ignore exceptions.
5313                }
5314            }
5315            return false;
5316        }
5317
5318        // If this application record is still attached to a previous
5319        // process, clean it up now.
5320        if (app.thread != null) {
5321            handleAppDiedLocked(app, true, true);
5322        }
5323
5324        // Tell the process all about itself.
5325
5326        if (localLOGV) Slog.v(
5327                TAG, "Binding process pid " + pid + " to record " + app);
5328
5329        final String processName = app.processName;
5330        try {
5331            AppDeathRecipient adr = new AppDeathRecipient(
5332                    app, pid, thread);
5333            thread.asBinder().linkToDeath(adr, 0);
5334            app.deathRecipient = adr;
5335        } catch (RemoteException e) {
5336            app.resetPackageList(mProcessStats);
5337            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5338            return false;
5339        }
5340
5341        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5342
5343        app.makeActive(thread, mProcessStats);
5344        app.curAdj = app.setAdj = -100;
5345        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5346        app.forcingToForeground = null;
5347        updateProcessForegroundLocked(app, false, false);
5348        app.hasShownUi = false;
5349        app.debugging = false;
5350        app.cached = false;
5351
5352        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5353
5354        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5355        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5356
5357        if (!normalMode) {
5358            Slog.i(TAG, "Launching preboot mode app: " + app);
5359        }
5360
5361        if (localLOGV) Slog.v(
5362            TAG, "New app record " + app
5363            + " thread=" + thread.asBinder() + " pid=" + pid);
5364        try {
5365            int testMode = IApplicationThread.DEBUG_OFF;
5366            if (mDebugApp != null && mDebugApp.equals(processName)) {
5367                testMode = mWaitForDebugger
5368                    ? IApplicationThread.DEBUG_WAIT
5369                    : IApplicationThread.DEBUG_ON;
5370                app.debugging = true;
5371                if (mDebugTransient) {
5372                    mDebugApp = mOrigDebugApp;
5373                    mWaitForDebugger = mOrigWaitForDebugger;
5374                }
5375            }
5376            String profileFile = app.instrumentationProfileFile;
5377            ParcelFileDescriptor profileFd = null;
5378            boolean profileAutoStop = false;
5379            if (mProfileApp != null && mProfileApp.equals(processName)) {
5380                mProfileProc = app;
5381                profileFile = mProfileFile;
5382                profileFd = mProfileFd;
5383                profileAutoStop = mAutoStopProfiler;
5384            }
5385            boolean enableOpenGlTrace = false;
5386            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5387                enableOpenGlTrace = true;
5388                mOpenGlTraceApp = null;
5389            }
5390
5391            // If the app is being launched for restore or full backup, set it up specially
5392            boolean isRestrictedBackupMode = false;
5393            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5394                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5395                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5396                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5397            }
5398
5399            ensurePackageDexOpt(app.instrumentationInfo != null
5400                    ? app.instrumentationInfo.packageName
5401                    : app.info.packageName);
5402            if (app.instrumentationClass != null) {
5403                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5404            }
5405            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5406                    + processName + " with config " + mConfiguration);
5407            ApplicationInfo appInfo = app.instrumentationInfo != null
5408                    ? app.instrumentationInfo : app.info;
5409            app.compat = compatibilityInfoForPackageLocked(appInfo);
5410            if (profileFd != null) {
5411                profileFd = profileFd.dup();
5412            }
5413            thread.bindApplication(processName, appInfo, providers,
5414                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5415                    app.instrumentationArguments, app.instrumentationWatcher,
5416                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5417                    isRestrictedBackupMode || !normalMode, app.persistent,
5418                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5419                    mCoreSettingsObserver.getCoreSettingsLocked());
5420            updateLruProcessLocked(app, false, null);
5421            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5422        } catch (Exception e) {
5423            // todo: Yikes!  What should we do?  For now we will try to
5424            // start another process, but that could easily get us in
5425            // an infinite loop of restarting processes...
5426            Slog.w(TAG, "Exception thrown during bind!", e);
5427
5428            app.resetPackageList(mProcessStats);
5429            app.unlinkDeathRecipient();
5430            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5431            return false;
5432        }
5433
5434        // Remove this record from the list of starting applications.
5435        mPersistentStartingProcesses.remove(app);
5436        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5437                "Attach application locked removing on hold: " + app);
5438        mProcessesOnHold.remove(app);
5439
5440        boolean badApp = false;
5441        boolean didSomething = false;
5442
5443        // See if the top visible activity is waiting to run in this process...
5444        if (normalMode) {
5445            try {
5446                if (mStackSupervisor.attachApplicationLocked(app)) {
5447                    didSomething = true;
5448                }
5449            } catch (Exception e) {
5450                badApp = true;
5451            }
5452        }
5453
5454        // Find any services that should be running in this process...
5455        if (!badApp) {
5456            try {
5457                didSomething |= mServices.attachApplicationLocked(app, processName);
5458            } catch (Exception e) {
5459                badApp = true;
5460            }
5461        }
5462
5463        // Check if a next-broadcast receiver is in this process...
5464        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5465            try {
5466                didSomething |= sendPendingBroadcastsLocked(app);
5467            } catch (Exception e) {
5468                // If the app died trying to launch the receiver we declare it 'bad'
5469                badApp = true;
5470            }
5471        }
5472
5473        // Check whether the next backup agent is in this process...
5474        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5475            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5476            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5477            try {
5478                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5479                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5480                        mBackupTarget.backupMode);
5481            } catch (Exception e) {
5482                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5483                e.printStackTrace();
5484            }
5485        }
5486
5487        if (badApp) {
5488            // todo: Also need to kill application to deal with all
5489            // kinds of exceptions.
5490            handleAppDiedLocked(app, false, true);
5491            return false;
5492        }
5493
5494        if (!didSomething) {
5495            updateOomAdjLocked();
5496        }
5497
5498        return true;
5499    }
5500
5501    @Override
5502    public final void attachApplication(IApplicationThread thread) {
5503        synchronized (this) {
5504            int callingPid = Binder.getCallingPid();
5505            final long origId = Binder.clearCallingIdentity();
5506            attachApplicationLocked(thread, callingPid);
5507            Binder.restoreCallingIdentity(origId);
5508        }
5509    }
5510
5511    @Override
5512    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5513        final long origId = Binder.clearCallingIdentity();
5514        synchronized (this) {
5515            ActivityStack stack = ActivityRecord.getStackLocked(token);
5516            if (stack != null) {
5517                ActivityRecord r =
5518                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5519                if (stopProfiling) {
5520                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5521                        try {
5522                            mProfileFd.close();
5523                        } catch (IOException e) {
5524                        }
5525                        clearProfilerLocked();
5526                    }
5527                }
5528            }
5529        }
5530        Binder.restoreCallingIdentity(origId);
5531    }
5532
5533    void postEnableScreenAfterBootLocked() {
5534        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5535    }
5536
5537    void enableScreenAfterBoot() {
5538        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5539                SystemClock.uptimeMillis());
5540        mWindowManager.enableScreenAfterBoot();
5541
5542        synchronized (this) {
5543            updateEventDispatchingLocked();
5544        }
5545    }
5546
5547    @Override
5548    public void showBootMessage(final CharSequence msg, final boolean always) {
5549        enforceNotIsolatedCaller("showBootMessage");
5550        mWindowManager.showBootMessage(msg, always);
5551    }
5552
5553    @Override
5554    public void dismissKeyguardOnNextActivity() {
5555        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5556        final long token = Binder.clearCallingIdentity();
5557        try {
5558            synchronized (this) {
5559                if (DEBUG_LOCKSCREEN) logLockScreen("");
5560                if (mLockScreenShown) {
5561                    mLockScreenShown = false;
5562                    comeOutOfSleepIfNeededLocked();
5563                }
5564                mStackSupervisor.setDismissKeyguard(true);
5565            }
5566        } finally {
5567            Binder.restoreCallingIdentity(token);
5568        }
5569    }
5570
5571    final void finishBooting() {
5572        // Register receivers to handle package update events
5573        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5574
5575        synchronized (this) {
5576            // Ensure that any processes we had put on hold are now started
5577            // up.
5578            final int NP = mProcessesOnHold.size();
5579            if (NP > 0) {
5580                ArrayList<ProcessRecord> procs =
5581                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5582                for (int ip=0; ip<NP; ip++) {
5583                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5584                            + procs.get(ip));
5585                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5586                }
5587            }
5588
5589            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5590                // Start looking for apps that are abusing wake locks.
5591                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5592                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5593                // Tell anyone interested that we are done booting!
5594                SystemProperties.set("sys.boot_completed", "1");
5595                SystemProperties.set("dev.bootcomplete", "1");
5596                for (int i=0; i<mStartedUsers.size(); i++) {
5597                    UserStartedState uss = mStartedUsers.valueAt(i);
5598                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5599                        uss.mState = UserStartedState.STATE_RUNNING;
5600                        final int userId = mStartedUsers.keyAt(i);
5601                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5602                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5603                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5604                        broadcastIntentLocked(null, null, intent, null,
5605                                new IIntentReceiver.Stub() {
5606                                    @Override
5607                                    public void performReceive(Intent intent, int resultCode,
5608                                            String data, Bundle extras, boolean ordered,
5609                                            boolean sticky, int sendingUser) {
5610                                        synchronized (ActivityManagerService.this) {
5611                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5612                                                    true, false);
5613                                        }
5614                                    }
5615                                },
5616                                0, null, null,
5617                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5618                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5619                                userId);
5620                    }
5621                }
5622                scheduleStartProfilesLocked();
5623            }
5624        }
5625    }
5626
5627    final void ensureBootCompleted() {
5628        boolean booting;
5629        boolean enableScreen;
5630        synchronized (this) {
5631            booting = mBooting;
5632            mBooting = false;
5633            enableScreen = !mBooted;
5634            mBooted = true;
5635        }
5636
5637        if (booting) {
5638            finishBooting();
5639        }
5640
5641        if (enableScreen) {
5642            enableScreenAfterBoot();
5643        }
5644    }
5645
5646    @Override
5647    public final void activityResumed(IBinder token) {
5648        final long origId = Binder.clearCallingIdentity();
5649        synchronized(this) {
5650            ActivityStack stack = ActivityRecord.getStackLocked(token);
5651            if (stack != null) {
5652                ActivityRecord.activityResumedLocked(token);
5653            }
5654        }
5655        Binder.restoreCallingIdentity(origId);
5656    }
5657
5658    @Override
5659    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5660        final long origId = Binder.clearCallingIdentity();
5661        synchronized(this) {
5662            ActivityStack stack = ActivityRecord.getStackLocked(token);
5663            if (stack != null) {
5664                stack.activityPausedLocked(token, false, persistentState);
5665            }
5666        }
5667        Binder.restoreCallingIdentity(origId);
5668    }
5669
5670    @Override
5671    public final void activityStopped(IBinder token, Bundle icicle,
5672            PersistableBundle persistentState, CharSequence description) {
5673        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5674
5675        // Refuse possible leaked file descriptors
5676        if (icicle != null && icicle.hasFileDescriptors()) {
5677            throw new IllegalArgumentException("File descriptors passed in Bundle");
5678        }
5679
5680        final long origId = Binder.clearCallingIdentity();
5681
5682        synchronized (this) {
5683            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5684            if (r != null) {
5685                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5686            }
5687        }
5688
5689        trimApplications();
5690
5691        Binder.restoreCallingIdentity(origId);
5692    }
5693
5694    @Override
5695    public final void activityDestroyed(IBinder token) {
5696        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5697        synchronized (this) {
5698            ActivityStack stack = ActivityRecord.getStackLocked(token);
5699            if (stack != null) {
5700                stack.activityDestroyedLocked(token);
5701            }
5702        }
5703    }
5704
5705    @Override
5706    public final void mediaResourcesReleased(IBinder token) {
5707        final long origId = Binder.clearCallingIdentity();
5708        try {
5709            synchronized (this) {
5710                ActivityStack stack = ActivityRecord.getStackLocked(token);
5711                if (stack != null) {
5712                    stack.mediaResourcesReleased(token);
5713                }
5714            }
5715        } finally {
5716            Binder.restoreCallingIdentity(origId);
5717        }
5718    }
5719
5720    @Override
5721    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5722        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5723    }
5724
5725    @Override
5726    public final void notifyEnterAnimationComplete(IBinder token) {
5727        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5728    }
5729
5730    @Override
5731    public String getCallingPackage(IBinder token) {
5732        synchronized (this) {
5733            ActivityRecord r = getCallingRecordLocked(token);
5734            return r != null ? r.info.packageName : null;
5735        }
5736    }
5737
5738    @Override
5739    public ComponentName getCallingActivity(IBinder token) {
5740        synchronized (this) {
5741            ActivityRecord r = getCallingRecordLocked(token);
5742            return r != null ? r.intent.getComponent() : null;
5743        }
5744    }
5745
5746    private ActivityRecord getCallingRecordLocked(IBinder token) {
5747        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5748        if (r == null) {
5749            return null;
5750        }
5751        return r.resultTo;
5752    }
5753
5754    @Override
5755    public ComponentName getActivityClassForToken(IBinder token) {
5756        synchronized(this) {
5757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5758            if (r == null) {
5759                return null;
5760            }
5761            return r.intent.getComponent();
5762        }
5763    }
5764
5765    @Override
5766    public String getPackageForToken(IBinder token) {
5767        synchronized(this) {
5768            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5769            if (r == null) {
5770                return null;
5771            }
5772            return r.packageName;
5773        }
5774    }
5775
5776    @Override
5777    public IIntentSender getIntentSender(int type,
5778            String packageName, IBinder token, String resultWho,
5779            int requestCode, Intent[] intents, String[] resolvedTypes,
5780            int flags, Bundle options, int userId) {
5781        enforceNotIsolatedCaller("getIntentSender");
5782        // Refuse possible leaked file descriptors
5783        if (intents != null) {
5784            if (intents.length < 1) {
5785                throw new IllegalArgumentException("Intents array length must be >= 1");
5786            }
5787            for (int i=0; i<intents.length; i++) {
5788                Intent intent = intents[i];
5789                if (intent != null) {
5790                    if (intent.hasFileDescriptors()) {
5791                        throw new IllegalArgumentException("File descriptors passed in Intent");
5792                    }
5793                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5794                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5795                        throw new IllegalArgumentException(
5796                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5797                    }
5798                    intents[i] = new Intent(intent);
5799                }
5800            }
5801            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5802                throw new IllegalArgumentException(
5803                        "Intent array length does not match resolvedTypes length");
5804            }
5805        }
5806        if (options != null) {
5807            if (options.hasFileDescriptors()) {
5808                throw new IllegalArgumentException("File descriptors passed in options");
5809            }
5810        }
5811
5812        synchronized(this) {
5813            int callingUid = Binder.getCallingUid();
5814            int origUserId = userId;
5815            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5816                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5817                    ALLOW_NON_FULL, "getIntentSender", null);
5818            if (origUserId == UserHandle.USER_CURRENT) {
5819                // We don't want to evaluate this until the pending intent is
5820                // actually executed.  However, we do want to always do the
5821                // security checking for it above.
5822                userId = UserHandle.USER_CURRENT;
5823            }
5824            try {
5825                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5826                    int uid = AppGlobals.getPackageManager()
5827                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5828                    if (!UserHandle.isSameApp(callingUid, uid)) {
5829                        String msg = "Permission Denial: getIntentSender() from pid="
5830                            + Binder.getCallingPid()
5831                            + ", uid=" + Binder.getCallingUid()
5832                            + ", (need uid=" + uid + ")"
5833                            + " is not allowed to send as package " + packageName;
5834                        Slog.w(TAG, msg);
5835                        throw new SecurityException(msg);
5836                    }
5837                }
5838
5839                return getIntentSenderLocked(type, packageName, callingUid, userId,
5840                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5841
5842            } catch (RemoteException e) {
5843                throw new SecurityException(e);
5844            }
5845        }
5846    }
5847
5848    IIntentSender getIntentSenderLocked(int type, String packageName,
5849            int callingUid, int userId, IBinder token, String resultWho,
5850            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5851            Bundle options) {
5852        if (DEBUG_MU)
5853            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5854        ActivityRecord activity = null;
5855        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5856            activity = ActivityRecord.isInStackLocked(token);
5857            if (activity == null) {
5858                return null;
5859            }
5860            if (activity.finishing) {
5861                return null;
5862            }
5863        }
5864
5865        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5866        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5867        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5868        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5869                |PendingIntent.FLAG_UPDATE_CURRENT);
5870
5871        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5872                type, packageName, activity, resultWho,
5873                requestCode, intents, resolvedTypes, flags, options, userId);
5874        WeakReference<PendingIntentRecord> ref;
5875        ref = mIntentSenderRecords.get(key);
5876        PendingIntentRecord rec = ref != null ? ref.get() : null;
5877        if (rec != null) {
5878            if (!cancelCurrent) {
5879                if (updateCurrent) {
5880                    if (rec.key.requestIntent != null) {
5881                        rec.key.requestIntent.replaceExtras(intents != null ?
5882                                intents[intents.length - 1] : null);
5883                    }
5884                    if (intents != null) {
5885                        intents[intents.length-1] = rec.key.requestIntent;
5886                        rec.key.allIntents = intents;
5887                        rec.key.allResolvedTypes = resolvedTypes;
5888                    } else {
5889                        rec.key.allIntents = null;
5890                        rec.key.allResolvedTypes = null;
5891                    }
5892                }
5893                return rec;
5894            }
5895            rec.canceled = true;
5896            mIntentSenderRecords.remove(key);
5897        }
5898        if (noCreate) {
5899            return rec;
5900        }
5901        rec = new PendingIntentRecord(this, key, callingUid);
5902        mIntentSenderRecords.put(key, rec.ref);
5903        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5904            if (activity.pendingResults == null) {
5905                activity.pendingResults
5906                        = new HashSet<WeakReference<PendingIntentRecord>>();
5907            }
5908            activity.pendingResults.add(rec.ref);
5909        }
5910        return rec;
5911    }
5912
5913    @Override
5914    public void cancelIntentSender(IIntentSender sender) {
5915        if (!(sender instanceof PendingIntentRecord)) {
5916            return;
5917        }
5918        synchronized(this) {
5919            PendingIntentRecord rec = (PendingIntentRecord)sender;
5920            try {
5921                int uid = AppGlobals.getPackageManager()
5922                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5923                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5924                    String msg = "Permission Denial: cancelIntentSender() from pid="
5925                        + Binder.getCallingPid()
5926                        + ", uid=" + Binder.getCallingUid()
5927                        + " is not allowed to cancel packges "
5928                        + rec.key.packageName;
5929                    Slog.w(TAG, msg);
5930                    throw new SecurityException(msg);
5931                }
5932            } catch (RemoteException e) {
5933                throw new SecurityException(e);
5934            }
5935            cancelIntentSenderLocked(rec, true);
5936        }
5937    }
5938
5939    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5940        rec.canceled = true;
5941        mIntentSenderRecords.remove(rec.key);
5942        if (cleanActivity && rec.key.activity != null) {
5943            rec.key.activity.pendingResults.remove(rec.ref);
5944        }
5945    }
5946
5947    @Override
5948    public String getPackageForIntentSender(IIntentSender pendingResult) {
5949        if (!(pendingResult instanceof PendingIntentRecord)) {
5950            return null;
5951        }
5952        try {
5953            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5954            return res.key.packageName;
5955        } catch (ClassCastException e) {
5956        }
5957        return null;
5958    }
5959
5960    @Override
5961    public int getUidForIntentSender(IIntentSender sender) {
5962        if (sender instanceof PendingIntentRecord) {
5963            try {
5964                PendingIntentRecord res = (PendingIntentRecord)sender;
5965                return res.uid;
5966            } catch (ClassCastException e) {
5967            }
5968        }
5969        return -1;
5970    }
5971
5972    @Override
5973    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5974        if (!(pendingResult instanceof PendingIntentRecord)) {
5975            return false;
5976        }
5977        try {
5978            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5979            if (res.key.allIntents == null) {
5980                return false;
5981            }
5982            for (int i=0; i<res.key.allIntents.length; i++) {
5983                Intent intent = res.key.allIntents[i];
5984                if (intent.getPackage() != null && intent.getComponent() != null) {
5985                    return false;
5986                }
5987            }
5988            return true;
5989        } catch (ClassCastException e) {
5990        }
5991        return false;
5992    }
5993
5994    @Override
5995    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5996        if (!(pendingResult instanceof PendingIntentRecord)) {
5997            return false;
5998        }
5999        try {
6000            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6001            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6002                return true;
6003            }
6004            return false;
6005        } catch (ClassCastException e) {
6006        }
6007        return false;
6008    }
6009
6010    @Override
6011    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6012        if (!(pendingResult instanceof PendingIntentRecord)) {
6013            return null;
6014        }
6015        try {
6016            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6017            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6018        } catch (ClassCastException e) {
6019        }
6020        return null;
6021    }
6022
6023    @Override
6024    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6025        if (!(pendingResult instanceof PendingIntentRecord)) {
6026            return null;
6027        }
6028        try {
6029            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6030            Intent intent = res.key.requestIntent;
6031            if (intent != null) {
6032                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6033                        || res.lastTagPrefix.equals(prefix))) {
6034                    return res.lastTag;
6035                }
6036                res.lastTagPrefix = prefix;
6037                StringBuilder sb = new StringBuilder(128);
6038                if (prefix != null) {
6039                    sb.append(prefix);
6040                }
6041                if (intent.getAction() != null) {
6042                    sb.append(intent.getAction());
6043                } else if (intent.getComponent() != null) {
6044                    intent.getComponent().appendShortString(sb);
6045                } else {
6046                    sb.append("?");
6047                }
6048                return res.lastTag = sb.toString();
6049            }
6050        } catch (ClassCastException e) {
6051        }
6052        return null;
6053    }
6054
6055    @Override
6056    public void setProcessLimit(int max) {
6057        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6058                "setProcessLimit()");
6059        synchronized (this) {
6060            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6061            mProcessLimitOverride = max;
6062        }
6063        trimApplications();
6064    }
6065
6066    @Override
6067    public int getProcessLimit() {
6068        synchronized (this) {
6069            return mProcessLimitOverride;
6070        }
6071    }
6072
6073    void foregroundTokenDied(ForegroundToken token) {
6074        synchronized (ActivityManagerService.this) {
6075            synchronized (mPidsSelfLocked) {
6076                ForegroundToken cur
6077                    = mForegroundProcesses.get(token.pid);
6078                if (cur != token) {
6079                    return;
6080                }
6081                mForegroundProcesses.remove(token.pid);
6082                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6083                if (pr == null) {
6084                    return;
6085                }
6086                pr.forcingToForeground = null;
6087                updateProcessForegroundLocked(pr, false, false);
6088            }
6089            updateOomAdjLocked();
6090        }
6091    }
6092
6093    @Override
6094    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6095        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6096                "setProcessForeground()");
6097        synchronized(this) {
6098            boolean changed = false;
6099
6100            synchronized (mPidsSelfLocked) {
6101                ProcessRecord pr = mPidsSelfLocked.get(pid);
6102                if (pr == null && isForeground) {
6103                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6104                    return;
6105                }
6106                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6107                if (oldToken != null) {
6108                    oldToken.token.unlinkToDeath(oldToken, 0);
6109                    mForegroundProcesses.remove(pid);
6110                    if (pr != null) {
6111                        pr.forcingToForeground = null;
6112                    }
6113                    changed = true;
6114                }
6115                if (isForeground && token != null) {
6116                    ForegroundToken newToken = new ForegroundToken() {
6117                        @Override
6118                        public void binderDied() {
6119                            foregroundTokenDied(this);
6120                        }
6121                    };
6122                    newToken.pid = pid;
6123                    newToken.token = token;
6124                    try {
6125                        token.linkToDeath(newToken, 0);
6126                        mForegroundProcesses.put(pid, newToken);
6127                        pr.forcingToForeground = token;
6128                        changed = true;
6129                    } catch (RemoteException e) {
6130                        // If the process died while doing this, we will later
6131                        // do the cleanup with the process death link.
6132                    }
6133                }
6134            }
6135
6136            if (changed) {
6137                updateOomAdjLocked();
6138            }
6139        }
6140    }
6141
6142    // =========================================================
6143    // PERMISSIONS
6144    // =========================================================
6145
6146    static class PermissionController extends IPermissionController.Stub {
6147        ActivityManagerService mActivityManagerService;
6148        PermissionController(ActivityManagerService activityManagerService) {
6149            mActivityManagerService = activityManagerService;
6150        }
6151
6152        @Override
6153        public boolean checkPermission(String permission, int pid, int uid) {
6154            return mActivityManagerService.checkPermission(permission, pid,
6155                    uid) == PackageManager.PERMISSION_GRANTED;
6156        }
6157    }
6158
6159    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6160        @Override
6161        public int checkComponentPermission(String permission, int pid, int uid,
6162                int owningUid, boolean exported) {
6163            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6164                    owningUid, exported);
6165        }
6166
6167        @Override
6168        public Object getAMSLock() {
6169            return ActivityManagerService.this;
6170        }
6171    }
6172
6173    /**
6174     * This can be called with or without the global lock held.
6175     */
6176    int checkComponentPermission(String permission, int pid, int uid,
6177            int owningUid, boolean exported) {
6178        // We might be performing an operation on behalf of an indirect binder
6179        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6180        // client identity accordingly before proceeding.
6181        Identity tlsIdentity = sCallerIdentity.get();
6182        if (tlsIdentity != null) {
6183            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6184                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6185            uid = tlsIdentity.uid;
6186            pid = tlsIdentity.pid;
6187        }
6188
6189        if (pid == MY_PID) {
6190            return PackageManager.PERMISSION_GRANTED;
6191        }
6192
6193        return ActivityManager.checkComponentPermission(permission, uid,
6194                owningUid, exported);
6195    }
6196
6197    /**
6198     * As the only public entry point for permissions checking, this method
6199     * can enforce the semantic that requesting a check on a null global
6200     * permission is automatically denied.  (Internally a null permission
6201     * string is used when calling {@link #checkComponentPermission} in cases
6202     * when only uid-based security is needed.)
6203     *
6204     * This can be called with or without the global lock held.
6205     */
6206    @Override
6207    public int checkPermission(String permission, int pid, int uid) {
6208        if (permission == null) {
6209            return PackageManager.PERMISSION_DENIED;
6210        }
6211        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6212    }
6213
6214    /**
6215     * Binder IPC calls go through the public entry point.
6216     * This can be called with or without the global lock held.
6217     */
6218    int checkCallingPermission(String permission) {
6219        return checkPermission(permission,
6220                Binder.getCallingPid(),
6221                UserHandle.getAppId(Binder.getCallingUid()));
6222    }
6223
6224    /**
6225     * This can be called with or without the global lock held.
6226     */
6227    void enforceCallingPermission(String permission, String func) {
6228        if (checkCallingPermission(permission)
6229                == PackageManager.PERMISSION_GRANTED) {
6230            return;
6231        }
6232
6233        String msg = "Permission Denial: " + func + " from pid="
6234                + Binder.getCallingPid()
6235                + ", uid=" + Binder.getCallingUid()
6236                + " requires " + permission;
6237        Slog.w(TAG, msg);
6238        throw new SecurityException(msg);
6239    }
6240
6241    /**
6242     * Determine if UID is holding permissions required to access {@link Uri} in
6243     * the given {@link ProviderInfo}. Final permission checking is always done
6244     * in {@link ContentProvider}.
6245     */
6246    private final boolean checkHoldingPermissionsLocked(
6247            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6248        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6249                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6250        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6251            return false;
6252        }
6253        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6254    }
6255
6256    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6257            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6258        if (pi.applicationInfo.uid == uid) {
6259            return true;
6260        } else if (!pi.exported) {
6261            return false;
6262        }
6263
6264        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6265        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6266        try {
6267            // check if target holds top-level <provider> permissions
6268            if (!readMet && pi.readPermission != null && considerUidPermissions
6269                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6270                readMet = true;
6271            }
6272            if (!writeMet && pi.writePermission != null && considerUidPermissions
6273                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6274                writeMet = true;
6275            }
6276
6277            // track if unprotected read/write is allowed; any denied
6278            // <path-permission> below removes this ability
6279            boolean allowDefaultRead = pi.readPermission == null;
6280            boolean allowDefaultWrite = pi.writePermission == null;
6281
6282            // check if target holds any <path-permission> that match uri
6283            final PathPermission[] pps = pi.pathPermissions;
6284            if (pps != null) {
6285                final String path = grantUri.uri.getPath();
6286                int i = pps.length;
6287                while (i > 0 && (!readMet || !writeMet)) {
6288                    i--;
6289                    PathPermission pp = pps[i];
6290                    if (pp.match(path)) {
6291                        if (!readMet) {
6292                            final String pprperm = pp.getReadPermission();
6293                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6294                                    + pprperm + " for " + pp.getPath()
6295                                    + ": match=" + pp.match(path)
6296                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6297                            if (pprperm != null) {
6298                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6299                                        == PERMISSION_GRANTED) {
6300                                    readMet = true;
6301                                } else {
6302                                    allowDefaultRead = false;
6303                                }
6304                            }
6305                        }
6306                        if (!writeMet) {
6307                            final String ppwperm = pp.getWritePermission();
6308                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6309                                    + ppwperm + " for " + pp.getPath()
6310                                    + ": match=" + pp.match(path)
6311                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6312                            if (ppwperm != null) {
6313                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6314                                        == PERMISSION_GRANTED) {
6315                                    writeMet = true;
6316                                } else {
6317                                    allowDefaultWrite = false;
6318                                }
6319                            }
6320                        }
6321                    }
6322                }
6323            }
6324
6325            // grant unprotected <provider> read/write, if not blocked by
6326            // <path-permission> above
6327            if (allowDefaultRead) readMet = true;
6328            if (allowDefaultWrite) writeMet = true;
6329
6330        } catch (RemoteException e) {
6331            return false;
6332        }
6333
6334        return readMet && writeMet;
6335    }
6336
6337    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6338        ProviderInfo pi = null;
6339        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6340        if (cpr != null) {
6341            pi = cpr.info;
6342        } else {
6343            try {
6344                pi = AppGlobals.getPackageManager().resolveContentProvider(
6345                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6346            } catch (RemoteException ex) {
6347            }
6348        }
6349        return pi;
6350    }
6351
6352    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6353        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6354        if (targetUris != null) {
6355            return targetUris.get(grantUri);
6356        }
6357        return null;
6358    }
6359
6360    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6361            String targetPkg, int targetUid, GrantUri grantUri) {
6362        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6363        if (targetUris == null) {
6364            targetUris = Maps.newArrayMap();
6365            mGrantedUriPermissions.put(targetUid, targetUris);
6366        }
6367
6368        UriPermission perm = targetUris.get(grantUri);
6369        if (perm == null) {
6370            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6371            targetUris.put(grantUri, perm);
6372        }
6373
6374        return perm;
6375    }
6376
6377    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6378            final int modeFlags) {
6379        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6380        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6381                : UriPermission.STRENGTH_OWNED;
6382
6383        // Root gets to do everything.
6384        if (uid == 0) {
6385            return true;
6386        }
6387
6388        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6389        if (perms == null) return false;
6390
6391        // First look for exact match
6392        final UriPermission exactPerm = perms.get(grantUri);
6393        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6394            return true;
6395        }
6396
6397        // No exact match, look for prefixes
6398        final int N = perms.size();
6399        for (int i = 0; i < N; i++) {
6400            final UriPermission perm = perms.valueAt(i);
6401            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6402                    && perm.getStrength(modeFlags) >= minStrength) {
6403                return true;
6404            }
6405        }
6406
6407        return false;
6408    }
6409
6410    @Override
6411    public int checkUriPermission(Uri uri, int pid, int uid,
6412            final int modeFlags, int userId) {
6413        enforceNotIsolatedCaller("checkUriPermission");
6414
6415        // Another redirected-binder-call permissions check as in
6416        // {@link checkComponentPermission}.
6417        Identity tlsIdentity = sCallerIdentity.get();
6418        if (tlsIdentity != null) {
6419            uid = tlsIdentity.uid;
6420            pid = tlsIdentity.pid;
6421        }
6422
6423        // Our own process gets to do everything.
6424        if (pid == MY_PID) {
6425            return PackageManager.PERMISSION_GRANTED;
6426        }
6427        synchronized (this) {
6428            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6429                    ? PackageManager.PERMISSION_GRANTED
6430                    : PackageManager.PERMISSION_DENIED;
6431        }
6432    }
6433
6434    /**
6435     * Check if the targetPkg can be granted permission to access uri by
6436     * the callingUid using the given modeFlags.  Throws a security exception
6437     * if callingUid is not allowed to do this.  Returns the uid of the target
6438     * if the URI permission grant should be performed; returns -1 if it is not
6439     * needed (for example targetPkg already has permission to access the URI).
6440     * If you already know the uid of the target, you can supply it in
6441     * lastTargetUid else set that to -1.
6442     */
6443    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6444            final int modeFlags, int lastTargetUid) {
6445        if (!Intent.isAccessUriMode(modeFlags)) {
6446            return -1;
6447        }
6448
6449        if (targetPkg != null) {
6450            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6451                    "Checking grant " + targetPkg + " permission to " + grantUri);
6452        }
6453
6454        final IPackageManager pm = AppGlobals.getPackageManager();
6455
6456        // If this is not a content: uri, we can't do anything with it.
6457        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6458            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6459                    "Can't grant URI permission for non-content URI: " + grantUri);
6460            return -1;
6461        }
6462
6463        final String authority = grantUri.uri.getAuthority();
6464        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6465        if (pi == null) {
6466            Slog.w(TAG, "No content provider found for permission check: " +
6467                    grantUri.uri.toSafeString());
6468            return -1;
6469        }
6470
6471        int targetUid = lastTargetUid;
6472        if (targetUid < 0 && targetPkg != null) {
6473            try {
6474                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6475                if (targetUid < 0) {
6476                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6477                            "Can't grant URI permission no uid for: " + targetPkg);
6478                    return -1;
6479                }
6480            } catch (RemoteException ex) {
6481                return -1;
6482            }
6483        }
6484
6485        if (targetUid >= 0) {
6486            // First...  does the target actually need this permission?
6487            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6488                // No need to grant the target this permission.
6489                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6490                        "Target " + targetPkg + " already has full permission to " + grantUri);
6491                return -1;
6492            }
6493        } else {
6494            // First...  there is no target package, so can anyone access it?
6495            boolean allowed = pi.exported;
6496            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6497                if (pi.readPermission != null) {
6498                    allowed = false;
6499                }
6500            }
6501            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6502                if (pi.writePermission != null) {
6503                    allowed = false;
6504                }
6505            }
6506            if (allowed) {
6507                return -1;
6508            }
6509        }
6510
6511        /* There is a special cross user grant if:
6512         * - The target is on another user.
6513         * - Apps on the current user can access the uri without any uid permissions.
6514         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6515         * grant uri permissions.
6516         */
6517        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6518                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6519                modeFlags, false /*without considering the uid permissions*/);
6520
6521        // Second...  is the provider allowing granting of URI permissions?
6522        if (!specialCrossUserGrant) {
6523            if (!pi.grantUriPermissions) {
6524                throw new SecurityException("Provider " + pi.packageName
6525                        + "/" + pi.name
6526                        + " does not allow granting of Uri permissions (uri "
6527                        + grantUri + ")");
6528            }
6529            if (pi.uriPermissionPatterns != null) {
6530                final int N = pi.uriPermissionPatterns.length;
6531                boolean allowed = false;
6532                for (int i=0; i<N; i++) {
6533                    if (pi.uriPermissionPatterns[i] != null
6534                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6535                        allowed = true;
6536                        break;
6537                    }
6538                }
6539                if (!allowed) {
6540                    throw new SecurityException("Provider " + pi.packageName
6541                            + "/" + pi.name
6542                            + " does not allow granting of permission to path of Uri "
6543                            + grantUri);
6544                }
6545            }
6546        }
6547
6548        // Third...  does the caller itself have permission to access
6549        // this uri?
6550        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6551            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6552                // Require they hold a strong enough Uri permission
6553                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6554                    throw new SecurityException("Uid " + callingUid
6555                            + " does not have permission to uri " + grantUri);
6556                }
6557            }
6558        }
6559        return targetUid;
6560    }
6561
6562    @Override
6563    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6564            final int modeFlags, int userId) {
6565        enforceNotIsolatedCaller("checkGrantUriPermission");
6566        synchronized(this) {
6567            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6568                    new GrantUri(userId, uri, false), modeFlags, -1);
6569        }
6570    }
6571
6572    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6573            final int modeFlags, UriPermissionOwner owner) {
6574        if (!Intent.isAccessUriMode(modeFlags)) {
6575            return;
6576        }
6577
6578        // So here we are: the caller has the assumed permission
6579        // to the uri, and the target doesn't.  Let's now give this to
6580        // the target.
6581
6582        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6583                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6584
6585        final String authority = grantUri.uri.getAuthority();
6586        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6587        if (pi == null) {
6588            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6589            return;
6590        }
6591
6592        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6593            grantUri.prefix = true;
6594        }
6595        final UriPermission perm = findOrCreateUriPermissionLocked(
6596                pi.packageName, targetPkg, targetUid, grantUri);
6597        perm.grantModes(modeFlags, owner);
6598    }
6599
6600    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6601            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6602        if (targetPkg == null) {
6603            throw new NullPointerException("targetPkg");
6604        }
6605        int targetUid;
6606        final IPackageManager pm = AppGlobals.getPackageManager();
6607        try {
6608            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6609        } catch (RemoteException ex) {
6610            return;
6611        }
6612
6613        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6614                targetUid);
6615        if (targetUid < 0) {
6616            return;
6617        }
6618
6619        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6620                owner);
6621    }
6622
6623    static class NeededUriGrants extends ArrayList<GrantUri> {
6624        final String targetPkg;
6625        final int targetUid;
6626        final int flags;
6627
6628        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6629            this.targetPkg = targetPkg;
6630            this.targetUid = targetUid;
6631            this.flags = flags;
6632        }
6633    }
6634
6635    /**
6636     * Like checkGrantUriPermissionLocked, but takes an Intent.
6637     */
6638    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6639            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6640        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6641                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6642                + " clip=" + (intent != null ? intent.getClipData() : null)
6643                + " from " + intent + "; flags=0x"
6644                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6645
6646        if (targetPkg == null) {
6647            throw new NullPointerException("targetPkg");
6648        }
6649
6650        if (intent == null) {
6651            return null;
6652        }
6653        Uri data = intent.getData();
6654        ClipData clip = intent.getClipData();
6655        if (data == null && clip == null) {
6656            return null;
6657        }
6658        // Default userId for uris in the intent (if they don't specify it themselves)
6659        int contentUserHint = intent.getContentUserHint();
6660        if (contentUserHint == UserHandle.USER_CURRENT) {
6661            contentUserHint = UserHandle.getUserId(callingUid);
6662        }
6663        final IPackageManager pm = AppGlobals.getPackageManager();
6664        int targetUid;
6665        if (needed != null) {
6666            targetUid = needed.targetUid;
6667        } else {
6668            try {
6669                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6670            } catch (RemoteException ex) {
6671                return null;
6672            }
6673            if (targetUid < 0) {
6674                if (DEBUG_URI_PERMISSION) {
6675                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6676                            + " on user " + targetUserId);
6677                }
6678                return null;
6679            }
6680        }
6681        if (data != null) {
6682            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6683            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6684                    targetUid);
6685            if (targetUid > 0) {
6686                if (needed == null) {
6687                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6688                }
6689                needed.add(grantUri);
6690            }
6691        }
6692        if (clip != null) {
6693            for (int i=0; i<clip.getItemCount(); i++) {
6694                Uri uri = clip.getItemAt(i).getUri();
6695                if (uri != null) {
6696                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6697                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6698                            targetUid);
6699                    if (targetUid > 0) {
6700                        if (needed == null) {
6701                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6702                        }
6703                        needed.add(grantUri);
6704                    }
6705                } else {
6706                    Intent clipIntent = clip.getItemAt(i).getIntent();
6707                    if (clipIntent != null) {
6708                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6709                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6710                        if (newNeeded != null) {
6711                            needed = newNeeded;
6712                        }
6713                    }
6714                }
6715            }
6716        }
6717
6718        return needed;
6719    }
6720
6721    /**
6722     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6723     */
6724    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6725            UriPermissionOwner owner) {
6726        if (needed != null) {
6727            for (int i=0; i<needed.size(); i++) {
6728                GrantUri grantUri = needed.get(i);
6729                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6730                        grantUri, needed.flags, owner);
6731            }
6732        }
6733    }
6734
6735    void grantUriPermissionFromIntentLocked(int callingUid,
6736            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6737        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6738                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6739        if (needed == null) {
6740            return;
6741        }
6742
6743        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6744    }
6745
6746    @Override
6747    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6748            final int modeFlags, int userId) {
6749        enforceNotIsolatedCaller("grantUriPermission");
6750        GrantUri grantUri = new GrantUri(userId, uri, false);
6751        synchronized(this) {
6752            final ProcessRecord r = getRecordForAppLocked(caller);
6753            if (r == null) {
6754                throw new SecurityException("Unable to find app for caller "
6755                        + caller
6756                        + " when granting permission to uri " + grantUri);
6757            }
6758            if (targetPkg == null) {
6759                throw new IllegalArgumentException("null target");
6760            }
6761            if (grantUri == null) {
6762                throw new IllegalArgumentException("null uri");
6763            }
6764
6765            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6766                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6767                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6768                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6769
6770            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6771                    UserHandle.getUserId(r.uid));
6772        }
6773    }
6774
6775    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6776        if (perm.modeFlags == 0) {
6777            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6778                    perm.targetUid);
6779            if (perms != null) {
6780                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6781                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6782
6783                perms.remove(perm.uri);
6784                if (perms.isEmpty()) {
6785                    mGrantedUriPermissions.remove(perm.targetUid);
6786                }
6787            }
6788        }
6789    }
6790
6791    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6792        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6793
6794        final IPackageManager pm = AppGlobals.getPackageManager();
6795        final String authority = grantUri.uri.getAuthority();
6796        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6797        if (pi == null) {
6798            Slog.w(TAG, "No content provider found for permission revoke: "
6799                    + grantUri.toSafeString());
6800            return;
6801        }
6802
6803        // Does the caller have this permission on the URI?
6804        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6805            // Right now, if you are not the original owner of the permission,
6806            // you are not allowed to revoke it.
6807            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6808                throw new SecurityException("Uid " + callingUid
6809                        + " does not have permission to uri " + grantUri);
6810            //}
6811        }
6812
6813        boolean persistChanged = false;
6814
6815        // Go through all of the permissions and remove any that match.
6816        int N = mGrantedUriPermissions.size();
6817        for (int i = 0; i < N; i++) {
6818            final int targetUid = mGrantedUriPermissions.keyAt(i);
6819            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6820
6821            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6822                final UriPermission perm = it.next();
6823                if (perm.uri.sourceUserId == grantUri.sourceUserId
6824                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6825                    if (DEBUG_URI_PERMISSION)
6826                        Slog.v(TAG,
6827                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6828                    persistChanged |= perm.revokeModes(
6829                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6830                    if (perm.modeFlags == 0) {
6831                        it.remove();
6832                    }
6833                }
6834            }
6835
6836            if (perms.isEmpty()) {
6837                mGrantedUriPermissions.remove(targetUid);
6838                N--;
6839                i--;
6840            }
6841        }
6842
6843        if (persistChanged) {
6844            schedulePersistUriGrants();
6845        }
6846    }
6847
6848    @Override
6849    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6850            int userId) {
6851        enforceNotIsolatedCaller("revokeUriPermission");
6852        synchronized(this) {
6853            final ProcessRecord r = getRecordForAppLocked(caller);
6854            if (r == null) {
6855                throw new SecurityException("Unable to find app for caller "
6856                        + caller
6857                        + " when revoking permission to uri " + uri);
6858            }
6859            if (uri == null) {
6860                Slog.w(TAG, "revokeUriPermission: null uri");
6861                return;
6862            }
6863
6864            if (!Intent.isAccessUriMode(modeFlags)) {
6865                return;
6866            }
6867
6868            final IPackageManager pm = AppGlobals.getPackageManager();
6869            final String authority = uri.getAuthority();
6870            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6871            if (pi == null) {
6872                Slog.w(TAG, "No content provider found for permission revoke: "
6873                        + uri.toSafeString());
6874                return;
6875            }
6876
6877            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6878        }
6879    }
6880
6881    /**
6882     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6883     * given package.
6884     *
6885     * @param packageName Package name to match, or {@code null} to apply to all
6886     *            packages.
6887     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6888     *            to all users.
6889     * @param persistable If persistable grants should be removed.
6890     */
6891    private void removeUriPermissionsForPackageLocked(
6892            String packageName, int userHandle, boolean persistable) {
6893        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6894            throw new IllegalArgumentException("Must narrow by either package or user");
6895        }
6896
6897        boolean persistChanged = false;
6898
6899        int N = mGrantedUriPermissions.size();
6900        for (int i = 0; i < N; i++) {
6901            final int targetUid = mGrantedUriPermissions.keyAt(i);
6902            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6903
6904            // Only inspect grants matching user
6905            if (userHandle == UserHandle.USER_ALL
6906                    || userHandle == UserHandle.getUserId(targetUid)) {
6907                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6908                    final UriPermission perm = it.next();
6909
6910                    // Only inspect grants matching package
6911                    if (packageName == null || perm.sourcePkg.equals(packageName)
6912                            || perm.targetPkg.equals(packageName)) {
6913                        persistChanged |= perm.revokeModes(
6914                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6915
6916                        // Only remove when no modes remain; any persisted grants
6917                        // will keep this alive.
6918                        if (perm.modeFlags == 0) {
6919                            it.remove();
6920                        }
6921                    }
6922                }
6923
6924                if (perms.isEmpty()) {
6925                    mGrantedUriPermissions.remove(targetUid);
6926                    N--;
6927                    i--;
6928                }
6929            }
6930        }
6931
6932        if (persistChanged) {
6933            schedulePersistUriGrants();
6934        }
6935    }
6936
6937    @Override
6938    public IBinder newUriPermissionOwner(String name) {
6939        enforceNotIsolatedCaller("newUriPermissionOwner");
6940        synchronized(this) {
6941            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6942            return owner.getExternalTokenLocked();
6943        }
6944    }
6945
6946    @Override
6947    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6948            final int modeFlags, int sourceUserId, int targetUserId) {
6949        synchronized(this) {
6950            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6951            if (owner == null) {
6952                throw new IllegalArgumentException("Unknown owner: " + token);
6953            }
6954            if (fromUid != Binder.getCallingUid()) {
6955                if (Binder.getCallingUid() != Process.myUid()) {
6956                    // Only system code can grant URI permissions on behalf
6957                    // of other users.
6958                    throw new SecurityException("nice try");
6959                }
6960            }
6961            if (targetPkg == null) {
6962                throw new IllegalArgumentException("null target");
6963            }
6964            if (uri == null) {
6965                throw new IllegalArgumentException("null uri");
6966            }
6967
6968            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
6969                    modeFlags, owner, targetUserId);
6970        }
6971    }
6972
6973    @Override
6974    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6975        synchronized(this) {
6976            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6977            if (owner == null) {
6978                throw new IllegalArgumentException("Unknown owner: " + token);
6979            }
6980
6981            if (uri == null) {
6982                owner.removeUriPermissionsLocked(mode);
6983            } else {
6984                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6985            }
6986        }
6987    }
6988
6989    private void schedulePersistUriGrants() {
6990        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6991            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6992                    10 * DateUtils.SECOND_IN_MILLIS);
6993        }
6994    }
6995
6996    private void writeGrantedUriPermissions() {
6997        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6998
6999        // Snapshot permissions so we can persist without lock
7000        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7001        synchronized (this) {
7002            final int size = mGrantedUriPermissions.size();
7003            for (int i = 0; i < size; i++) {
7004                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7005                for (UriPermission perm : perms.values()) {
7006                    if (perm.persistedModeFlags != 0) {
7007                        persist.add(perm.snapshot());
7008                    }
7009                }
7010            }
7011        }
7012
7013        FileOutputStream fos = null;
7014        try {
7015            fos = mGrantFile.startWrite();
7016
7017            XmlSerializer out = new FastXmlSerializer();
7018            out.setOutput(fos, "utf-8");
7019            out.startDocument(null, true);
7020            out.startTag(null, TAG_URI_GRANTS);
7021            for (UriPermission.Snapshot perm : persist) {
7022                out.startTag(null, TAG_URI_GRANT);
7023                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7024                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7025                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7026                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7027                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7028                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7029                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7030                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7031                out.endTag(null, TAG_URI_GRANT);
7032            }
7033            out.endTag(null, TAG_URI_GRANTS);
7034            out.endDocument();
7035
7036            mGrantFile.finishWrite(fos);
7037        } catch (IOException e) {
7038            if (fos != null) {
7039                mGrantFile.failWrite(fos);
7040            }
7041        }
7042    }
7043
7044    private void readGrantedUriPermissionsLocked() {
7045        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7046
7047        final long now = System.currentTimeMillis();
7048
7049        FileInputStream fis = null;
7050        try {
7051            fis = mGrantFile.openRead();
7052            final XmlPullParser in = Xml.newPullParser();
7053            in.setInput(fis, null);
7054
7055            int type;
7056            while ((type = in.next()) != END_DOCUMENT) {
7057                final String tag = in.getName();
7058                if (type == START_TAG) {
7059                    if (TAG_URI_GRANT.equals(tag)) {
7060                        final int sourceUserId;
7061                        final int targetUserId;
7062                        final int userHandle = readIntAttribute(in,
7063                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7064                        if (userHandle != UserHandle.USER_NULL) {
7065                            // For backwards compatibility.
7066                            sourceUserId = userHandle;
7067                            targetUserId = userHandle;
7068                        } else {
7069                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7070                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7071                        }
7072                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7073                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7074                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7075                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7076                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7077                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7078
7079                        // Sanity check that provider still belongs to source package
7080                        final ProviderInfo pi = getProviderInfoLocked(
7081                                uri.getAuthority(), sourceUserId);
7082                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7083                            int targetUid = -1;
7084                            try {
7085                                targetUid = AppGlobals.getPackageManager()
7086                                        .getPackageUid(targetPkg, targetUserId);
7087                            } catch (RemoteException e) {
7088                            }
7089                            if (targetUid != -1) {
7090                                final UriPermission perm = findOrCreateUriPermissionLocked(
7091                                        sourcePkg, targetPkg, targetUid,
7092                                        new GrantUri(sourceUserId, uri, prefix));
7093                                perm.initPersistedModes(modeFlags, createdTime);
7094                            }
7095                        } else {
7096                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7097                                    + " but instead found " + pi);
7098                        }
7099                    }
7100                }
7101            }
7102        } catch (FileNotFoundException e) {
7103            // Missing grants is okay
7104        } catch (IOException e) {
7105            Log.wtf(TAG, "Failed reading Uri grants", e);
7106        } catch (XmlPullParserException e) {
7107            Log.wtf(TAG, "Failed reading Uri grants", e);
7108        } finally {
7109            IoUtils.closeQuietly(fis);
7110        }
7111    }
7112
7113    @Override
7114    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7115        enforceNotIsolatedCaller("takePersistableUriPermission");
7116
7117        Preconditions.checkFlagsArgument(modeFlags,
7118                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7119
7120        synchronized (this) {
7121            final int callingUid = Binder.getCallingUid();
7122            boolean persistChanged = false;
7123            GrantUri grantUri = new GrantUri(userId, uri, false);
7124
7125            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7126                    new GrantUri(userId, uri, false));
7127            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7128                    new GrantUri(userId, uri, true));
7129
7130            final boolean exactValid = (exactPerm != null)
7131                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7132            final boolean prefixValid = (prefixPerm != null)
7133                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7134
7135            if (!(exactValid || prefixValid)) {
7136                throw new SecurityException("No persistable permission grants found for UID "
7137                        + callingUid + " and Uri " + grantUri.toSafeString());
7138            }
7139
7140            if (exactValid) {
7141                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7142            }
7143            if (prefixValid) {
7144                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7145            }
7146
7147            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7148
7149            if (persistChanged) {
7150                schedulePersistUriGrants();
7151            }
7152        }
7153    }
7154
7155    @Override
7156    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7157        enforceNotIsolatedCaller("releasePersistableUriPermission");
7158
7159        Preconditions.checkFlagsArgument(modeFlags,
7160                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7161
7162        synchronized (this) {
7163            final int callingUid = Binder.getCallingUid();
7164            boolean persistChanged = false;
7165
7166            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7167                    new GrantUri(userId, uri, false));
7168            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7169                    new GrantUri(userId, uri, true));
7170            if (exactPerm == null && prefixPerm == null) {
7171                throw new SecurityException("No permission grants found for UID " + callingUid
7172                        + " and Uri " + uri.toSafeString());
7173            }
7174
7175            if (exactPerm != null) {
7176                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7177                removeUriPermissionIfNeededLocked(exactPerm);
7178            }
7179            if (prefixPerm != null) {
7180                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7181                removeUriPermissionIfNeededLocked(prefixPerm);
7182            }
7183
7184            if (persistChanged) {
7185                schedulePersistUriGrants();
7186            }
7187        }
7188    }
7189
7190    /**
7191     * Prune any older {@link UriPermission} for the given UID until outstanding
7192     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7193     *
7194     * @return if any mutations occured that require persisting.
7195     */
7196    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7197        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7198        if (perms == null) return false;
7199        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7200
7201        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7202        for (UriPermission perm : perms.values()) {
7203            if (perm.persistedModeFlags != 0) {
7204                persisted.add(perm);
7205            }
7206        }
7207
7208        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7209        if (trimCount <= 0) return false;
7210
7211        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7212        for (int i = 0; i < trimCount; i++) {
7213            final UriPermission perm = persisted.get(i);
7214
7215            if (DEBUG_URI_PERMISSION) {
7216                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7217            }
7218
7219            perm.releasePersistableModes(~0);
7220            removeUriPermissionIfNeededLocked(perm);
7221        }
7222
7223        return true;
7224    }
7225
7226    @Override
7227    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7228            String packageName, boolean incoming) {
7229        enforceNotIsolatedCaller("getPersistedUriPermissions");
7230        Preconditions.checkNotNull(packageName, "packageName");
7231
7232        final int callingUid = Binder.getCallingUid();
7233        final IPackageManager pm = AppGlobals.getPackageManager();
7234        try {
7235            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7236            if (packageUid != callingUid) {
7237                throw new SecurityException(
7238                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7239            }
7240        } catch (RemoteException e) {
7241            throw new SecurityException("Failed to verify package name ownership");
7242        }
7243
7244        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7245        synchronized (this) {
7246            if (incoming) {
7247                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7248                        callingUid);
7249                if (perms == null) {
7250                    Slog.w(TAG, "No permission grants found for " + packageName);
7251                } else {
7252                    for (UriPermission perm : perms.values()) {
7253                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7254                            result.add(perm.buildPersistedPublicApiObject());
7255                        }
7256                    }
7257                }
7258            } else {
7259                final int size = mGrantedUriPermissions.size();
7260                for (int i = 0; i < size; i++) {
7261                    final ArrayMap<GrantUri, UriPermission> perms =
7262                            mGrantedUriPermissions.valueAt(i);
7263                    for (UriPermission perm : perms.values()) {
7264                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7265                            result.add(perm.buildPersistedPublicApiObject());
7266                        }
7267                    }
7268                }
7269            }
7270        }
7271        return new ParceledListSlice<android.content.UriPermission>(result);
7272    }
7273
7274    @Override
7275    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7276        synchronized (this) {
7277            ProcessRecord app =
7278                who != null ? getRecordForAppLocked(who) : null;
7279            if (app == null) return;
7280
7281            Message msg = Message.obtain();
7282            msg.what = WAIT_FOR_DEBUGGER_MSG;
7283            msg.obj = app;
7284            msg.arg1 = waiting ? 1 : 0;
7285            mHandler.sendMessage(msg);
7286        }
7287    }
7288
7289    @Override
7290    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7291        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7292        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7293        outInfo.availMem = Process.getFreeMemory();
7294        outInfo.totalMem = Process.getTotalMemory();
7295        outInfo.threshold = homeAppMem;
7296        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7297        outInfo.hiddenAppThreshold = cachedAppMem;
7298        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7299                ProcessList.SERVICE_ADJ);
7300        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7301                ProcessList.VISIBLE_APP_ADJ);
7302        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7303                ProcessList.FOREGROUND_APP_ADJ);
7304    }
7305
7306    // =========================================================
7307    // TASK MANAGEMENT
7308    // =========================================================
7309
7310    @Override
7311    public List<IAppTask> getAppTasks() {
7312        final PackageManager pm = mContext.getPackageManager();
7313        int callingUid = Binder.getCallingUid();
7314        long ident = Binder.clearCallingIdentity();
7315
7316        // Compose the list of packages for this id to test against
7317        HashSet<String> packages = new HashSet<String>();
7318        String[] uidPackages = pm.getPackagesForUid(callingUid);
7319        for (int i = 0; i < uidPackages.length; i++) {
7320            packages.add(uidPackages[i]);
7321        }
7322
7323        synchronized(this) {
7324            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7325            try {
7326                if (localLOGV) Slog.v(TAG, "getAppTasks");
7327
7328                final int N = mRecentTasks.size();
7329                for (int i = 0; i < N; i++) {
7330                    TaskRecord tr = mRecentTasks.get(i);
7331                    // Skip tasks that are not created by the caller
7332                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7333                        ActivityManager.RecentTaskInfo taskInfo =
7334                                createRecentTaskInfoFromTaskRecord(tr);
7335                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7336                        list.add(taskImpl);
7337                    }
7338                }
7339            } finally {
7340                Binder.restoreCallingIdentity(ident);
7341            }
7342            return list;
7343        }
7344    }
7345
7346    @Override
7347    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7348        final int callingUid = Binder.getCallingUid();
7349        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7350
7351        synchronized(this) {
7352            if (localLOGV) Slog.v(
7353                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7354
7355            final boolean allowed = checkCallingPermission(
7356                    android.Manifest.permission.GET_TASKS)
7357                    == PackageManager.PERMISSION_GRANTED;
7358            if (!allowed) {
7359                Slog.w(TAG, "getTasks: caller " + callingUid
7360                        + " does not hold GET_TASKS; limiting output");
7361            }
7362
7363            // TODO: Improve with MRU list from all ActivityStacks.
7364            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7365        }
7366
7367        return list;
7368    }
7369
7370    TaskRecord getMostRecentTask() {
7371        return mRecentTasks.get(0);
7372    }
7373
7374    /**
7375     * Creates a new RecentTaskInfo from a TaskRecord.
7376     */
7377    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7378        // Update the task description to reflect any changes in the task stack
7379        tr.updateTaskDescription();
7380
7381        // Compose the recent task info
7382        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7383        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7384        rti.persistentId = tr.taskId;
7385        rti.baseIntent = new Intent(tr.getBaseIntent());
7386        rti.origActivity = tr.origActivity;
7387        rti.description = tr.lastDescription;
7388        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7389        rti.userId = tr.userId;
7390        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7391        rti.firstActiveTime = tr.firstActiveTime;
7392        rti.lastActiveTime = tr.lastActiveTime;
7393        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7394        return rti;
7395    }
7396
7397    @Override
7398    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7399        final int callingUid = Binder.getCallingUid();
7400        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7401                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7402
7403        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7404        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7405        synchronized (this) {
7406            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7407                    == PackageManager.PERMISSION_GRANTED;
7408            if (!allowed) {
7409                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7410                        + " does not hold GET_TASKS; limiting output");
7411            }
7412            final boolean detailed = checkCallingPermission(
7413                    android.Manifest.permission.GET_DETAILED_TASKS)
7414                    == PackageManager.PERMISSION_GRANTED;
7415
7416            IPackageManager pm = AppGlobals.getPackageManager();
7417
7418            final int N = mRecentTasks.size();
7419            ArrayList<ActivityManager.RecentTaskInfo> res
7420                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7421                            maxNum < N ? maxNum : N);
7422
7423            final Set<Integer> includedUsers;
7424            if (includeProfiles) {
7425                includedUsers = getProfileIdsLocked(userId);
7426            } else {
7427                includedUsers = new HashSet<Integer>();
7428            }
7429            includedUsers.add(Integer.valueOf(userId));
7430
7431            // Regroup affiliated tasks together.
7432            for (int i = 0; i < N; ) {
7433                TaskRecord task = mRecentTasks.remove(i);
7434                if (mTmpRecents.contains(task)) {
7435                    continue;
7436                }
7437                int affiliatedTaskId = task.mAffiliatedTaskId;
7438                while (true) {
7439                    TaskRecord next = task.mNextAffiliate;
7440                    if (next == null) {
7441                        break;
7442                    }
7443                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7444                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7445                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7446                        task.setNextAffiliate(null);
7447                        if (next.mPrevAffiliate == task) {
7448                            next.setPrevAffiliate(null);
7449                        }
7450                        break;
7451                    }
7452                    if (next.mPrevAffiliate != task) {
7453                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7454                                next.mPrevAffiliate + " task=" + task);
7455                        next.setPrevAffiliate(null);
7456                        break;
7457                    }
7458                    if (!mRecentTasks.contains(next)) {
7459                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7460                        task.setNextAffiliate(null);
7461                        if (next.mPrevAffiliate == task) {
7462                            next.setPrevAffiliate(null);
7463                        }
7464                        break;
7465                    }
7466                    task = next;
7467                }
7468                // task is now the end of the list
7469                do {
7470                    mRecentTasks.remove(task);
7471                    mRecentTasks.add(i++, task);
7472                    mTmpRecents.add(task);
7473                } while ((task = task.mPrevAffiliate) != null);
7474            }
7475            mTmpRecents.clear();
7476            // mRecentTasks is now in sorted, affiliated order.
7477
7478            for (int i=0; i<N && maxNum > 0; i++) {
7479                TaskRecord tr = mRecentTasks.get(i);
7480                // Only add calling user or related users recent tasks
7481                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7482
7483                // Return the entry if desired by the caller.  We always return
7484                // the first entry, because callers always expect this to be the
7485                // foreground app.  We may filter others if the caller has
7486                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7487                // we should exclude the entry.
7488
7489                if (i == 0
7490                        || withExcluded
7491                        || (tr.intent == null)
7492                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7493                                == 0)) {
7494                    if (!allowed) {
7495                        // If the caller doesn't have the GET_TASKS permission, then only
7496                        // allow them to see a small subset of tasks -- their own and home.
7497                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7498                            continue;
7499                        }
7500                    }
7501                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7502                        // Don't include auto remove tasks that are finished or finishing.
7503                        continue;
7504                    }
7505
7506                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7507                    if (!detailed) {
7508                        rti.baseIntent.replaceExtras((Bundle)null);
7509                    }
7510
7511                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7512                        // Check whether this activity is currently available.
7513                        try {
7514                            if (rti.origActivity != null) {
7515                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7516                                        == null) {
7517                                    continue;
7518                                }
7519                            } else if (rti.baseIntent != null) {
7520                                if (pm.queryIntentActivities(rti.baseIntent,
7521                                        null, 0, userId) == null) {
7522                                    continue;
7523                                }
7524                            }
7525                        } catch (RemoteException e) {
7526                            // Will never happen.
7527                        }
7528                    }
7529
7530                    res.add(rti);
7531                    maxNum--;
7532                }
7533            }
7534            return res;
7535        }
7536    }
7537
7538    private TaskRecord recentTaskForIdLocked(int id) {
7539        final int N = mRecentTasks.size();
7540            for (int i=0; i<N; i++) {
7541                TaskRecord tr = mRecentTasks.get(i);
7542                if (tr.taskId == id) {
7543                    return tr;
7544                }
7545            }
7546            return null;
7547    }
7548
7549    @Override
7550    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7551        synchronized (this) {
7552            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7553                    "getTaskThumbnail()");
7554            TaskRecord tr = recentTaskForIdLocked(id);
7555            if (tr != null) {
7556                return tr.getTaskThumbnailLocked();
7557            }
7558        }
7559        return null;
7560    }
7561
7562    @Override
7563    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7564        synchronized (this) {
7565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7566            if (r != null) {
7567                r.taskDescription = td;
7568                r.task.updateTaskDescription();
7569            }
7570        }
7571    }
7572
7573    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7574        if (!pr.killedByAm) {
7575            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7576            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7577                    pr.processName, pr.setAdj, reason);
7578            pr.killedByAm = true;
7579            Process.killProcessQuiet(pr.pid);
7580            Process.killProcessGroup(pr.info.uid, pr.pid);
7581        }
7582    }
7583
7584    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7585        tr.disposeThumbnail();
7586        mRecentTasks.remove(tr);
7587        tr.closeRecentsChain();
7588        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7589        Intent baseIntent = new Intent(
7590                tr.intent != null ? tr.intent : tr.affinityIntent);
7591        ComponentName component = baseIntent.getComponent();
7592        if (component == null) {
7593            Slog.w(TAG, "Now component for base intent of task: " + tr);
7594            return;
7595        }
7596
7597        // Find any running services associated with this app.
7598        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7599
7600        if (killProcesses) {
7601            // Find any running processes associated with this app.
7602            final String pkg = component.getPackageName();
7603            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7604            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7605            for (int i=0; i<pmap.size(); i++) {
7606                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7607                for (int j=0; j<uids.size(); j++) {
7608                    ProcessRecord proc = uids.valueAt(j);
7609                    if (proc.userId != tr.userId) {
7610                        continue;
7611                    }
7612                    if (!proc.pkgList.containsKey(pkg)) {
7613                        continue;
7614                    }
7615                    procs.add(proc);
7616                }
7617            }
7618
7619            // Kill the running processes.
7620            for (int i=0; i<procs.size(); i++) {
7621                ProcessRecord pr = procs.get(i);
7622                if (pr == mHomeProcess) {
7623                    // Don't kill the home process along with tasks from the same package.
7624                    continue;
7625                }
7626                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7627                    killUnneededProcessLocked(pr, "remove task");
7628                } else {
7629                    pr.waitingToKill = "remove task";
7630                }
7631            }
7632        }
7633    }
7634
7635    /**
7636     * Removes the task with the specified task id.
7637     *
7638     * @param taskId Identifier of the task to be removed.
7639     * @param flags Additional operational flags.  May be 0 or
7640     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7641     * @return Returns true if the given task was found and removed.
7642     */
7643    private boolean removeTaskByIdLocked(int taskId, int flags) {
7644        TaskRecord tr = recentTaskForIdLocked(taskId);
7645        if (tr != null) {
7646            tr.removeTaskActivitiesLocked();
7647            cleanUpRemovedTaskLocked(tr, flags);
7648            if (tr.isPersistable) {
7649                notifyTaskPersisterLocked(tr, true);
7650            }
7651            return true;
7652        }
7653        return false;
7654    }
7655
7656    @Override
7657    public boolean removeTask(int taskId, int flags) {
7658        synchronized (this) {
7659            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7660                    "removeTask()");
7661            long ident = Binder.clearCallingIdentity();
7662            try {
7663                return removeTaskByIdLocked(taskId, flags);
7664            } finally {
7665                Binder.restoreCallingIdentity(ident);
7666            }
7667        }
7668    }
7669
7670    /**
7671     * TODO: Add mController hook
7672     */
7673    @Override
7674    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7675        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7676                "moveTaskToFront()");
7677
7678        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7679        synchronized(this) {
7680            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7681                    Binder.getCallingUid(), "Task to front")) {
7682                ActivityOptions.abort(options);
7683                return;
7684            }
7685            final long origId = Binder.clearCallingIdentity();
7686            try {
7687                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7688                if (task == null) {
7689                    return;
7690                }
7691                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7692                    mStackSupervisor.showLockTaskToast();
7693                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7694                    return;
7695                }
7696                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7697                if (prev != null && prev.isRecentsActivity()) {
7698                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7699                }
7700                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7701            } finally {
7702                Binder.restoreCallingIdentity(origId);
7703            }
7704            ActivityOptions.abort(options);
7705        }
7706    }
7707
7708    @Override
7709    public void moveTaskToBack(int taskId) {
7710        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7711                "moveTaskToBack()");
7712
7713        synchronized(this) {
7714            TaskRecord tr = recentTaskForIdLocked(taskId);
7715            if (tr != null) {
7716                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7717                ActivityStack stack = tr.stack;
7718                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7719                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7720                            Binder.getCallingUid(), "Task to back")) {
7721                        return;
7722                    }
7723                }
7724                final long origId = Binder.clearCallingIdentity();
7725                try {
7726                    stack.moveTaskToBackLocked(taskId, null);
7727                } finally {
7728                    Binder.restoreCallingIdentity(origId);
7729                }
7730            }
7731        }
7732    }
7733
7734    /**
7735     * Moves an activity, and all of the other activities within the same task, to the bottom
7736     * of the history stack.  The activity's order within the task is unchanged.
7737     *
7738     * @param token A reference to the activity we wish to move
7739     * @param nonRoot If false then this only works if the activity is the root
7740     *                of a task; if true it will work for any activity in a task.
7741     * @return Returns true if the move completed, false if not.
7742     */
7743    @Override
7744    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7745        enforceNotIsolatedCaller("moveActivityTaskToBack");
7746        synchronized(this) {
7747            final long origId = Binder.clearCallingIdentity();
7748            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7749            if (taskId >= 0) {
7750                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7751            }
7752            Binder.restoreCallingIdentity(origId);
7753        }
7754        return false;
7755    }
7756
7757    @Override
7758    public void moveTaskBackwards(int task) {
7759        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7760                "moveTaskBackwards()");
7761
7762        synchronized(this) {
7763            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7764                    Binder.getCallingUid(), "Task backwards")) {
7765                return;
7766            }
7767            final long origId = Binder.clearCallingIdentity();
7768            moveTaskBackwardsLocked(task);
7769            Binder.restoreCallingIdentity(origId);
7770        }
7771    }
7772
7773    private final void moveTaskBackwardsLocked(int task) {
7774        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7775    }
7776
7777    @Override
7778    public IBinder getHomeActivityToken() throws RemoteException {
7779        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7780                "getHomeActivityToken()");
7781        synchronized (this) {
7782            return mStackSupervisor.getHomeActivityToken();
7783        }
7784    }
7785
7786    @Override
7787    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7788            IActivityContainerCallback callback) throws RemoteException {
7789        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7790                "createActivityContainer()");
7791        synchronized (this) {
7792            if (parentActivityToken == null) {
7793                throw new IllegalArgumentException("parent token must not be null");
7794            }
7795            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7796            if (r == null) {
7797                return null;
7798            }
7799            if (callback == null) {
7800                throw new IllegalArgumentException("callback must not be null");
7801            }
7802            return mStackSupervisor.createActivityContainer(r, callback);
7803        }
7804    }
7805
7806    @Override
7807    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7808        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7809                "deleteActivityContainer()");
7810        synchronized (this) {
7811            mStackSupervisor.deleteActivityContainer(container);
7812        }
7813    }
7814
7815    @Override
7816    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7817            throws RemoteException {
7818        synchronized (this) {
7819            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7820            if (stack != null) {
7821                return stack.mActivityContainer;
7822            }
7823            return null;
7824        }
7825    }
7826
7827    @Override
7828    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7829        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7830                "moveTaskToStack()");
7831        if (stackId == HOME_STACK_ID) {
7832            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7833                    new RuntimeException("here").fillInStackTrace());
7834        }
7835        synchronized (this) {
7836            long ident = Binder.clearCallingIdentity();
7837            try {
7838                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7839                        + stackId + " toTop=" + toTop);
7840                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7841            } finally {
7842                Binder.restoreCallingIdentity(ident);
7843            }
7844        }
7845    }
7846
7847    @Override
7848    public void resizeStack(int stackBoxId, Rect bounds) {
7849        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7850                "resizeStackBox()");
7851        long ident = Binder.clearCallingIdentity();
7852        try {
7853            mWindowManager.resizeStack(stackBoxId, bounds);
7854        } finally {
7855            Binder.restoreCallingIdentity(ident);
7856        }
7857    }
7858
7859    @Override
7860    public List<StackInfo> getAllStackInfos() {
7861        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7862                "getAllStackInfos()");
7863        long ident = Binder.clearCallingIdentity();
7864        try {
7865            synchronized (this) {
7866                return mStackSupervisor.getAllStackInfosLocked();
7867            }
7868        } finally {
7869            Binder.restoreCallingIdentity(ident);
7870        }
7871    }
7872
7873    @Override
7874    public StackInfo getStackInfo(int stackId) {
7875        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7876                "getStackInfo()");
7877        long ident = Binder.clearCallingIdentity();
7878        try {
7879            synchronized (this) {
7880                return mStackSupervisor.getStackInfoLocked(stackId);
7881            }
7882        } finally {
7883            Binder.restoreCallingIdentity(ident);
7884        }
7885    }
7886
7887    @Override
7888    public boolean isInHomeStack(int taskId) {
7889        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7890                "getStackInfo()");
7891        long ident = Binder.clearCallingIdentity();
7892        try {
7893            synchronized (this) {
7894                TaskRecord tr = recentTaskForIdLocked(taskId);
7895                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7896            }
7897        } finally {
7898            Binder.restoreCallingIdentity(ident);
7899        }
7900    }
7901
7902    @Override
7903    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7904        synchronized(this) {
7905            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7906        }
7907    }
7908
7909    private boolean isLockTaskAuthorized(String pkg) {
7910        final DevicePolicyManager dpm = (DevicePolicyManager)
7911                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7912        try {
7913            int uid = mContext.getPackageManager().getPackageUid(pkg,
7914                    Binder.getCallingUserHandle().getIdentifier());
7915            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7916        } catch (NameNotFoundException e) {
7917            return false;
7918        }
7919    }
7920
7921    void startLockTaskMode(TaskRecord task) {
7922        final String pkg;
7923        synchronized (this) {
7924            pkg = task.intent.getComponent().getPackageName();
7925        }
7926        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7927        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7928            final TaskRecord taskRecord = task;
7929            mHandler.post(new Runnable() {
7930                @Override
7931                public void run() {
7932                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7933                }
7934            });
7935            return;
7936        }
7937        long ident = Binder.clearCallingIdentity();
7938        try {
7939            synchronized (this) {
7940                // Since we lost lock on task, make sure it is still there.
7941                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7942                if (task != null) {
7943                    if (!isSystemInitiated
7944                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7945                        throw new IllegalArgumentException("Invalid task, not in foreground");
7946                    }
7947                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7948                }
7949            }
7950        } finally {
7951            Binder.restoreCallingIdentity(ident);
7952        }
7953    }
7954
7955    @Override
7956    public void startLockTaskMode(int taskId) {
7957        final TaskRecord task;
7958        long ident = Binder.clearCallingIdentity();
7959        try {
7960            synchronized (this) {
7961                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7962            }
7963        } finally {
7964            Binder.restoreCallingIdentity(ident);
7965        }
7966        if (task != null) {
7967            startLockTaskMode(task);
7968        }
7969    }
7970
7971    @Override
7972    public void startLockTaskMode(IBinder token) {
7973        final TaskRecord task;
7974        long ident = Binder.clearCallingIdentity();
7975        try {
7976            synchronized (this) {
7977                final ActivityRecord r = ActivityRecord.forToken(token);
7978                if (r == null) {
7979                    return;
7980                }
7981                task = r.task;
7982            }
7983        } finally {
7984            Binder.restoreCallingIdentity(ident);
7985        }
7986        if (task != null) {
7987            startLockTaskMode(task);
7988        }
7989    }
7990
7991    @Override
7992    public void startLockTaskModeOnCurrent() throws RemoteException {
7993        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7994        ActivityRecord r = null;
7995        synchronized (this) {
7996            r = mStackSupervisor.topRunningActivityLocked();
7997        }
7998        startLockTaskMode(r.task);
7999    }
8000
8001    @Override
8002    public void stopLockTaskMode() {
8003        // Verify that the user matches the package of the intent for the TaskRecord
8004        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8005        // and stopLockTaskMode.
8006        final int callingUid = Binder.getCallingUid();
8007        if (callingUid != Process.SYSTEM_UID) {
8008            try {
8009                String pkg =
8010                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8011                int uid = mContext.getPackageManager().getPackageUid(pkg,
8012                        Binder.getCallingUserHandle().getIdentifier());
8013                if (uid != callingUid) {
8014                    throw new SecurityException("Invalid uid, expected " + uid);
8015                }
8016            } catch (NameNotFoundException e) {
8017                Log.d(TAG, "stopLockTaskMode " + e);
8018                return;
8019            }
8020        }
8021        long ident = Binder.clearCallingIdentity();
8022        try {
8023            Log.d(TAG, "stopLockTaskMode");
8024            // Stop lock task
8025            synchronized (this) {
8026                mStackSupervisor.setLockTaskModeLocked(null, false);
8027            }
8028        } finally {
8029            Binder.restoreCallingIdentity(ident);
8030        }
8031    }
8032
8033    @Override
8034    public void stopLockTaskModeOnCurrent() throws RemoteException {
8035        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8036        long ident = Binder.clearCallingIdentity();
8037        try {
8038            stopLockTaskMode();
8039        } finally {
8040            Binder.restoreCallingIdentity(ident);
8041        }
8042    }
8043
8044    @Override
8045    public boolean isInLockTaskMode() {
8046        synchronized (this) {
8047            return mStackSupervisor.isInLockTaskMode();
8048        }
8049    }
8050
8051    // =========================================================
8052    // CONTENT PROVIDERS
8053    // =========================================================
8054
8055    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8056        List<ProviderInfo> providers = null;
8057        try {
8058            providers = AppGlobals.getPackageManager().
8059                queryContentProviders(app.processName, app.uid,
8060                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8061        } catch (RemoteException ex) {
8062        }
8063        if (DEBUG_MU)
8064            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8065        int userId = app.userId;
8066        if (providers != null) {
8067            int N = providers.size();
8068            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8069            for (int i=0; i<N; i++) {
8070                ProviderInfo cpi =
8071                    (ProviderInfo)providers.get(i);
8072                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8073                        cpi.name, cpi.flags);
8074                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8075                    // This is a singleton provider, but a user besides the
8076                    // default user is asking to initialize a process it runs
8077                    // in...  well, no, it doesn't actually run in this process,
8078                    // it runs in the process of the default user.  Get rid of it.
8079                    providers.remove(i);
8080                    N--;
8081                    i--;
8082                    continue;
8083                }
8084
8085                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8086                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8087                if (cpr == null) {
8088                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8089                    mProviderMap.putProviderByClass(comp, cpr);
8090                }
8091                if (DEBUG_MU)
8092                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8093                app.pubProviders.put(cpi.name, cpr);
8094                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8095                    // Don't add this if it is a platform component that is marked
8096                    // to run in multiple processes, because this is actually
8097                    // part of the framework so doesn't make sense to track as a
8098                    // separate apk in the process.
8099                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8100                            mProcessStats);
8101                }
8102                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8103            }
8104        }
8105        return providers;
8106    }
8107
8108    /**
8109     * Check if {@link ProcessRecord} has a possible chance at accessing the
8110     * given {@link ProviderInfo}. Final permission checking is always done
8111     * in {@link ContentProvider}.
8112     */
8113    private final String checkContentProviderPermissionLocked(
8114            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8115        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8116        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8117        boolean checkedGrants = false;
8118        if (checkUser) {
8119            // Looking for cross-user grants before enforcing the typical cross-users permissions
8120            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8121            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8122                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8123                    return null;
8124                }
8125                checkedGrants = true;
8126            }
8127            userId = handleIncomingUser(callingPid, callingUid, userId,
8128                    false, ALLOW_NON_FULL,
8129                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8130            if (userId != tmpTargetUserId) {
8131                // When we actually went to determine the final targer user ID, this ended
8132                // up different than our initial check for the authority.  This is because
8133                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8134                // SELF.  So we need to re-check the grants again.
8135                checkedGrants = false;
8136            }
8137        }
8138        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8139                cpi.applicationInfo.uid, cpi.exported)
8140                == PackageManager.PERMISSION_GRANTED) {
8141            return null;
8142        }
8143        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8144                cpi.applicationInfo.uid, cpi.exported)
8145                == PackageManager.PERMISSION_GRANTED) {
8146            return null;
8147        }
8148
8149        PathPermission[] pps = cpi.pathPermissions;
8150        if (pps != null) {
8151            int i = pps.length;
8152            while (i > 0) {
8153                i--;
8154                PathPermission pp = pps[i];
8155                String pprperm = pp.getReadPermission();
8156                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8157                        cpi.applicationInfo.uid, cpi.exported)
8158                        == PackageManager.PERMISSION_GRANTED) {
8159                    return null;
8160                }
8161                String ppwperm = pp.getWritePermission();
8162                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8163                        cpi.applicationInfo.uid, cpi.exported)
8164                        == PackageManager.PERMISSION_GRANTED) {
8165                    return null;
8166                }
8167            }
8168        }
8169        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8170            return null;
8171        }
8172
8173        String msg;
8174        if (!cpi.exported) {
8175            msg = "Permission Denial: opening provider " + cpi.name
8176                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8177                    + ", uid=" + callingUid + ") that is not exported from uid "
8178                    + cpi.applicationInfo.uid;
8179        } else {
8180            msg = "Permission Denial: opening provider " + cpi.name
8181                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8182                    + ", uid=" + callingUid + ") requires "
8183                    + cpi.readPermission + " or " + cpi.writePermission;
8184        }
8185        Slog.w(TAG, msg);
8186        return msg;
8187    }
8188
8189    /**
8190     * Returns if the ContentProvider has granted a uri to callingUid
8191     */
8192    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8193        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8194        if (perms != null) {
8195            for (int i=perms.size()-1; i>=0; i--) {
8196                GrantUri grantUri = perms.keyAt(i);
8197                if (grantUri.sourceUserId == userId || !checkUser) {
8198                    if (matchesProvider(grantUri.uri, cpi)) {
8199                        return true;
8200                    }
8201                }
8202            }
8203        }
8204        return false;
8205    }
8206
8207    /**
8208     * Returns true if the uri authority is one of the authorities specified in the provider.
8209     */
8210    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8211        String uriAuth = uri.getAuthority();
8212        String cpiAuth = cpi.authority;
8213        if (cpiAuth.indexOf(';') == -1) {
8214            return cpiAuth.equals(uriAuth);
8215        }
8216        String[] cpiAuths = cpiAuth.split(";");
8217        int length = cpiAuths.length;
8218        for (int i = 0; i < length; i++) {
8219            if (cpiAuths[i].equals(uriAuth)) return true;
8220        }
8221        return false;
8222    }
8223
8224    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8225            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8226        if (r != null) {
8227            for (int i=0; i<r.conProviders.size(); i++) {
8228                ContentProviderConnection conn = r.conProviders.get(i);
8229                if (conn.provider == cpr) {
8230                    if (DEBUG_PROVIDER) Slog.v(TAG,
8231                            "Adding provider requested by "
8232                            + r.processName + " from process "
8233                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8234                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8235                    if (stable) {
8236                        conn.stableCount++;
8237                        conn.numStableIncs++;
8238                    } else {
8239                        conn.unstableCount++;
8240                        conn.numUnstableIncs++;
8241                    }
8242                    return conn;
8243                }
8244            }
8245            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8246            if (stable) {
8247                conn.stableCount = 1;
8248                conn.numStableIncs = 1;
8249            } else {
8250                conn.unstableCount = 1;
8251                conn.numUnstableIncs = 1;
8252            }
8253            cpr.connections.add(conn);
8254            r.conProviders.add(conn);
8255            return conn;
8256        }
8257        cpr.addExternalProcessHandleLocked(externalProcessToken);
8258        return null;
8259    }
8260
8261    boolean decProviderCountLocked(ContentProviderConnection conn,
8262            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8263        if (conn != null) {
8264            cpr = conn.provider;
8265            if (DEBUG_PROVIDER) Slog.v(TAG,
8266                    "Removing provider requested by "
8267                    + conn.client.processName + " from process "
8268                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8269                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8270            if (stable) {
8271                conn.stableCount--;
8272            } else {
8273                conn.unstableCount--;
8274            }
8275            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8276                cpr.connections.remove(conn);
8277                conn.client.conProviders.remove(conn);
8278                return true;
8279            }
8280            return false;
8281        }
8282        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8283        return false;
8284    }
8285
8286    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8287            String name, IBinder token, boolean stable, int userId) {
8288        ContentProviderRecord cpr;
8289        ContentProviderConnection conn = null;
8290        ProviderInfo cpi = null;
8291
8292        synchronized(this) {
8293            ProcessRecord r = null;
8294            if (caller != null) {
8295                r = getRecordForAppLocked(caller);
8296                if (r == null) {
8297                    throw new SecurityException(
8298                            "Unable to find app for caller " + caller
8299                          + " (pid=" + Binder.getCallingPid()
8300                          + ") when getting content provider " + name);
8301                }
8302            }
8303
8304            boolean checkCrossUser = true;
8305
8306            // First check if this content provider has been published...
8307            cpr = mProviderMap.getProviderByName(name, userId);
8308            // If that didn't work, check if it exists for user 0 and then
8309            // verify that it's a singleton provider before using it.
8310            if (cpr == null && userId != UserHandle.USER_OWNER) {
8311                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8312                if (cpr != null) {
8313                    cpi = cpr.info;
8314                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8315                            cpi.name, cpi.flags)
8316                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8317                        userId = UserHandle.USER_OWNER;
8318                        checkCrossUser = false;
8319                    } else {
8320                        cpr = null;
8321                        cpi = null;
8322                    }
8323                }
8324            }
8325
8326            boolean providerRunning = cpr != null;
8327            if (providerRunning) {
8328                cpi = cpr.info;
8329                String msg;
8330                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8331                        != null) {
8332                    throw new SecurityException(msg);
8333                }
8334
8335                if (r != null && cpr.canRunHere(r)) {
8336                    // This provider has been published or is in the process
8337                    // of being published...  but it is also allowed to run
8338                    // in the caller's process, so don't make a connection
8339                    // and just let the caller instantiate its own instance.
8340                    ContentProviderHolder holder = cpr.newHolder(null);
8341                    // don't give caller the provider object, it needs
8342                    // to make its own.
8343                    holder.provider = null;
8344                    return holder;
8345                }
8346
8347                final long origId = Binder.clearCallingIdentity();
8348
8349                // In this case the provider instance already exists, so we can
8350                // return it right away.
8351                conn = incProviderCountLocked(r, cpr, token, stable);
8352                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8353                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8354                        // If this is a perceptible app accessing the provider,
8355                        // make sure to count it as being accessed and thus
8356                        // back up on the LRU list.  This is good because
8357                        // content providers are often expensive to start.
8358                        updateLruProcessLocked(cpr.proc, false, null);
8359                    }
8360                }
8361
8362                if (cpr.proc != null) {
8363                    if (false) {
8364                        if (cpr.name.flattenToShortString().equals(
8365                                "com.android.providers.calendar/.CalendarProvider2")) {
8366                            Slog.v(TAG, "****************** KILLING "
8367                                + cpr.name.flattenToShortString());
8368                            Process.killProcess(cpr.proc.pid);
8369                        }
8370                    }
8371                    boolean success = updateOomAdjLocked(cpr.proc);
8372                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8373                    // NOTE: there is still a race here where a signal could be
8374                    // pending on the process even though we managed to update its
8375                    // adj level.  Not sure what to do about this, but at least
8376                    // the race is now smaller.
8377                    if (!success) {
8378                        // Uh oh...  it looks like the provider's process
8379                        // has been killed on us.  We need to wait for a new
8380                        // process to be started, and make sure its death
8381                        // doesn't kill our process.
8382                        Slog.i(TAG,
8383                                "Existing provider " + cpr.name.flattenToShortString()
8384                                + " is crashing; detaching " + r);
8385                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8386                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8387                        if (!lastRef) {
8388                            // This wasn't the last ref our process had on
8389                            // the provider...  we have now been killed, bail.
8390                            return null;
8391                        }
8392                        providerRunning = false;
8393                        conn = null;
8394                    }
8395                }
8396
8397                Binder.restoreCallingIdentity(origId);
8398            }
8399
8400            boolean singleton;
8401            if (!providerRunning) {
8402                try {
8403                    cpi = AppGlobals.getPackageManager().
8404                        resolveContentProvider(name,
8405                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8406                } catch (RemoteException ex) {
8407                }
8408                if (cpi == null) {
8409                    return null;
8410                }
8411                // If the provider is a singleton AND
8412                // (it's a call within the same user || the provider is a
8413                // privileged app)
8414                // Then allow connecting to the singleton provider
8415                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8416                        cpi.name, cpi.flags)
8417                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8418                if (singleton) {
8419                    userId = UserHandle.USER_OWNER;
8420                }
8421                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8422
8423                String msg;
8424                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8425                        != null) {
8426                    throw new SecurityException(msg);
8427                }
8428
8429                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8430                        && !cpi.processName.equals("system")) {
8431                    // If this content provider does not run in the system
8432                    // process, and the system is not yet ready to run other
8433                    // processes, then fail fast instead of hanging.
8434                    throw new IllegalArgumentException(
8435                            "Attempt to launch content provider before system ready");
8436                }
8437
8438                // Make sure that the user who owns this provider is started.  If not,
8439                // we don't want to allow it to run.
8440                if (mStartedUsers.get(userId) == null) {
8441                    Slog.w(TAG, "Unable to launch app "
8442                            + cpi.applicationInfo.packageName + "/"
8443                            + cpi.applicationInfo.uid + " for provider "
8444                            + name + ": user " + userId + " is stopped");
8445                    return null;
8446                }
8447
8448                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8449                cpr = mProviderMap.getProviderByClass(comp, userId);
8450                final boolean firstClass = cpr == null;
8451                if (firstClass) {
8452                    try {
8453                        ApplicationInfo ai =
8454                            AppGlobals.getPackageManager().
8455                                getApplicationInfo(
8456                                        cpi.applicationInfo.packageName,
8457                                        STOCK_PM_FLAGS, userId);
8458                        if (ai == null) {
8459                            Slog.w(TAG, "No package info for content provider "
8460                                    + cpi.name);
8461                            return null;
8462                        }
8463                        ai = getAppInfoForUser(ai, userId);
8464                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8465                    } catch (RemoteException ex) {
8466                        // pm is in same process, this will never happen.
8467                    }
8468                }
8469
8470                if (r != null && cpr.canRunHere(r)) {
8471                    // If this is a multiprocess provider, then just return its
8472                    // info and allow the caller to instantiate it.  Only do
8473                    // this if the provider is the same user as the caller's
8474                    // process, or can run as root (so can be in any process).
8475                    return cpr.newHolder(null);
8476                }
8477
8478                if (DEBUG_PROVIDER) {
8479                    RuntimeException e = new RuntimeException("here");
8480                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8481                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8482                }
8483
8484                // This is single process, and our app is now connecting to it.
8485                // See if we are already in the process of launching this
8486                // provider.
8487                final int N = mLaunchingProviders.size();
8488                int i;
8489                for (i=0; i<N; i++) {
8490                    if (mLaunchingProviders.get(i) == cpr) {
8491                        break;
8492                    }
8493                }
8494
8495                // If the provider is not already being launched, then get it
8496                // started.
8497                if (i >= N) {
8498                    final long origId = Binder.clearCallingIdentity();
8499
8500                    try {
8501                        // Content provider is now in use, its package can't be stopped.
8502                        try {
8503                            AppGlobals.getPackageManager().setPackageStoppedState(
8504                                    cpr.appInfo.packageName, false, userId);
8505                        } catch (RemoteException e) {
8506                        } catch (IllegalArgumentException e) {
8507                            Slog.w(TAG, "Failed trying to unstop package "
8508                                    + cpr.appInfo.packageName + ": " + e);
8509                        }
8510
8511                        // Use existing process if already started
8512                        ProcessRecord proc = getProcessRecordLocked(
8513                                cpi.processName, cpr.appInfo.uid, false);
8514                        if (proc != null && proc.thread != null) {
8515                            if (DEBUG_PROVIDER) {
8516                                Slog.d(TAG, "Installing in existing process " + proc);
8517                            }
8518                            proc.pubProviders.put(cpi.name, cpr);
8519                            try {
8520                                proc.thread.scheduleInstallProvider(cpi);
8521                            } catch (RemoteException e) {
8522                            }
8523                        } else {
8524                            proc = startProcessLocked(cpi.processName,
8525                                    cpr.appInfo, false, 0, "content provider",
8526                                    new ComponentName(cpi.applicationInfo.packageName,
8527                                            cpi.name), false, false, false);
8528                            if (proc == null) {
8529                                Slog.w(TAG, "Unable to launch app "
8530                                        + cpi.applicationInfo.packageName + "/"
8531                                        + cpi.applicationInfo.uid + " for provider "
8532                                        + name + ": process is bad");
8533                                return null;
8534                            }
8535                        }
8536                        cpr.launchingApp = proc;
8537                        mLaunchingProviders.add(cpr);
8538                    } finally {
8539                        Binder.restoreCallingIdentity(origId);
8540                    }
8541                }
8542
8543                // Make sure the provider is published (the same provider class
8544                // may be published under multiple names).
8545                if (firstClass) {
8546                    mProviderMap.putProviderByClass(comp, cpr);
8547                }
8548
8549                mProviderMap.putProviderByName(name, cpr);
8550                conn = incProviderCountLocked(r, cpr, token, stable);
8551                if (conn != null) {
8552                    conn.waiting = true;
8553                }
8554            }
8555        }
8556
8557        // Wait for the provider to be published...
8558        synchronized (cpr) {
8559            while (cpr.provider == null) {
8560                if (cpr.launchingApp == null) {
8561                    Slog.w(TAG, "Unable to launch app "
8562                            + cpi.applicationInfo.packageName + "/"
8563                            + cpi.applicationInfo.uid + " for provider "
8564                            + name + ": launching app became null");
8565                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8566                            UserHandle.getUserId(cpi.applicationInfo.uid),
8567                            cpi.applicationInfo.packageName,
8568                            cpi.applicationInfo.uid, name);
8569                    return null;
8570                }
8571                try {
8572                    if (DEBUG_MU) {
8573                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8574                                + cpr.launchingApp);
8575                    }
8576                    if (conn != null) {
8577                        conn.waiting = true;
8578                    }
8579                    cpr.wait();
8580                } catch (InterruptedException ex) {
8581                } finally {
8582                    if (conn != null) {
8583                        conn.waiting = false;
8584                    }
8585                }
8586            }
8587        }
8588        return cpr != null ? cpr.newHolder(conn) : null;
8589    }
8590
8591    @Override
8592    public final ContentProviderHolder getContentProvider(
8593            IApplicationThread caller, String name, int userId, boolean stable) {
8594        enforceNotIsolatedCaller("getContentProvider");
8595        if (caller == null) {
8596            String msg = "null IApplicationThread when getting content provider "
8597                    + name;
8598            Slog.w(TAG, msg);
8599            throw new SecurityException(msg);
8600        }
8601        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8602        // with cross-user grant.
8603        return getContentProviderImpl(caller, name, null, stable, userId);
8604    }
8605
8606    public ContentProviderHolder getContentProviderExternal(
8607            String name, int userId, IBinder token) {
8608        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8609            "Do not have permission in call getContentProviderExternal()");
8610        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8611                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8612        return getContentProviderExternalUnchecked(name, token, userId);
8613    }
8614
8615    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8616            IBinder token, int userId) {
8617        return getContentProviderImpl(null, name, token, true, userId);
8618    }
8619
8620    /**
8621     * Drop a content provider from a ProcessRecord's bookkeeping
8622     */
8623    public void removeContentProvider(IBinder connection, boolean stable) {
8624        enforceNotIsolatedCaller("removeContentProvider");
8625        long ident = Binder.clearCallingIdentity();
8626        try {
8627            synchronized (this) {
8628                ContentProviderConnection conn;
8629                try {
8630                    conn = (ContentProviderConnection)connection;
8631                } catch (ClassCastException e) {
8632                    String msg ="removeContentProvider: " + connection
8633                            + " not a ContentProviderConnection";
8634                    Slog.w(TAG, msg);
8635                    throw new IllegalArgumentException(msg);
8636                }
8637                if (conn == null) {
8638                    throw new NullPointerException("connection is null");
8639                }
8640                if (decProviderCountLocked(conn, null, null, stable)) {
8641                    updateOomAdjLocked();
8642                }
8643            }
8644        } finally {
8645            Binder.restoreCallingIdentity(ident);
8646        }
8647    }
8648
8649    public void removeContentProviderExternal(String name, IBinder token) {
8650        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8651            "Do not have permission in call removeContentProviderExternal()");
8652        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8653    }
8654
8655    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8656        synchronized (this) {
8657            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8658            if(cpr == null) {
8659                //remove from mProvidersByClass
8660                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8661                return;
8662            }
8663
8664            //update content provider record entry info
8665            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8666            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8667            if (localCpr.hasExternalProcessHandles()) {
8668                if (localCpr.removeExternalProcessHandleLocked(token)) {
8669                    updateOomAdjLocked();
8670                } else {
8671                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8672                            + " with no external reference for token: "
8673                            + token + ".");
8674                }
8675            } else {
8676                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8677                        + " with no external references.");
8678            }
8679        }
8680    }
8681
8682    public final void publishContentProviders(IApplicationThread caller,
8683            List<ContentProviderHolder> providers) {
8684        if (providers == null) {
8685            return;
8686        }
8687
8688        enforceNotIsolatedCaller("publishContentProviders");
8689        synchronized (this) {
8690            final ProcessRecord r = getRecordForAppLocked(caller);
8691            if (DEBUG_MU)
8692                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8693            if (r == null) {
8694                throw new SecurityException(
8695                        "Unable to find app for caller " + caller
8696                      + " (pid=" + Binder.getCallingPid()
8697                      + ") when publishing content providers");
8698            }
8699
8700            final long origId = Binder.clearCallingIdentity();
8701
8702            final int N = providers.size();
8703            for (int i=0; i<N; i++) {
8704                ContentProviderHolder src = providers.get(i);
8705                if (src == null || src.info == null || src.provider == null) {
8706                    continue;
8707                }
8708                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8709                if (DEBUG_MU)
8710                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8711                if (dst != null) {
8712                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8713                    mProviderMap.putProviderByClass(comp, dst);
8714                    String names[] = dst.info.authority.split(";");
8715                    for (int j = 0; j < names.length; j++) {
8716                        mProviderMap.putProviderByName(names[j], dst);
8717                    }
8718
8719                    int NL = mLaunchingProviders.size();
8720                    int j;
8721                    for (j=0; j<NL; j++) {
8722                        if (mLaunchingProviders.get(j) == dst) {
8723                            mLaunchingProviders.remove(j);
8724                            j--;
8725                            NL--;
8726                        }
8727                    }
8728                    synchronized (dst) {
8729                        dst.provider = src.provider;
8730                        dst.proc = r;
8731                        dst.notifyAll();
8732                    }
8733                    updateOomAdjLocked(r);
8734                }
8735            }
8736
8737            Binder.restoreCallingIdentity(origId);
8738        }
8739    }
8740
8741    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8742        ContentProviderConnection conn;
8743        try {
8744            conn = (ContentProviderConnection)connection;
8745        } catch (ClassCastException e) {
8746            String msg ="refContentProvider: " + connection
8747                    + " not a ContentProviderConnection";
8748            Slog.w(TAG, msg);
8749            throw new IllegalArgumentException(msg);
8750        }
8751        if (conn == null) {
8752            throw new NullPointerException("connection is null");
8753        }
8754
8755        synchronized (this) {
8756            if (stable > 0) {
8757                conn.numStableIncs += stable;
8758            }
8759            stable = conn.stableCount + stable;
8760            if (stable < 0) {
8761                throw new IllegalStateException("stableCount < 0: " + stable);
8762            }
8763
8764            if (unstable > 0) {
8765                conn.numUnstableIncs += unstable;
8766            }
8767            unstable = conn.unstableCount + unstable;
8768            if (unstable < 0) {
8769                throw new IllegalStateException("unstableCount < 0: " + unstable);
8770            }
8771
8772            if ((stable+unstable) <= 0) {
8773                throw new IllegalStateException("ref counts can't go to zero here: stable="
8774                        + stable + " unstable=" + unstable);
8775            }
8776            conn.stableCount = stable;
8777            conn.unstableCount = unstable;
8778            return !conn.dead;
8779        }
8780    }
8781
8782    public void unstableProviderDied(IBinder connection) {
8783        ContentProviderConnection conn;
8784        try {
8785            conn = (ContentProviderConnection)connection;
8786        } catch (ClassCastException e) {
8787            String msg ="refContentProvider: " + connection
8788                    + " not a ContentProviderConnection";
8789            Slog.w(TAG, msg);
8790            throw new IllegalArgumentException(msg);
8791        }
8792        if (conn == null) {
8793            throw new NullPointerException("connection is null");
8794        }
8795
8796        // Safely retrieve the content provider associated with the connection.
8797        IContentProvider provider;
8798        synchronized (this) {
8799            provider = conn.provider.provider;
8800        }
8801
8802        if (provider == null) {
8803            // Um, yeah, we're way ahead of you.
8804            return;
8805        }
8806
8807        // Make sure the caller is being honest with us.
8808        if (provider.asBinder().pingBinder()) {
8809            // Er, no, still looks good to us.
8810            synchronized (this) {
8811                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8812                        + " says " + conn + " died, but we don't agree");
8813                return;
8814            }
8815        }
8816
8817        // Well look at that!  It's dead!
8818        synchronized (this) {
8819            if (conn.provider.provider != provider) {
8820                // But something changed...  good enough.
8821                return;
8822            }
8823
8824            ProcessRecord proc = conn.provider.proc;
8825            if (proc == null || proc.thread == null) {
8826                // Seems like the process is already cleaned up.
8827                return;
8828            }
8829
8830            // As far as we're concerned, this is just like receiving a
8831            // death notification...  just a bit prematurely.
8832            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8833                    + ") early provider death");
8834            final long ident = Binder.clearCallingIdentity();
8835            try {
8836                appDiedLocked(proc, proc.pid, proc.thread);
8837            } finally {
8838                Binder.restoreCallingIdentity(ident);
8839            }
8840        }
8841    }
8842
8843    @Override
8844    public void appNotRespondingViaProvider(IBinder connection) {
8845        enforceCallingPermission(
8846                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8847
8848        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8849        if (conn == null) {
8850            Slog.w(TAG, "ContentProviderConnection is null");
8851            return;
8852        }
8853
8854        final ProcessRecord host = conn.provider.proc;
8855        if (host == null) {
8856            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8857            return;
8858        }
8859
8860        final long token = Binder.clearCallingIdentity();
8861        try {
8862            appNotResponding(host, null, null, false, "ContentProvider not responding");
8863        } finally {
8864            Binder.restoreCallingIdentity(token);
8865        }
8866    }
8867
8868    public final void installSystemProviders() {
8869        List<ProviderInfo> providers;
8870        synchronized (this) {
8871            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8872            providers = generateApplicationProvidersLocked(app);
8873            if (providers != null) {
8874                for (int i=providers.size()-1; i>=0; i--) {
8875                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8876                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8877                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8878                                + ": not system .apk");
8879                        providers.remove(i);
8880                    }
8881                }
8882            }
8883        }
8884        if (providers != null) {
8885            mSystemThread.installSystemProviders(providers);
8886        }
8887
8888        mCoreSettingsObserver = new CoreSettingsObserver(this);
8889
8890        //mUsageStatsService.monitorPackages();
8891    }
8892
8893    /**
8894     * Allows app to retrieve the MIME type of a URI without having permission
8895     * to access its content provider.
8896     *
8897     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8898     *
8899     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8900     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8901     */
8902    public String getProviderMimeType(Uri uri, int userId) {
8903        enforceNotIsolatedCaller("getProviderMimeType");
8904        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8905                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8906        final String name = uri.getAuthority();
8907        final long ident = Binder.clearCallingIdentity();
8908        ContentProviderHolder holder = null;
8909
8910        try {
8911            holder = getContentProviderExternalUnchecked(name, null, userId);
8912            if (holder != null) {
8913                return holder.provider.getType(uri);
8914            }
8915        } catch (RemoteException e) {
8916            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8917            return null;
8918        } finally {
8919            if (holder != null) {
8920                removeContentProviderExternalUnchecked(name, null, userId);
8921            }
8922            Binder.restoreCallingIdentity(ident);
8923        }
8924
8925        return null;
8926    }
8927
8928    // =========================================================
8929    // GLOBAL MANAGEMENT
8930    // =========================================================
8931
8932    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8933            boolean isolated) {
8934        String proc = customProcess != null ? customProcess : info.processName;
8935        BatteryStatsImpl.Uid.Proc ps = null;
8936        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8937        int uid = info.uid;
8938        if (isolated) {
8939            int userId = UserHandle.getUserId(uid);
8940            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8941            while (true) {
8942                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8943                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8944                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8945                }
8946                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8947                mNextIsolatedProcessUid++;
8948                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8949                    // No process for this uid, use it.
8950                    break;
8951                }
8952                stepsLeft--;
8953                if (stepsLeft <= 0) {
8954                    return null;
8955                }
8956            }
8957        }
8958        return new ProcessRecord(stats, info, proc, uid);
8959    }
8960
8961    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8962            String abiOverride) {
8963        ProcessRecord app;
8964        if (!isolated) {
8965            app = getProcessRecordLocked(info.processName, info.uid, true);
8966        } else {
8967            app = null;
8968        }
8969
8970        if (app == null) {
8971            app = newProcessRecordLocked(info, null, isolated);
8972            mProcessNames.put(info.processName, app.uid, app);
8973            if (isolated) {
8974                mIsolatedProcesses.put(app.uid, app);
8975            }
8976            updateLruProcessLocked(app, false, null);
8977            updateOomAdjLocked();
8978        }
8979
8980        // This package really, really can not be stopped.
8981        try {
8982            AppGlobals.getPackageManager().setPackageStoppedState(
8983                    info.packageName, false, UserHandle.getUserId(app.uid));
8984        } catch (RemoteException e) {
8985        } catch (IllegalArgumentException e) {
8986            Slog.w(TAG, "Failed trying to unstop package "
8987                    + info.packageName + ": " + e);
8988        }
8989
8990        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8991                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8992            app.persistent = true;
8993            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8994        }
8995        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8996            mPersistentStartingProcesses.add(app);
8997            startProcessLocked(app, "added application", app.processName,
8998                    abiOverride);
8999        }
9000
9001        return app;
9002    }
9003
9004    public void unhandledBack() {
9005        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9006                "unhandledBack()");
9007
9008        synchronized(this) {
9009            final long origId = Binder.clearCallingIdentity();
9010            try {
9011                getFocusedStack().unhandledBackLocked();
9012            } finally {
9013                Binder.restoreCallingIdentity(origId);
9014            }
9015        }
9016    }
9017
9018    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9019        enforceNotIsolatedCaller("openContentUri");
9020        final int userId = UserHandle.getCallingUserId();
9021        String name = uri.getAuthority();
9022        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9023        ParcelFileDescriptor pfd = null;
9024        if (cph != null) {
9025            // We record the binder invoker's uid in thread-local storage before
9026            // going to the content provider to open the file.  Later, in the code
9027            // that handles all permissions checks, we look for this uid and use
9028            // that rather than the Activity Manager's own uid.  The effect is that
9029            // we do the check against the caller's permissions even though it looks
9030            // to the content provider like the Activity Manager itself is making
9031            // the request.
9032            sCallerIdentity.set(new Identity(
9033                    Binder.getCallingPid(), Binder.getCallingUid()));
9034            try {
9035                pfd = cph.provider.openFile(null, uri, "r", null);
9036            } catch (FileNotFoundException e) {
9037                // do nothing; pfd will be returned null
9038            } finally {
9039                // Ensure that whatever happens, we clean up the identity state
9040                sCallerIdentity.remove();
9041            }
9042
9043            // We've got the fd now, so we're done with the provider.
9044            removeContentProviderExternalUnchecked(name, null, userId);
9045        } else {
9046            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9047        }
9048        return pfd;
9049    }
9050
9051    // Actually is sleeping or shutting down or whatever else in the future
9052    // is an inactive state.
9053    public boolean isSleepingOrShuttingDown() {
9054        return mSleeping || mShuttingDown;
9055    }
9056
9057    public boolean isSleeping() {
9058        return mSleeping;
9059    }
9060
9061    void goingToSleep() {
9062        synchronized(this) {
9063            mWentToSleep = true;
9064            updateEventDispatchingLocked();
9065            goToSleepIfNeededLocked();
9066        }
9067    }
9068
9069    void finishRunningVoiceLocked() {
9070        if (mRunningVoice) {
9071            mRunningVoice = false;
9072            goToSleepIfNeededLocked();
9073        }
9074    }
9075
9076    void goToSleepIfNeededLocked() {
9077        if (mWentToSleep && !mRunningVoice) {
9078            if (!mSleeping) {
9079                mSleeping = true;
9080                mStackSupervisor.goingToSleepLocked();
9081
9082                // Initialize the wake times of all processes.
9083                checkExcessivePowerUsageLocked(false);
9084                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9085                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9086                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9087            }
9088        }
9089    }
9090
9091    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9092        mTaskPersister.notify(task, flush);
9093    }
9094
9095    @Override
9096    public boolean shutdown(int timeout) {
9097        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9098                != PackageManager.PERMISSION_GRANTED) {
9099            throw new SecurityException("Requires permission "
9100                    + android.Manifest.permission.SHUTDOWN);
9101        }
9102
9103        boolean timedout = false;
9104
9105        synchronized(this) {
9106            mShuttingDown = true;
9107            updateEventDispatchingLocked();
9108            timedout = mStackSupervisor.shutdownLocked(timeout);
9109        }
9110
9111        mAppOpsService.shutdown();
9112        if (mUsageStatsService != null) {
9113            mUsageStatsService.prepareShutdown();
9114        }
9115        mBatteryStatsService.shutdown();
9116        synchronized (this) {
9117            mProcessStats.shutdownLocked();
9118        }
9119        notifyTaskPersisterLocked(null, true);
9120
9121        return timedout;
9122    }
9123
9124    public final void activitySlept(IBinder token) {
9125        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9126
9127        final long origId = Binder.clearCallingIdentity();
9128
9129        synchronized (this) {
9130            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9131            if (r != null) {
9132                mStackSupervisor.activitySleptLocked(r);
9133            }
9134        }
9135
9136        Binder.restoreCallingIdentity(origId);
9137    }
9138
9139    void logLockScreen(String msg) {
9140        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9141                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9142                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9143                mStackSupervisor.mDismissKeyguardOnNextActivity);
9144    }
9145
9146    private void comeOutOfSleepIfNeededLocked() {
9147        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9148            if (mSleeping) {
9149                mSleeping = false;
9150                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9151            }
9152        }
9153    }
9154
9155    void wakingUp() {
9156        synchronized(this) {
9157            mWentToSleep = false;
9158            updateEventDispatchingLocked();
9159            comeOutOfSleepIfNeededLocked();
9160        }
9161    }
9162
9163    void startRunningVoiceLocked() {
9164        if (!mRunningVoice) {
9165            mRunningVoice = true;
9166            comeOutOfSleepIfNeededLocked();
9167        }
9168    }
9169
9170    private void updateEventDispatchingLocked() {
9171        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9172    }
9173
9174    public void setLockScreenShown(boolean shown) {
9175        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9176                != PackageManager.PERMISSION_GRANTED) {
9177            throw new SecurityException("Requires permission "
9178                    + android.Manifest.permission.DEVICE_POWER);
9179        }
9180
9181        synchronized(this) {
9182            long ident = Binder.clearCallingIdentity();
9183            try {
9184                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9185                mLockScreenShown = shown;
9186                comeOutOfSleepIfNeededLocked();
9187            } finally {
9188                Binder.restoreCallingIdentity(ident);
9189            }
9190        }
9191    }
9192
9193    @Override
9194    public void stopAppSwitches() {
9195        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9196                != PackageManager.PERMISSION_GRANTED) {
9197            throw new SecurityException("Requires permission "
9198                    + android.Manifest.permission.STOP_APP_SWITCHES);
9199        }
9200
9201        synchronized(this) {
9202            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9203                    + APP_SWITCH_DELAY_TIME;
9204            mDidAppSwitch = false;
9205            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9206            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9207            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9208        }
9209    }
9210
9211    public void resumeAppSwitches() {
9212        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9213                != PackageManager.PERMISSION_GRANTED) {
9214            throw new SecurityException("Requires permission "
9215                    + android.Manifest.permission.STOP_APP_SWITCHES);
9216        }
9217
9218        synchronized(this) {
9219            // Note that we don't execute any pending app switches... we will
9220            // let those wait until either the timeout, or the next start
9221            // activity request.
9222            mAppSwitchesAllowedTime = 0;
9223        }
9224    }
9225
9226    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9227            String name) {
9228        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9229            return true;
9230        }
9231
9232        final int perm = checkComponentPermission(
9233                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9234                callingUid, -1, true);
9235        if (perm == PackageManager.PERMISSION_GRANTED) {
9236            return true;
9237        }
9238
9239        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9240        return false;
9241    }
9242
9243    public void setDebugApp(String packageName, boolean waitForDebugger,
9244            boolean persistent) {
9245        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9246                "setDebugApp()");
9247
9248        long ident = Binder.clearCallingIdentity();
9249        try {
9250            // Note that this is not really thread safe if there are multiple
9251            // callers into it at the same time, but that's not a situation we
9252            // care about.
9253            if (persistent) {
9254                final ContentResolver resolver = mContext.getContentResolver();
9255                Settings.Global.putString(
9256                    resolver, Settings.Global.DEBUG_APP,
9257                    packageName);
9258                Settings.Global.putInt(
9259                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9260                    waitForDebugger ? 1 : 0);
9261            }
9262
9263            synchronized (this) {
9264                if (!persistent) {
9265                    mOrigDebugApp = mDebugApp;
9266                    mOrigWaitForDebugger = mWaitForDebugger;
9267                }
9268                mDebugApp = packageName;
9269                mWaitForDebugger = waitForDebugger;
9270                mDebugTransient = !persistent;
9271                if (packageName != null) {
9272                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9273                            false, UserHandle.USER_ALL, "set debug app");
9274                }
9275            }
9276        } finally {
9277            Binder.restoreCallingIdentity(ident);
9278        }
9279    }
9280
9281    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9282        synchronized (this) {
9283            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9284            if (!isDebuggable) {
9285                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9286                    throw new SecurityException("Process not debuggable: " + app.packageName);
9287                }
9288            }
9289
9290            mOpenGlTraceApp = processName;
9291        }
9292    }
9293
9294    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9295            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9296        synchronized (this) {
9297            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9298            if (!isDebuggable) {
9299                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9300                    throw new SecurityException("Process not debuggable: " + app.packageName);
9301                }
9302            }
9303            mProfileApp = processName;
9304            mProfileFile = profileFile;
9305            if (mProfileFd != null) {
9306                try {
9307                    mProfileFd.close();
9308                } catch (IOException e) {
9309                }
9310                mProfileFd = null;
9311            }
9312            mProfileFd = profileFd;
9313            mProfileType = 0;
9314            mAutoStopProfiler = autoStopProfiler;
9315        }
9316    }
9317
9318    @Override
9319    public void setAlwaysFinish(boolean enabled) {
9320        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9321                "setAlwaysFinish()");
9322
9323        Settings.Global.putInt(
9324                mContext.getContentResolver(),
9325                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9326
9327        synchronized (this) {
9328            mAlwaysFinishActivities = enabled;
9329        }
9330    }
9331
9332    @Override
9333    public void setActivityController(IActivityController controller) {
9334        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9335                "setActivityController()");
9336        synchronized (this) {
9337            mController = controller;
9338            Watchdog.getInstance().setActivityController(controller);
9339        }
9340    }
9341
9342    @Override
9343    public void setUserIsMonkey(boolean userIsMonkey) {
9344        synchronized (this) {
9345            synchronized (mPidsSelfLocked) {
9346                final int callingPid = Binder.getCallingPid();
9347                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9348                if (precessRecord == null) {
9349                    throw new SecurityException("Unknown process: " + callingPid);
9350                }
9351                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9352                    throw new SecurityException("Only an instrumentation process "
9353                            + "with a UiAutomation can call setUserIsMonkey");
9354                }
9355            }
9356            mUserIsMonkey = userIsMonkey;
9357        }
9358    }
9359
9360    @Override
9361    public boolean isUserAMonkey() {
9362        synchronized (this) {
9363            // If there is a controller also implies the user is a monkey.
9364            return (mUserIsMonkey || mController != null);
9365        }
9366    }
9367
9368    public void requestBugReport() {
9369        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9370        SystemProperties.set("ctl.start", "bugreport");
9371    }
9372
9373    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9374        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9375    }
9376
9377    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9378        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9379            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9380        }
9381        return KEY_DISPATCHING_TIMEOUT;
9382    }
9383
9384    @Override
9385    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9386        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9387                != PackageManager.PERMISSION_GRANTED) {
9388            throw new SecurityException("Requires permission "
9389                    + android.Manifest.permission.FILTER_EVENTS);
9390        }
9391        ProcessRecord proc;
9392        long timeout;
9393        synchronized (this) {
9394            synchronized (mPidsSelfLocked) {
9395                proc = mPidsSelfLocked.get(pid);
9396            }
9397            timeout = getInputDispatchingTimeoutLocked(proc);
9398        }
9399
9400        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9401            return -1;
9402        }
9403
9404        return timeout;
9405    }
9406
9407    /**
9408     * Handle input dispatching timeouts.
9409     * Returns whether input dispatching should be aborted or not.
9410     */
9411    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9412            final ActivityRecord activity, final ActivityRecord parent,
9413            final boolean aboveSystem, String reason) {
9414        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9415                != PackageManager.PERMISSION_GRANTED) {
9416            throw new SecurityException("Requires permission "
9417                    + android.Manifest.permission.FILTER_EVENTS);
9418        }
9419
9420        final String annotation;
9421        if (reason == null) {
9422            annotation = "Input dispatching timed out";
9423        } else {
9424            annotation = "Input dispatching timed out (" + reason + ")";
9425        }
9426
9427        if (proc != null) {
9428            synchronized (this) {
9429                if (proc.debugging) {
9430                    return false;
9431                }
9432
9433                if (mDidDexOpt) {
9434                    // Give more time since we were dexopting.
9435                    mDidDexOpt = false;
9436                    return false;
9437                }
9438
9439                if (proc.instrumentationClass != null) {
9440                    Bundle info = new Bundle();
9441                    info.putString("shortMsg", "keyDispatchingTimedOut");
9442                    info.putString("longMsg", annotation);
9443                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9444                    return true;
9445                }
9446            }
9447            mHandler.post(new Runnable() {
9448                @Override
9449                public void run() {
9450                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9451                }
9452            });
9453        }
9454
9455        return true;
9456    }
9457
9458    public Bundle getAssistContextExtras(int requestType) {
9459        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9460                "getAssistContextExtras()");
9461        PendingAssistExtras pae;
9462        Bundle extras = new Bundle();
9463        synchronized (this) {
9464            ActivityRecord activity = getFocusedStack().mResumedActivity;
9465            if (activity == null) {
9466                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9467                return null;
9468            }
9469            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9470            if (activity.app == null || activity.app.thread == null) {
9471                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9472                return extras;
9473            }
9474            if (activity.app.pid == Binder.getCallingPid()) {
9475                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9476                return extras;
9477            }
9478            pae = new PendingAssistExtras(activity);
9479            try {
9480                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9481                        requestType);
9482                mPendingAssistExtras.add(pae);
9483                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9484            } catch (RemoteException e) {
9485                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9486                return extras;
9487            }
9488        }
9489        synchronized (pae) {
9490            while (!pae.haveResult) {
9491                try {
9492                    pae.wait();
9493                } catch (InterruptedException e) {
9494                }
9495            }
9496            if (pae.result != null) {
9497                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9498            }
9499        }
9500        synchronized (this) {
9501            mPendingAssistExtras.remove(pae);
9502            mHandler.removeCallbacks(pae);
9503        }
9504        return extras;
9505    }
9506
9507    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9508        PendingAssistExtras pae = (PendingAssistExtras)token;
9509        synchronized (pae) {
9510            pae.result = extras;
9511            pae.haveResult = true;
9512            pae.notifyAll();
9513        }
9514    }
9515
9516    public void registerProcessObserver(IProcessObserver observer) {
9517        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9518                "registerProcessObserver()");
9519        synchronized (this) {
9520            mProcessObservers.register(observer);
9521        }
9522    }
9523
9524    @Override
9525    public void unregisterProcessObserver(IProcessObserver observer) {
9526        synchronized (this) {
9527            mProcessObservers.unregister(observer);
9528        }
9529    }
9530
9531    @Override
9532    public boolean convertFromTranslucent(IBinder token) {
9533        final long origId = Binder.clearCallingIdentity();
9534        try {
9535            synchronized (this) {
9536                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9537                if (r == null) {
9538                    return false;
9539                }
9540                if (r.changeWindowTranslucency(true)) {
9541                    mWindowManager.setAppFullscreen(token, true);
9542                    r.task.stack.releaseMediaResources();
9543                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9544                    return true;
9545                }
9546                return false;
9547            }
9548        } finally {
9549            Binder.restoreCallingIdentity(origId);
9550        }
9551    }
9552
9553    @Override
9554    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9555        final long origId = Binder.clearCallingIdentity();
9556        try {
9557            synchronized (this) {
9558                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9559                if (r == null) {
9560                    return false;
9561                }
9562                if (r.changeWindowTranslucency(false)) {
9563                    r.task.stack.convertToTranslucent(r, options);
9564                    mWindowManager.setAppFullscreen(token, false);
9565                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9566                    return true;
9567                } else {
9568                    r.task.stack.mReturningActivityOptions = options;
9569                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9570                    return false;
9571                }
9572            }
9573        } finally {
9574            Binder.restoreCallingIdentity(origId);
9575        }
9576    }
9577
9578    @Override
9579    public boolean setMediaPlaying(IBinder token, boolean playing) {
9580        final long origId = Binder.clearCallingIdentity();
9581        try {
9582            synchronized (this) {
9583                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9584                if (r != null) {
9585                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9586                }
9587            }
9588            return false;
9589        } finally {
9590            Binder.restoreCallingIdentity(origId);
9591        }
9592    }
9593
9594    @Override
9595    public boolean isBackgroundMediaPlaying(IBinder token) {
9596        final long origId = Binder.clearCallingIdentity();
9597        try {
9598            synchronized (this) {
9599                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9600                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9601                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9602                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9603                return playing;
9604            }
9605        } finally {
9606            Binder.restoreCallingIdentity(origId);
9607        }
9608    }
9609
9610    @Override
9611    public ActivityOptions getActivityOptions(IBinder token) {
9612        final long origId = Binder.clearCallingIdentity();
9613        try {
9614            synchronized (this) {
9615                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9616                if (r != null) {
9617                    final ActivityOptions activityOptions = r.pendingOptions;
9618                    r.pendingOptions = null;
9619                    return activityOptions;
9620                }
9621                return null;
9622            }
9623        } finally {
9624            Binder.restoreCallingIdentity(origId);
9625        }
9626    }
9627
9628    @Override
9629    public void setImmersive(IBinder token, boolean immersive) {
9630        synchronized(this) {
9631            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9632            if (r == null) {
9633                throw new IllegalArgumentException();
9634            }
9635            r.immersive = immersive;
9636
9637            // update associated state if we're frontmost
9638            if (r == mFocusedActivity) {
9639                if (DEBUG_IMMERSIVE) {
9640                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9641                }
9642                applyUpdateLockStateLocked(r);
9643            }
9644        }
9645    }
9646
9647    @Override
9648    public boolean isImmersive(IBinder token) {
9649        synchronized (this) {
9650            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9651            if (r == null) {
9652                throw new IllegalArgumentException();
9653            }
9654            return r.immersive;
9655        }
9656    }
9657
9658    public boolean isTopActivityImmersive() {
9659        enforceNotIsolatedCaller("startActivity");
9660        synchronized (this) {
9661            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9662            return (r != null) ? r.immersive : false;
9663        }
9664    }
9665
9666    @Override
9667    public boolean isTopOfTask(IBinder token) {
9668        synchronized (this) {
9669            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9670            if (r == null) {
9671                throw new IllegalArgumentException();
9672            }
9673            return r.task.getTopActivity() == r;
9674        }
9675    }
9676
9677    public final void enterSafeMode() {
9678        synchronized(this) {
9679            // It only makes sense to do this before the system is ready
9680            // and started launching other packages.
9681            if (!mSystemReady) {
9682                try {
9683                    AppGlobals.getPackageManager().enterSafeMode();
9684                } catch (RemoteException e) {
9685                }
9686            }
9687
9688            mSafeMode = true;
9689        }
9690    }
9691
9692    public final void showSafeModeOverlay() {
9693        View v = LayoutInflater.from(mContext).inflate(
9694                com.android.internal.R.layout.safe_mode, null);
9695        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9696        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9697        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9698        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9699        lp.gravity = Gravity.BOTTOM | Gravity.START;
9700        lp.format = v.getBackground().getOpacity();
9701        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9702                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9703        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9704        ((WindowManager)mContext.getSystemService(
9705                Context.WINDOW_SERVICE)).addView(v, lp);
9706    }
9707
9708    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9709        if (!(sender instanceof PendingIntentRecord)) {
9710            return;
9711        }
9712        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9713        synchronized (stats) {
9714            if (mBatteryStatsService.isOnBattery()) {
9715                mBatteryStatsService.enforceCallingPermission();
9716                PendingIntentRecord rec = (PendingIntentRecord)sender;
9717                int MY_UID = Binder.getCallingUid();
9718                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9719                BatteryStatsImpl.Uid.Pkg pkg =
9720                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9721                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9722                pkg.incWakeupsLocked();
9723            }
9724        }
9725    }
9726
9727    public boolean killPids(int[] pids, String pReason, boolean secure) {
9728        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9729            throw new SecurityException("killPids only available to the system");
9730        }
9731        String reason = (pReason == null) ? "Unknown" : pReason;
9732        // XXX Note: don't acquire main activity lock here, because the window
9733        // manager calls in with its locks held.
9734
9735        boolean killed = false;
9736        synchronized (mPidsSelfLocked) {
9737            int[] types = new int[pids.length];
9738            int worstType = 0;
9739            for (int i=0; i<pids.length; i++) {
9740                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9741                if (proc != null) {
9742                    int type = proc.setAdj;
9743                    types[i] = type;
9744                    if (type > worstType) {
9745                        worstType = type;
9746                    }
9747                }
9748            }
9749
9750            // If the worst oom_adj is somewhere in the cached proc LRU range,
9751            // then constrain it so we will kill all cached procs.
9752            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9753                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9754                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9755            }
9756
9757            // If this is not a secure call, don't let it kill processes that
9758            // are important.
9759            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9760                worstType = ProcessList.SERVICE_ADJ;
9761            }
9762
9763            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9764            for (int i=0; i<pids.length; i++) {
9765                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9766                if (proc == null) {
9767                    continue;
9768                }
9769                int adj = proc.setAdj;
9770                if (adj >= worstType && !proc.killedByAm) {
9771                    killUnneededProcessLocked(proc, reason);
9772                    killed = true;
9773                }
9774            }
9775        }
9776        return killed;
9777    }
9778
9779    @Override
9780    public void killUid(int uid, String reason) {
9781        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9782            throw new SecurityException("killUid only available to the system");
9783        }
9784        synchronized (this) {
9785            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9786                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9787                    reason != null ? reason : "kill uid");
9788        }
9789    }
9790
9791    @Override
9792    public boolean killProcessesBelowForeground(String reason) {
9793        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9794            throw new SecurityException("killProcessesBelowForeground() only available to system");
9795        }
9796
9797        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9798    }
9799
9800    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9801        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9802            throw new SecurityException("killProcessesBelowAdj() only available to system");
9803        }
9804
9805        boolean killed = false;
9806        synchronized (mPidsSelfLocked) {
9807            final int size = mPidsSelfLocked.size();
9808            for (int i = 0; i < size; i++) {
9809                final int pid = mPidsSelfLocked.keyAt(i);
9810                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9811                if (proc == null) continue;
9812
9813                final int adj = proc.setAdj;
9814                if (adj > belowAdj && !proc.killedByAm) {
9815                    killUnneededProcessLocked(proc, reason);
9816                    killed = true;
9817                }
9818            }
9819        }
9820        return killed;
9821    }
9822
9823    @Override
9824    public void hang(final IBinder who, boolean allowRestart) {
9825        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9826                != PackageManager.PERMISSION_GRANTED) {
9827            throw new SecurityException("Requires permission "
9828                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9829        }
9830
9831        final IBinder.DeathRecipient death = new DeathRecipient() {
9832            @Override
9833            public void binderDied() {
9834                synchronized (this) {
9835                    notifyAll();
9836                }
9837            }
9838        };
9839
9840        try {
9841            who.linkToDeath(death, 0);
9842        } catch (RemoteException e) {
9843            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9844            return;
9845        }
9846
9847        synchronized (this) {
9848            Watchdog.getInstance().setAllowRestart(allowRestart);
9849            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9850            synchronized (death) {
9851                while (who.isBinderAlive()) {
9852                    try {
9853                        death.wait();
9854                    } catch (InterruptedException e) {
9855                    }
9856                }
9857            }
9858            Watchdog.getInstance().setAllowRestart(true);
9859        }
9860    }
9861
9862    @Override
9863    public void restart() {
9864        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9865                != PackageManager.PERMISSION_GRANTED) {
9866            throw new SecurityException("Requires permission "
9867                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9868        }
9869
9870        Log.i(TAG, "Sending shutdown broadcast...");
9871
9872        BroadcastReceiver br = new BroadcastReceiver() {
9873            @Override public void onReceive(Context context, Intent intent) {
9874                // Now the broadcast is done, finish up the low-level shutdown.
9875                Log.i(TAG, "Shutting down activity manager...");
9876                shutdown(10000);
9877                Log.i(TAG, "Shutdown complete, restarting!");
9878                Process.killProcess(Process.myPid());
9879                System.exit(10);
9880            }
9881        };
9882
9883        // First send the high-level shut down broadcast.
9884        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9885        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9886        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9887        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9888        mContext.sendOrderedBroadcastAsUser(intent,
9889                UserHandle.ALL, null, br, mHandler, 0, null, null);
9890        */
9891        br.onReceive(mContext, intent);
9892    }
9893
9894    private long getLowRamTimeSinceIdle(long now) {
9895        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9896    }
9897
9898    @Override
9899    public void performIdleMaintenance() {
9900        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9901                != PackageManager.PERMISSION_GRANTED) {
9902            throw new SecurityException("Requires permission "
9903                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9904        }
9905
9906        synchronized (this) {
9907            final long now = SystemClock.uptimeMillis();
9908            final long timeSinceLastIdle = now - mLastIdleTime;
9909            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9910            mLastIdleTime = now;
9911            mLowRamTimeSinceLastIdle = 0;
9912            if (mLowRamStartTime != 0) {
9913                mLowRamStartTime = now;
9914            }
9915
9916            StringBuilder sb = new StringBuilder(128);
9917            sb.append("Idle maintenance over ");
9918            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9919            sb.append(" low RAM for ");
9920            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9921            Slog.i(TAG, sb.toString());
9922
9923            // If at least 1/3 of our time since the last idle period has been spent
9924            // with RAM low, then we want to kill processes.
9925            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9926
9927            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9928                ProcessRecord proc = mLruProcesses.get(i);
9929                if (proc.notCachedSinceIdle) {
9930                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9931                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9932                        if (doKilling && proc.initialIdlePss != 0
9933                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9934                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9935                                    + " from " + proc.initialIdlePss + ")");
9936                        }
9937                    }
9938                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9939                    proc.notCachedSinceIdle = true;
9940                    proc.initialIdlePss = 0;
9941                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9942                            isSleeping(), now);
9943                }
9944            }
9945
9946            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9947            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9948        }
9949    }
9950
9951    private void retrieveSettings() {
9952        final ContentResolver resolver = mContext.getContentResolver();
9953        String debugApp = Settings.Global.getString(
9954            resolver, Settings.Global.DEBUG_APP);
9955        boolean waitForDebugger = Settings.Global.getInt(
9956            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9957        boolean alwaysFinishActivities = Settings.Global.getInt(
9958            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9959        boolean forceRtl = Settings.Global.getInt(
9960                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9961        // Transfer any global setting for forcing RTL layout, into a System Property
9962        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9963
9964        Configuration configuration = new Configuration();
9965        Settings.System.getConfiguration(resolver, configuration);
9966        if (forceRtl) {
9967            // This will take care of setting the correct layout direction flags
9968            configuration.setLayoutDirection(configuration.locale);
9969        }
9970
9971        synchronized (this) {
9972            mDebugApp = mOrigDebugApp = debugApp;
9973            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9974            mAlwaysFinishActivities = alwaysFinishActivities;
9975            // This happens before any activities are started, so we can
9976            // change mConfiguration in-place.
9977            updateConfigurationLocked(configuration, null, false, true);
9978            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9979        }
9980    }
9981
9982    public boolean testIsSystemReady() {
9983        // no need to synchronize(this) just to read & return the value
9984        return mSystemReady;
9985    }
9986
9987    private static File getCalledPreBootReceiversFile() {
9988        File dataDir = Environment.getDataDirectory();
9989        File systemDir = new File(dataDir, "system");
9990        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
9991        return fname;
9992    }
9993
9994    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9995        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9996        File file = getCalledPreBootReceiversFile();
9997        FileInputStream fis = null;
9998        try {
9999            fis = new FileInputStream(file);
10000            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10001            int fvers = dis.readInt();
10002            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10003                String vers = dis.readUTF();
10004                String codename = dis.readUTF();
10005                String build = dis.readUTF();
10006                if (android.os.Build.VERSION.RELEASE.equals(vers)
10007                        && android.os.Build.VERSION.CODENAME.equals(codename)
10008                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10009                    int num = dis.readInt();
10010                    while (num > 0) {
10011                        num--;
10012                        String pkg = dis.readUTF();
10013                        String cls = dis.readUTF();
10014                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10015                    }
10016                }
10017            }
10018        } catch (FileNotFoundException e) {
10019        } catch (IOException e) {
10020            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10021        } finally {
10022            if (fis != null) {
10023                try {
10024                    fis.close();
10025                } catch (IOException e) {
10026                }
10027            }
10028        }
10029        return lastDoneReceivers;
10030    }
10031
10032    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10033        File file = getCalledPreBootReceiversFile();
10034        FileOutputStream fos = null;
10035        DataOutputStream dos = null;
10036        try {
10037            fos = new FileOutputStream(file);
10038            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10039            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10040            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10041            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10042            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10043            dos.writeInt(list.size());
10044            for (int i=0; i<list.size(); i++) {
10045                dos.writeUTF(list.get(i).getPackageName());
10046                dos.writeUTF(list.get(i).getClassName());
10047            }
10048        } catch (IOException e) {
10049            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10050            file.delete();
10051        } finally {
10052            FileUtils.sync(fos);
10053            if (dos != null) {
10054                try {
10055                    dos.close();
10056                } catch (IOException e) {
10057                    // TODO Auto-generated catch block
10058                    e.printStackTrace();
10059                }
10060            }
10061        }
10062    }
10063
10064    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10065            ArrayList<ComponentName> doneReceivers, int userId) {
10066        boolean waitingUpdate = false;
10067        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10068        List<ResolveInfo> ris = null;
10069        try {
10070            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10071                    intent, null, 0, userId);
10072        } catch (RemoteException e) {
10073        }
10074        if (ris != null) {
10075            for (int i=ris.size()-1; i>=0; i--) {
10076                if ((ris.get(i).activityInfo.applicationInfo.flags
10077                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10078                    ris.remove(i);
10079                }
10080            }
10081            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10082
10083            // For User 0, load the version number. When delivering to a new user, deliver
10084            // to all receivers.
10085            if (userId == UserHandle.USER_OWNER) {
10086                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10087                for (int i=0; i<ris.size(); i++) {
10088                    ActivityInfo ai = ris.get(i).activityInfo;
10089                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10090                    if (lastDoneReceivers.contains(comp)) {
10091                        // We already did the pre boot receiver for this app with the current
10092                        // platform version, so don't do it again...
10093                        ris.remove(i);
10094                        i--;
10095                        // ...however, do keep it as one that has been done, so we don't
10096                        // forget about it when rewriting the file of last done receivers.
10097                        doneReceivers.add(comp);
10098                    }
10099                }
10100            }
10101
10102            // If primary user, send broadcast to all available users, else just to userId
10103            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10104                    : new int[] { userId };
10105            for (int i = 0; i < ris.size(); i++) {
10106                ActivityInfo ai = ris.get(i).activityInfo;
10107                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10108                doneReceivers.add(comp);
10109                intent.setComponent(comp);
10110                for (int j=0; j<users.length; j++) {
10111                    IIntentReceiver finisher = null;
10112                    // On last receiver and user, set up a completion callback
10113                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10114                        finisher = new IIntentReceiver.Stub() {
10115                            public void performReceive(Intent intent, int resultCode,
10116                                    String data, Bundle extras, boolean ordered,
10117                                    boolean sticky, int sendingUser) {
10118                                // The raw IIntentReceiver interface is called
10119                                // with the AM lock held, so redispatch to
10120                                // execute our code without the lock.
10121                                mHandler.post(onFinishCallback);
10122                            }
10123                        };
10124                    }
10125                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10126                            + " for user " + users[j]);
10127                    broadcastIntentLocked(null, null, intent, null, finisher,
10128                            0, null, null, null, AppOpsManager.OP_NONE,
10129                            true, false, MY_PID, Process.SYSTEM_UID,
10130                            users[j]);
10131                    if (finisher != null) {
10132                        waitingUpdate = true;
10133                    }
10134                }
10135            }
10136        }
10137
10138        return waitingUpdate;
10139    }
10140
10141    public void systemReady(final Runnable goingCallback) {
10142        synchronized(this) {
10143            if (mSystemReady) {
10144                // If we're done calling all the receivers, run the next "boot phase" passed in
10145                // by the SystemServer
10146                if (goingCallback != null) {
10147                    goingCallback.run();
10148                }
10149                return;
10150            }
10151
10152            // Make sure we have the current profile info, since it is needed for
10153            // security checks.
10154            updateCurrentProfileIdsLocked();
10155
10156            if (mRecentTasks == null) {
10157                mRecentTasks = mTaskPersister.restoreTasksLocked();
10158                if (!mRecentTasks.isEmpty()) {
10159                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10160                }
10161                mTaskPersister.startPersisting();
10162            }
10163
10164            // Check to see if there are any update receivers to run.
10165            if (!mDidUpdate) {
10166                if (mWaitingUpdate) {
10167                    return;
10168                }
10169                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10170                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10171                    public void run() {
10172                        synchronized (ActivityManagerService.this) {
10173                            mDidUpdate = true;
10174                        }
10175                        writeLastDonePreBootReceivers(doneReceivers);
10176                        showBootMessage(mContext.getText(
10177                                R.string.android_upgrading_complete),
10178                                false);
10179                        systemReady(goingCallback);
10180                    }
10181                }, doneReceivers, UserHandle.USER_OWNER);
10182
10183                if (mWaitingUpdate) {
10184                    return;
10185                }
10186                mDidUpdate = true;
10187            }
10188
10189            mAppOpsService.systemReady();
10190            mSystemReady = true;
10191        }
10192
10193        ArrayList<ProcessRecord> procsToKill = null;
10194        synchronized(mPidsSelfLocked) {
10195            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10196                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10197                if (!isAllowedWhileBooting(proc.info)){
10198                    if (procsToKill == null) {
10199                        procsToKill = new ArrayList<ProcessRecord>();
10200                    }
10201                    procsToKill.add(proc);
10202                }
10203            }
10204        }
10205
10206        synchronized(this) {
10207            if (procsToKill != null) {
10208                for (int i=procsToKill.size()-1; i>=0; i--) {
10209                    ProcessRecord proc = procsToKill.get(i);
10210                    Slog.i(TAG, "Removing system update proc: " + proc);
10211                    removeProcessLocked(proc, true, false, "system update done");
10212                }
10213            }
10214
10215            // Now that we have cleaned up any update processes, we
10216            // are ready to start launching real processes and know that
10217            // we won't trample on them any more.
10218            mProcessesReady = true;
10219        }
10220
10221        Slog.i(TAG, "System now ready");
10222        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10223            SystemClock.uptimeMillis());
10224
10225        synchronized(this) {
10226            // Make sure we have no pre-ready processes sitting around.
10227
10228            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10229                ResolveInfo ri = mContext.getPackageManager()
10230                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10231                                STOCK_PM_FLAGS);
10232                CharSequence errorMsg = null;
10233                if (ri != null) {
10234                    ActivityInfo ai = ri.activityInfo;
10235                    ApplicationInfo app = ai.applicationInfo;
10236                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10237                        mTopAction = Intent.ACTION_FACTORY_TEST;
10238                        mTopData = null;
10239                        mTopComponent = new ComponentName(app.packageName,
10240                                ai.name);
10241                    } else {
10242                        errorMsg = mContext.getResources().getText(
10243                                com.android.internal.R.string.factorytest_not_system);
10244                    }
10245                } else {
10246                    errorMsg = mContext.getResources().getText(
10247                            com.android.internal.R.string.factorytest_no_action);
10248                }
10249                if (errorMsg != null) {
10250                    mTopAction = null;
10251                    mTopData = null;
10252                    mTopComponent = null;
10253                    Message msg = Message.obtain();
10254                    msg.what = SHOW_FACTORY_ERROR_MSG;
10255                    msg.getData().putCharSequence("msg", errorMsg);
10256                    mHandler.sendMessage(msg);
10257                }
10258            }
10259        }
10260
10261        retrieveSettings();
10262
10263        synchronized (this) {
10264            readGrantedUriPermissionsLocked();
10265        }
10266
10267        if (goingCallback != null) goingCallback.run();
10268
10269        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10270                Integer.toString(mCurrentUserId), mCurrentUserId);
10271        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10272                Integer.toString(mCurrentUserId), mCurrentUserId);
10273        mSystemServiceManager.startUser(mCurrentUserId);
10274
10275        synchronized (this) {
10276            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10277                try {
10278                    List apps = AppGlobals.getPackageManager().
10279                        getPersistentApplications(STOCK_PM_FLAGS);
10280                    if (apps != null) {
10281                        int N = apps.size();
10282                        int i;
10283                        for (i=0; i<N; i++) {
10284                            ApplicationInfo info
10285                                = (ApplicationInfo)apps.get(i);
10286                            if (info != null &&
10287                                    !info.packageName.equals("android")) {
10288                                addAppLocked(info, false, null /* ABI override */);
10289                            }
10290                        }
10291                    }
10292                } catch (RemoteException ex) {
10293                    // pm is in same process, this will never happen.
10294                }
10295            }
10296
10297            // Start up initial activity.
10298            mBooting = true;
10299
10300            try {
10301                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10302                    Message msg = Message.obtain();
10303                    msg.what = SHOW_UID_ERROR_MSG;
10304                    mHandler.sendMessage(msg);
10305                }
10306            } catch (RemoteException e) {
10307            }
10308
10309            long ident = Binder.clearCallingIdentity();
10310            try {
10311                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10312                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10313                        | Intent.FLAG_RECEIVER_FOREGROUND);
10314                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10315                broadcastIntentLocked(null, null, intent,
10316                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10317                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10318                intent = new Intent(Intent.ACTION_USER_STARTING);
10319                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10320                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10321                broadcastIntentLocked(null, null, intent,
10322                        null, new IIntentReceiver.Stub() {
10323                            @Override
10324                            public void performReceive(Intent intent, int resultCode, String data,
10325                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10326                                    throws RemoteException {
10327                            }
10328                        }, 0, null, null,
10329                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10330                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10331            } catch (Throwable t) {
10332                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10333            } finally {
10334                Binder.restoreCallingIdentity(ident);
10335            }
10336            mStackSupervisor.resumeTopActivitiesLocked();
10337            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10338        }
10339    }
10340
10341    private boolean makeAppCrashingLocked(ProcessRecord app,
10342            String shortMsg, String longMsg, String stackTrace) {
10343        app.crashing = true;
10344        app.crashingReport = generateProcessError(app,
10345                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10346        startAppProblemLocked(app);
10347        app.stopFreezingAllLocked();
10348        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10349    }
10350
10351    private void makeAppNotRespondingLocked(ProcessRecord app,
10352            String activity, String shortMsg, String longMsg) {
10353        app.notResponding = true;
10354        app.notRespondingReport = generateProcessError(app,
10355                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10356                activity, shortMsg, longMsg, null);
10357        startAppProblemLocked(app);
10358        app.stopFreezingAllLocked();
10359    }
10360
10361    /**
10362     * Generate a process error record, suitable for attachment to a ProcessRecord.
10363     *
10364     * @param app The ProcessRecord in which the error occurred.
10365     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10366     *                      ActivityManager.AppErrorStateInfo
10367     * @param activity The activity associated with the crash, if known.
10368     * @param shortMsg Short message describing the crash.
10369     * @param longMsg Long message describing the crash.
10370     * @param stackTrace Full crash stack trace, may be null.
10371     *
10372     * @return Returns a fully-formed AppErrorStateInfo record.
10373     */
10374    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10375            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10376        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10377
10378        report.condition = condition;
10379        report.processName = app.processName;
10380        report.pid = app.pid;
10381        report.uid = app.info.uid;
10382        report.tag = activity;
10383        report.shortMsg = shortMsg;
10384        report.longMsg = longMsg;
10385        report.stackTrace = stackTrace;
10386
10387        return report;
10388    }
10389
10390    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10391        synchronized (this) {
10392            app.crashing = false;
10393            app.crashingReport = null;
10394            app.notResponding = false;
10395            app.notRespondingReport = null;
10396            if (app.anrDialog == fromDialog) {
10397                app.anrDialog = null;
10398            }
10399            if (app.waitDialog == fromDialog) {
10400                app.waitDialog = null;
10401            }
10402            if (app.pid > 0 && app.pid != MY_PID) {
10403                handleAppCrashLocked(app, null, null, null);
10404                killUnneededProcessLocked(app, "user request after error");
10405            }
10406        }
10407    }
10408
10409    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10410            String stackTrace) {
10411        long now = SystemClock.uptimeMillis();
10412
10413        Long crashTime;
10414        if (!app.isolated) {
10415            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10416        } else {
10417            crashTime = null;
10418        }
10419        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10420            // This process loses!
10421            Slog.w(TAG, "Process " + app.info.processName
10422                    + " has crashed too many times: killing!");
10423            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10424                    app.userId, app.info.processName, app.uid);
10425            mStackSupervisor.handleAppCrashLocked(app);
10426            if (!app.persistent) {
10427                // We don't want to start this process again until the user
10428                // explicitly does so...  but for persistent process, we really
10429                // need to keep it running.  If a persistent process is actually
10430                // repeatedly crashing, then badness for everyone.
10431                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10432                        app.info.processName);
10433                if (!app.isolated) {
10434                    // XXX We don't have a way to mark isolated processes
10435                    // as bad, since they don't have a peristent identity.
10436                    mBadProcesses.put(app.info.processName, app.uid,
10437                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10438                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10439                }
10440                app.bad = true;
10441                app.removed = true;
10442                // Don't let services in this process be restarted and potentially
10443                // annoy the user repeatedly.  Unless it is persistent, since those
10444                // processes run critical code.
10445                removeProcessLocked(app, false, false, "crash");
10446                mStackSupervisor.resumeTopActivitiesLocked();
10447                return false;
10448            }
10449            mStackSupervisor.resumeTopActivitiesLocked();
10450        } else {
10451            mStackSupervisor.finishTopRunningActivityLocked(app);
10452        }
10453
10454        // Bump up the crash count of any services currently running in the proc.
10455        for (int i=app.services.size()-1; i>=0; i--) {
10456            // Any services running in the application need to be placed
10457            // back in the pending list.
10458            ServiceRecord sr = app.services.valueAt(i);
10459            sr.crashCount++;
10460        }
10461
10462        // If the crashing process is what we consider to be the "home process" and it has been
10463        // replaced by a third-party app, clear the package preferred activities from packages
10464        // with a home activity running in the process to prevent a repeatedly crashing app
10465        // from blocking the user to manually clear the list.
10466        final ArrayList<ActivityRecord> activities = app.activities;
10467        if (app == mHomeProcess && activities.size() > 0
10468                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10469            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10470                final ActivityRecord r = activities.get(activityNdx);
10471                if (r.isHomeActivity()) {
10472                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10473                    try {
10474                        ActivityThread.getPackageManager()
10475                                .clearPackagePreferredActivities(r.packageName);
10476                    } catch (RemoteException c) {
10477                        // pm is in same process, this will never happen.
10478                    }
10479                }
10480            }
10481        }
10482
10483        if (!app.isolated) {
10484            // XXX Can't keep track of crash times for isolated processes,
10485            // because they don't have a perisistent identity.
10486            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10487        }
10488
10489        return true;
10490    }
10491
10492    void startAppProblemLocked(ProcessRecord app) {
10493        if (app.userId == mCurrentUserId) {
10494            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10495                    mContext, app.info.packageName, app.info.flags);
10496        } else {
10497            // If this app is not running under the current user, then we
10498            // can't give it a report button because that would require
10499            // launching the report UI under a different user.
10500            app.errorReportReceiver = null;
10501        }
10502        skipCurrentReceiverLocked(app);
10503    }
10504
10505    void skipCurrentReceiverLocked(ProcessRecord app) {
10506        for (BroadcastQueue queue : mBroadcastQueues) {
10507            queue.skipCurrentReceiverLocked(app);
10508        }
10509    }
10510
10511    /**
10512     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10513     * The application process will exit immediately after this call returns.
10514     * @param app object of the crashing app, null for the system server
10515     * @param crashInfo describing the exception
10516     */
10517    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10518        ProcessRecord r = findAppProcess(app, "Crash");
10519        final String processName = app == null ? "system_server"
10520                : (r == null ? "unknown" : r.processName);
10521
10522        handleApplicationCrashInner("crash", r, processName, crashInfo);
10523    }
10524
10525    /* Native crash reporting uses this inner version because it needs to be somewhat
10526     * decoupled from the AM-managed cleanup lifecycle
10527     */
10528    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10529            ApplicationErrorReport.CrashInfo crashInfo) {
10530        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10531                UserHandle.getUserId(Binder.getCallingUid()), processName,
10532                r == null ? -1 : r.info.flags,
10533                crashInfo.exceptionClassName,
10534                crashInfo.exceptionMessage,
10535                crashInfo.throwFileName,
10536                crashInfo.throwLineNumber);
10537
10538        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10539
10540        crashApplication(r, crashInfo);
10541    }
10542
10543    public void handleApplicationStrictModeViolation(
10544            IBinder app,
10545            int violationMask,
10546            StrictMode.ViolationInfo info) {
10547        ProcessRecord r = findAppProcess(app, "StrictMode");
10548        if (r == null) {
10549            return;
10550        }
10551
10552        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10553            Integer stackFingerprint = info.hashCode();
10554            boolean logIt = true;
10555            synchronized (mAlreadyLoggedViolatedStacks) {
10556                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10557                    logIt = false;
10558                    // TODO: sub-sample into EventLog for these, with
10559                    // the info.durationMillis?  Then we'd get
10560                    // the relative pain numbers, without logging all
10561                    // the stack traces repeatedly.  We'd want to do
10562                    // likewise in the client code, which also does
10563                    // dup suppression, before the Binder call.
10564                } else {
10565                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10566                        mAlreadyLoggedViolatedStacks.clear();
10567                    }
10568                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10569                }
10570            }
10571            if (logIt) {
10572                logStrictModeViolationToDropBox(r, info);
10573            }
10574        }
10575
10576        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10577            AppErrorResult result = new AppErrorResult();
10578            synchronized (this) {
10579                final long origId = Binder.clearCallingIdentity();
10580
10581                Message msg = Message.obtain();
10582                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10583                HashMap<String, Object> data = new HashMap<String, Object>();
10584                data.put("result", result);
10585                data.put("app", r);
10586                data.put("violationMask", violationMask);
10587                data.put("info", info);
10588                msg.obj = data;
10589                mHandler.sendMessage(msg);
10590
10591                Binder.restoreCallingIdentity(origId);
10592            }
10593            int res = result.get();
10594            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10595        }
10596    }
10597
10598    // Depending on the policy in effect, there could be a bunch of
10599    // these in quick succession so we try to batch these together to
10600    // minimize disk writes, number of dropbox entries, and maximize
10601    // compression, by having more fewer, larger records.
10602    private void logStrictModeViolationToDropBox(
10603            ProcessRecord process,
10604            StrictMode.ViolationInfo info) {
10605        if (info == null) {
10606            return;
10607        }
10608        final boolean isSystemApp = process == null ||
10609                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10610                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10611        final String processName = process == null ? "unknown" : process.processName;
10612        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10613        final DropBoxManager dbox = (DropBoxManager)
10614                mContext.getSystemService(Context.DROPBOX_SERVICE);
10615
10616        // Exit early if the dropbox isn't configured to accept this report type.
10617        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10618
10619        boolean bufferWasEmpty;
10620        boolean needsFlush;
10621        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10622        synchronized (sb) {
10623            bufferWasEmpty = sb.length() == 0;
10624            appendDropBoxProcessHeaders(process, processName, sb);
10625            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10626            sb.append("System-App: ").append(isSystemApp).append("\n");
10627            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10628            if (info.violationNumThisLoop != 0) {
10629                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10630            }
10631            if (info.numAnimationsRunning != 0) {
10632                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10633            }
10634            if (info.broadcastIntentAction != null) {
10635                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10636            }
10637            if (info.durationMillis != -1) {
10638                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10639            }
10640            if (info.numInstances != -1) {
10641                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10642            }
10643            if (info.tags != null) {
10644                for (String tag : info.tags) {
10645                    sb.append("Span-Tag: ").append(tag).append("\n");
10646                }
10647            }
10648            sb.append("\n");
10649            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10650                sb.append(info.crashInfo.stackTrace);
10651            }
10652            sb.append("\n");
10653
10654            // Only buffer up to ~64k.  Various logging bits truncate
10655            // things at 128k.
10656            needsFlush = (sb.length() > 64 * 1024);
10657        }
10658
10659        // Flush immediately if the buffer's grown too large, or this
10660        // is a non-system app.  Non-system apps are isolated with a
10661        // different tag & policy and not batched.
10662        //
10663        // Batching is useful during internal testing with
10664        // StrictMode settings turned up high.  Without batching,
10665        // thousands of separate files could be created on boot.
10666        if (!isSystemApp || needsFlush) {
10667            new Thread("Error dump: " + dropboxTag) {
10668                @Override
10669                public void run() {
10670                    String report;
10671                    synchronized (sb) {
10672                        report = sb.toString();
10673                        sb.delete(0, sb.length());
10674                        sb.trimToSize();
10675                    }
10676                    if (report.length() != 0) {
10677                        dbox.addText(dropboxTag, report);
10678                    }
10679                }
10680            }.start();
10681            return;
10682        }
10683
10684        // System app batching:
10685        if (!bufferWasEmpty) {
10686            // An existing dropbox-writing thread is outstanding, so
10687            // we don't need to start it up.  The existing thread will
10688            // catch the buffer appends we just did.
10689            return;
10690        }
10691
10692        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10693        // (After this point, we shouldn't access AMS internal data structures.)
10694        new Thread("Error dump: " + dropboxTag) {
10695            @Override
10696            public void run() {
10697                // 5 second sleep to let stacks arrive and be batched together
10698                try {
10699                    Thread.sleep(5000);  // 5 seconds
10700                } catch (InterruptedException e) {}
10701
10702                String errorReport;
10703                synchronized (mStrictModeBuffer) {
10704                    errorReport = mStrictModeBuffer.toString();
10705                    if (errorReport.length() == 0) {
10706                        return;
10707                    }
10708                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10709                    mStrictModeBuffer.trimToSize();
10710                }
10711                dbox.addText(dropboxTag, errorReport);
10712            }
10713        }.start();
10714    }
10715
10716    /**
10717     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10718     * @param app object of the crashing app, null for the system server
10719     * @param tag reported by the caller
10720     * @param crashInfo describing the context of the error
10721     * @return true if the process should exit immediately (WTF is fatal)
10722     */
10723    public boolean handleApplicationWtf(IBinder app, String tag,
10724            ApplicationErrorReport.CrashInfo crashInfo) {
10725        ProcessRecord r = findAppProcess(app, "WTF");
10726        final String processName = app == null ? "system_server"
10727                : (r == null ? "unknown" : r.processName);
10728
10729        EventLog.writeEvent(EventLogTags.AM_WTF,
10730                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10731                processName,
10732                r == null ? -1 : r.info.flags,
10733                tag, crashInfo.exceptionMessage);
10734
10735        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10736
10737        if (r != null && r.pid != Process.myPid() &&
10738                Settings.Global.getInt(mContext.getContentResolver(),
10739                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10740            crashApplication(r, crashInfo);
10741            return true;
10742        } else {
10743            return false;
10744        }
10745    }
10746
10747    /**
10748     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10749     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10750     */
10751    private ProcessRecord findAppProcess(IBinder app, String reason) {
10752        if (app == null) {
10753            return null;
10754        }
10755
10756        synchronized (this) {
10757            final int NP = mProcessNames.getMap().size();
10758            for (int ip=0; ip<NP; ip++) {
10759                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10760                final int NA = apps.size();
10761                for (int ia=0; ia<NA; ia++) {
10762                    ProcessRecord p = apps.valueAt(ia);
10763                    if (p.thread != null && p.thread.asBinder() == app) {
10764                        return p;
10765                    }
10766                }
10767            }
10768
10769            Slog.w(TAG, "Can't find mystery application for " + reason
10770                    + " from pid=" + Binder.getCallingPid()
10771                    + " uid=" + Binder.getCallingUid() + ": " + app);
10772            return null;
10773        }
10774    }
10775
10776    /**
10777     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10778     * to append various headers to the dropbox log text.
10779     */
10780    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10781            StringBuilder sb) {
10782        // Watchdog thread ends up invoking this function (with
10783        // a null ProcessRecord) to add the stack file to dropbox.
10784        // Do not acquire a lock on this (am) in such cases, as it
10785        // could cause a potential deadlock, if and when watchdog
10786        // is invoked due to unavailability of lock on am and it
10787        // would prevent watchdog from killing system_server.
10788        if (process == null) {
10789            sb.append("Process: ").append(processName).append("\n");
10790            return;
10791        }
10792        // Note: ProcessRecord 'process' is guarded by the service
10793        // instance.  (notably process.pkgList, which could otherwise change
10794        // concurrently during execution of this method)
10795        synchronized (this) {
10796            sb.append("Process: ").append(processName).append("\n");
10797            int flags = process.info.flags;
10798            IPackageManager pm = AppGlobals.getPackageManager();
10799            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10800            for (int ip=0; ip<process.pkgList.size(); ip++) {
10801                String pkg = process.pkgList.keyAt(ip);
10802                sb.append("Package: ").append(pkg);
10803                try {
10804                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10805                    if (pi != null) {
10806                        sb.append(" v").append(pi.versionCode);
10807                        if (pi.versionName != null) {
10808                            sb.append(" (").append(pi.versionName).append(")");
10809                        }
10810                    }
10811                } catch (RemoteException e) {
10812                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10813                }
10814                sb.append("\n");
10815            }
10816        }
10817    }
10818
10819    private static String processClass(ProcessRecord process) {
10820        if (process == null || process.pid == MY_PID) {
10821            return "system_server";
10822        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10823            return "system_app";
10824        } else {
10825            return "data_app";
10826        }
10827    }
10828
10829    /**
10830     * Write a description of an error (crash, WTF, ANR) to the drop box.
10831     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10832     * @param process which caused the error, null means the system server
10833     * @param activity which triggered the error, null if unknown
10834     * @param parent activity related to the error, null if unknown
10835     * @param subject line related to the error, null if absent
10836     * @param report in long form describing the error, null if absent
10837     * @param logFile to include in the report, null if none
10838     * @param crashInfo giving an application stack trace, null if absent
10839     */
10840    public void addErrorToDropBox(String eventType,
10841            ProcessRecord process, String processName, ActivityRecord activity,
10842            ActivityRecord parent, String subject,
10843            final String report, final File logFile,
10844            final ApplicationErrorReport.CrashInfo crashInfo) {
10845        // NOTE -- this must never acquire the ActivityManagerService lock,
10846        // otherwise the watchdog may be prevented from resetting the system.
10847
10848        final String dropboxTag = processClass(process) + "_" + eventType;
10849        final DropBoxManager dbox = (DropBoxManager)
10850                mContext.getSystemService(Context.DROPBOX_SERVICE);
10851
10852        // Exit early if the dropbox isn't configured to accept this report type.
10853        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10854
10855        final StringBuilder sb = new StringBuilder(1024);
10856        appendDropBoxProcessHeaders(process, processName, sb);
10857        if (activity != null) {
10858            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10859        }
10860        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10861            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10862        }
10863        if (parent != null && parent != activity) {
10864            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10865        }
10866        if (subject != null) {
10867            sb.append("Subject: ").append(subject).append("\n");
10868        }
10869        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10870        if (Debug.isDebuggerConnected()) {
10871            sb.append("Debugger: Connected\n");
10872        }
10873        sb.append("\n");
10874
10875        // Do the rest in a worker thread to avoid blocking the caller on I/O
10876        // (After this point, we shouldn't access AMS internal data structures.)
10877        Thread worker = new Thread("Error dump: " + dropboxTag) {
10878            @Override
10879            public void run() {
10880                if (report != null) {
10881                    sb.append(report);
10882                }
10883                if (logFile != null) {
10884                    try {
10885                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10886                                    "\n\n[[TRUNCATED]]"));
10887                    } catch (IOException e) {
10888                        Slog.e(TAG, "Error reading " + logFile, e);
10889                    }
10890                }
10891                if (crashInfo != null && crashInfo.stackTrace != null) {
10892                    sb.append(crashInfo.stackTrace);
10893                }
10894
10895                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10896                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10897                if (lines > 0) {
10898                    sb.append("\n");
10899
10900                    // Merge several logcat streams, and take the last N lines
10901                    InputStreamReader input = null;
10902                    try {
10903                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10904                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10905                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10906
10907                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10908                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10909                        input = new InputStreamReader(logcat.getInputStream());
10910
10911                        int num;
10912                        char[] buf = new char[8192];
10913                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10914                    } catch (IOException e) {
10915                        Slog.e(TAG, "Error running logcat", e);
10916                    } finally {
10917                        if (input != null) try { input.close(); } catch (IOException e) {}
10918                    }
10919                }
10920
10921                dbox.addText(dropboxTag, sb.toString());
10922            }
10923        };
10924
10925        if (process == null) {
10926            // If process is null, we are being called from some internal code
10927            // and may be about to die -- run this synchronously.
10928            worker.run();
10929        } else {
10930            worker.start();
10931        }
10932    }
10933
10934    /**
10935     * Bring up the "unexpected error" dialog box for a crashing app.
10936     * Deal with edge cases (intercepts from instrumented applications,
10937     * ActivityController, error intent receivers, that sort of thing).
10938     * @param r the application crashing
10939     * @param crashInfo describing the failure
10940     */
10941    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10942        long timeMillis = System.currentTimeMillis();
10943        String shortMsg = crashInfo.exceptionClassName;
10944        String longMsg = crashInfo.exceptionMessage;
10945        String stackTrace = crashInfo.stackTrace;
10946        if (shortMsg != null && longMsg != null) {
10947            longMsg = shortMsg + ": " + longMsg;
10948        } else if (shortMsg != null) {
10949            longMsg = shortMsg;
10950        }
10951
10952        AppErrorResult result = new AppErrorResult();
10953        synchronized (this) {
10954            if (mController != null) {
10955                try {
10956                    String name = r != null ? r.processName : null;
10957                    int pid = r != null ? r.pid : Binder.getCallingPid();
10958                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10959                    if (!mController.appCrashed(name, pid,
10960                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10961                        Slog.w(TAG, "Force-killing crashed app " + name
10962                                + " at watcher's request");
10963                        Process.killProcess(pid);
10964                        if (r != null) {
10965                            Process.killProcessGroup(uid, pid);
10966                        }
10967                        return;
10968                    }
10969                } catch (RemoteException e) {
10970                    mController = null;
10971                    Watchdog.getInstance().setActivityController(null);
10972                }
10973            }
10974
10975            final long origId = Binder.clearCallingIdentity();
10976
10977            // If this process is running instrumentation, finish it.
10978            if (r != null && r.instrumentationClass != null) {
10979                Slog.w(TAG, "Error in app " + r.processName
10980                      + " running instrumentation " + r.instrumentationClass + ":");
10981                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10982                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10983                Bundle info = new Bundle();
10984                info.putString("shortMsg", shortMsg);
10985                info.putString("longMsg", longMsg);
10986                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10987                Binder.restoreCallingIdentity(origId);
10988                return;
10989            }
10990
10991            // If we can't identify the process or it's already exceeded its crash quota,
10992            // quit right away without showing a crash dialog.
10993            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10994                Binder.restoreCallingIdentity(origId);
10995                return;
10996            }
10997
10998            Message msg = Message.obtain();
10999            msg.what = SHOW_ERROR_MSG;
11000            HashMap data = new HashMap();
11001            data.put("result", result);
11002            data.put("app", r);
11003            msg.obj = data;
11004            mHandler.sendMessage(msg);
11005
11006            Binder.restoreCallingIdentity(origId);
11007        }
11008
11009        int res = result.get();
11010
11011        Intent appErrorIntent = null;
11012        synchronized (this) {
11013            if (r != null && !r.isolated) {
11014                // XXX Can't keep track of crash time for isolated processes,
11015                // since they don't have a persistent identity.
11016                mProcessCrashTimes.put(r.info.processName, r.uid,
11017                        SystemClock.uptimeMillis());
11018            }
11019            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11020                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11021            }
11022        }
11023
11024        if (appErrorIntent != null) {
11025            try {
11026                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11027            } catch (ActivityNotFoundException e) {
11028                Slog.w(TAG, "bug report receiver dissappeared", e);
11029            }
11030        }
11031    }
11032
11033    Intent createAppErrorIntentLocked(ProcessRecord r,
11034            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11035        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11036        if (report == null) {
11037            return null;
11038        }
11039        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11040        result.setComponent(r.errorReportReceiver);
11041        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11042        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11043        return result;
11044    }
11045
11046    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11047            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11048        if (r.errorReportReceiver == null) {
11049            return null;
11050        }
11051
11052        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11053            return null;
11054        }
11055
11056        ApplicationErrorReport report = new ApplicationErrorReport();
11057        report.packageName = r.info.packageName;
11058        report.installerPackageName = r.errorReportReceiver.getPackageName();
11059        report.processName = r.processName;
11060        report.time = timeMillis;
11061        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11062
11063        if (r.crashing || r.forceCrashReport) {
11064            report.type = ApplicationErrorReport.TYPE_CRASH;
11065            report.crashInfo = crashInfo;
11066        } else if (r.notResponding) {
11067            report.type = ApplicationErrorReport.TYPE_ANR;
11068            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11069
11070            report.anrInfo.activity = r.notRespondingReport.tag;
11071            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11072            report.anrInfo.info = r.notRespondingReport.longMsg;
11073        }
11074
11075        return report;
11076    }
11077
11078    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11079        enforceNotIsolatedCaller("getProcessesInErrorState");
11080        // assume our apps are happy - lazy create the list
11081        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11082
11083        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11084                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11085        int userId = UserHandle.getUserId(Binder.getCallingUid());
11086
11087        synchronized (this) {
11088
11089            // iterate across all processes
11090            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11091                ProcessRecord app = mLruProcesses.get(i);
11092                if (!allUsers && app.userId != userId) {
11093                    continue;
11094                }
11095                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11096                    // This one's in trouble, so we'll generate a report for it
11097                    // crashes are higher priority (in case there's a crash *and* an anr)
11098                    ActivityManager.ProcessErrorStateInfo report = null;
11099                    if (app.crashing) {
11100                        report = app.crashingReport;
11101                    } else if (app.notResponding) {
11102                        report = app.notRespondingReport;
11103                    }
11104
11105                    if (report != null) {
11106                        if (errList == null) {
11107                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11108                        }
11109                        errList.add(report);
11110                    } else {
11111                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11112                                " crashing = " + app.crashing +
11113                                " notResponding = " + app.notResponding);
11114                    }
11115                }
11116            }
11117        }
11118
11119        return errList;
11120    }
11121
11122    static int procStateToImportance(int procState, int memAdj,
11123            ActivityManager.RunningAppProcessInfo currApp) {
11124        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11125        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11126            currApp.lru = memAdj;
11127        } else {
11128            currApp.lru = 0;
11129        }
11130        return imp;
11131    }
11132
11133    private void fillInProcMemInfo(ProcessRecord app,
11134            ActivityManager.RunningAppProcessInfo outInfo) {
11135        outInfo.pid = app.pid;
11136        outInfo.uid = app.info.uid;
11137        if (mHeavyWeightProcess == app) {
11138            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11139        }
11140        if (app.persistent) {
11141            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11142        }
11143        if (app.activities.size() > 0) {
11144            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11145        }
11146        outInfo.lastTrimLevel = app.trimMemoryLevel;
11147        int adj = app.curAdj;
11148        int procState = app.curProcState;
11149        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11150        outInfo.importanceReasonCode = app.adjTypeCode;
11151        outInfo.processState = app.curProcState;
11152    }
11153
11154    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11155        enforceNotIsolatedCaller("getRunningAppProcesses");
11156        // Lazy instantiation of list
11157        List<ActivityManager.RunningAppProcessInfo> runList = null;
11158        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11159                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11160        int userId = UserHandle.getUserId(Binder.getCallingUid());
11161        synchronized (this) {
11162            // Iterate across all processes
11163            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11164                ProcessRecord app = mLruProcesses.get(i);
11165                if (!allUsers && app.userId != userId) {
11166                    continue;
11167                }
11168                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11169                    // Generate process state info for running application
11170                    ActivityManager.RunningAppProcessInfo currApp =
11171                        new ActivityManager.RunningAppProcessInfo(app.processName,
11172                                app.pid, app.getPackageList());
11173                    fillInProcMemInfo(app, currApp);
11174                    if (app.adjSource instanceof ProcessRecord) {
11175                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11176                        currApp.importanceReasonImportance =
11177                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11178                                        app.adjSourceProcState);
11179                    } else if (app.adjSource instanceof ActivityRecord) {
11180                        ActivityRecord r = (ActivityRecord)app.adjSource;
11181                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11182                    }
11183                    if (app.adjTarget instanceof ComponentName) {
11184                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11185                    }
11186                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11187                    //        + " lru=" + currApp.lru);
11188                    if (runList == null) {
11189                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11190                    }
11191                    runList.add(currApp);
11192                }
11193            }
11194        }
11195        return runList;
11196    }
11197
11198    public List<ApplicationInfo> getRunningExternalApplications() {
11199        enforceNotIsolatedCaller("getRunningExternalApplications");
11200        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11201        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11202        if (runningApps != null && runningApps.size() > 0) {
11203            Set<String> extList = new HashSet<String>();
11204            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11205                if (app.pkgList != null) {
11206                    for (String pkg : app.pkgList) {
11207                        extList.add(pkg);
11208                    }
11209                }
11210            }
11211            IPackageManager pm = AppGlobals.getPackageManager();
11212            for (String pkg : extList) {
11213                try {
11214                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11215                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11216                        retList.add(info);
11217                    }
11218                } catch (RemoteException e) {
11219                }
11220            }
11221        }
11222        return retList;
11223    }
11224
11225    @Override
11226    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11227        enforceNotIsolatedCaller("getMyMemoryState");
11228        synchronized (this) {
11229            ProcessRecord proc;
11230            synchronized (mPidsSelfLocked) {
11231                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11232            }
11233            fillInProcMemInfo(proc, outInfo);
11234        }
11235    }
11236
11237    @Override
11238    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11239        if (checkCallingPermission(android.Manifest.permission.DUMP)
11240                != PackageManager.PERMISSION_GRANTED) {
11241            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11242                    + Binder.getCallingPid()
11243                    + ", uid=" + Binder.getCallingUid()
11244                    + " without permission "
11245                    + android.Manifest.permission.DUMP);
11246            return;
11247        }
11248
11249        boolean dumpAll = false;
11250        boolean dumpClient = false;
11251        String dumpPackage = null;
11252
11253        int opti = 0;
11254        while (opti < args.length) {
11255            String opt = args[opti];
11256            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11257                break;
11258            }
11259            opti++;
11260            if ("-a".equals(opt)) {
11261                dumpAll = true;
11262            } else if ("-c".equals(opt)) {
11263                dumpClient = true;
11264            } else if ("-h".equals(opt)) {
11265                pw.println("Activity manager dump options:");
11266                pw.println("  [-a] [-c] [-h] [cmd] ...");
11267                pw.println("  cmd may be one of:");
11268                pw.println("    a[ctivities]: activity stack state");
11269                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11270                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11271                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11272                pw.println("    o[om]: out of memory management");
11273                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11274                pw.println("    provider [COMP_SPEC]: provider client-side state");
11275                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11276                pw.println("    service [COMP_SPEC]: service client-side state");
11277                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11278                pw.println("    all: dump all activities");
11279                pw.println("    top: dump the top activity");
11280                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11281                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11282                pw.println("    a partial substring in a component name, a");
11283                pw.println("    hex object identifier.");
11284                pw.println("  -a: include all available server state.");
11285                pw.println("  -c: include client state.");
11286                return;
11287            } else {
11288                pw.println("Unknown argument: " + opt + "; use -h for help");
11289            }
11290        }
11291
11292        long origId = Binder.clearCallingIdentity();
11293        boolean more = false;
11294        // Is the caller requesting to dump a particular piece of data?
11295        if (opti < args.length) {
11296            String cmd = args[opti];
11297            opti++;
11298            if ("activities".equals(cmd) || "a".equals(cmd)) {
11299                synchronized (this) {
11300                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11301                }
11302            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11303                String[] newArgs;
11304                String name;
11305                if (opti >= args.length) {
11306                    name = null;
11307                    newArgs = EMPTY_STRING_ARRAY;
11308                } else {
11309                    name = args[opti];
11310                    opti++;
11311                    newArgs = new String[args.length - opti];
11312                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11313                            args.length - opti);
11314                }
11315                synchronized (this) {
11316                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11317                }
11318            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11319                String[] newArgs;
11320                String name;
11321                if (opti >= args.length) {
11322                    name = null;
11323                    newArgs = EMPTY_STRING_ARRAY;
11324                } else {
11325                    name = args[opti];
11326                    opti++;
11327                    newArgs = new String[args.length - opti];
11328                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11329                            args.length - opti);
11330                }
11331                synchronized (this) {
11332                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11333                }
11334            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11335                String[] newArgs;
11336                String name;
11337                if (opti >= args.length) {
11338                    name = null;
11339                    newArgs = EMPTY_STRING_ARRAY;
11340                } else {
11341                    name = args[opti];
11342                    opti++;
11343                    newArgs = new String[args.length - opti];
11344                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11345                            args.length - opti);
11346                }
11347                synchronized (this) {
11348                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11349                }
11350            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11351                synchronized (this) {
11352                    dumpOomLocked(fd, pw, args, opti, true);
11353                }
11354            } else if ("provider".equals(cmd)) {
11355                String[] newArgs;
11356                String name;
11357                if (opti >= args.length) {
11358                    name = null;
11359                    newArgs = EMPTY_STRING_ARRAY;
11360                } else {
11361                    name = args[opti];
11362                    opti++;
11363                    newArgs = new String[args.length - opti];
11364                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11365                }
11366                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11367                    pw.println("No providers match: " + name);
11368                    pw.println("Use -h for help.");
11369                }
11370            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11371                synchronized (this) {
11372                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11373                }
11374            } else if ("service".equals(cmd)) {
11375                String[] newArgs;
11376                String name;
11377                if (opti >= args.length) {
11378                    name = null;
11379                    newArgs = EMPTY_STRING_ARRAY;
11380                } else {
11381                    name = args[opti];
11382                    opti++;
11383                    newArgs = new String[args.length - opti];
11384                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11385                            args.length - opti);
11386                }
11387                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11388                    pw.println("No services match: " + name);
11389                    pw.println("Use -h for help.");
11390                }
11391            } else if ("package".equals(cmd)) {
11392                String[] newArgs;
11393                if (opti >= args.length) {
11394                    pw.println("package: no package name specified");
11395                    pw.println("Use -h for help.");
11396                } else {
11397                    dumpPackage = args[opti];
11398                    opti++;
11399                    newArgs = new String[args.length - opti];
11400                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11401                            args.length - opti);
11402                    args = newArgs;
11403                    opti = 0;
11404                    more = true;
11405                }
11406            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11407                synchronized (this) {
11408                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11409                }
11410            } else {
11411                // Dumping a single activity?
11412                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11413                    pw.println("Bad activity command, or no activities match: " + cmd);
11414                    pw.println("Use -h for help.");
11415                }
11416            }
11417            if (!more) {
11418                Binder.restoreCallingIdentity(origId);
11419                return;
11420            }
11421        }
11422
11423        // No piece of data specified, dump everything.
11424        synchronized (this) {
11425            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11426            pw.println();
11427            if (dumpAll) {
11428                pw.println("-------------------------------------------------------------------------------");
11429            }
11430            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11431            pw.println();
11432            if (dumpAll) {
11433                pw.println("-------------------------------------------------------------------------------");
11434            }
11435            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11436            pw.println();
11437            if (dumpAll) {
11438                pw.println("-------------------------------------------------------------------------------");
11439            }
11440            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11441            pw.println();
11442            if (dumpAll) {
11443                pw.println("-------------------------------------------------------------------------------");
11444            }
11445            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11446            pw.println();
11447            if (dumpAll) {
11448                pw.println("-------------------------------------------------------------------------------");
11449            }
11450            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11451        }
11452        Binder.restoreCallingIdentity(origId);
11453    }
11454
11455    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11456            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11457        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11458
11459        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11460                dumpPackage);
11461        boolean needSep = printedAnything;
11462
11463        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11464                dumpPackage, needSep, "  mFocusedActivity: ");
11465        if (printed) {
11466            printedAnything = true;
11467            needSep = false;
11468        }
11469
11470        if (dumpPackage == null) {
11471            if (needSep) {
11472                pw.println();
11473            }
11474            needSep = true;
11475            printedAnything = true;
11476            mStackSupervisor.dump(pw, "  ");
11477        }
11478
11479        if (mRecentTasks.size() > 0) {
11480            boolean printedHeader = false;
11481
11482            final int N = mRecentTasks.size();
11483            for (int i=0; i<N; i++) {
11484                TaskRecord tr = mRecentTasks.get(i);
11485                if (dumpPackage != null) {
11486                    if (tr.realActivity == null ||
11487                            !dumpPackage.equals(tr.realActivity)) {
11488                        continue;
11489                    }
11490                }
11491                if (!printedHeader) {
11492                    if (needSep) {
11493                        pw.println();
11494                    }
11495                    pw.println("  Recent tasks:");
11496                    printedHeader = true;
11497                    printedAnything = true;
11498                }
11499                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11500                        pw.println(tr);
11501                if (dumpAll) {
11502                    mRecentTasks.get(i).dump(pw, "    ");
11503                }
11504            }
11505        }
11506
11507        if (!printedAnything) {
11508            pw.println("  (nothing)");
11509        }
11510    }
11511
11512    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11513            int opti, boolean dumpAll, String dumpPackage) {
11514        boolean needSep = false;
11515        boolean printedAnything = false;
11516        int numPers = 0;
11517
11518        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11519
11520        if (dumpAll) {
11521            final int NP = mProcessNames.getMap().size();
11522            for (int ip=0; ip<NP; ip++) {
11523                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11524                final int NA = procs.size();
11525                for (int ia=0; ia<NA; ia++) {
11526                    ProcessRecord r = procs.valueAt(ia);
11527                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11528                        continue;
11529                    }
11530                    if (!needSep) {
11531                        pw.println("  All known processes:");
11532                        needSep = true;
11533                        printedAnything = true;
11534                    }
11535                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11536                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11537                        pw.print(" "); pw.println(r);
11538                    r.dump(pw, "    ");
11539                    if (r.persistent) {
11540                        numPers++;
11541                    }
11542                }
11543            }
11544        }
11545
11546        if (mIsolatedProcesses.size() > 0) {
11547            boolean printed = false;
11548            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11549                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11550                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11551                    continue;
11552                }
11553                if (!printed) {
11554                    if (needSep) {
11555                        pw.println();
11556                    }
11557                    pw.println("  Isolated process list (sorted by uid):");
11558                    printedAnything = true;
11559                    printed = true;
11560                    needSep = true;
11561                }
11562                pw.println(String.format("%sIsolated #%2d: %s",
11563                        "    ", i, r.toString()));
11564            }
11565        }
11566
11567        if (mLruProcesses.size() > 0) {
11568            if (needSep) {
11569                pw.println();
11570            }
11571            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11572                    pw.print(" total, non-act at ");
11573                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11574                    pw.print(", non-svc at ");
11575                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11576                    pw.println("):");
11577            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11578            needSep = true;
11579            printedAnything = true;
11580        }
11581
11582        if (dumpAll || dumpPackage != null) {
11583            synchronized (mPidsSelfLocked) {
11584                boolean printed = false;
11585                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11586                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11587                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11588                        continue;
11589                    }
11590                    if (!printed) {
11591                        if (needSep) pw.println();
11592                        needSep = true;
11593                        pw.println("  PID mappings:");
11594                        printed = true;
11595                        printedAnything = true;
11596                    }
11597                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11598                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11599                }
11600            }
11601        }
11602
11603        if (mForegroundProcesses.size() > 0) {
11604            synchronized (mPidsSelfLocked) {
11605                boolean printed = false;
11606                for (int i=0; i<mForegroundProcesses.size(); i++) {
11607                    ProcessRecord r = mPidsSelfLocked.get(
11608                            mForegroundProcesses.valueAt(i).pid);
11609                    if (dumpPackage != null && (r == null
11610                            || !r.pkgList.containsKey(dumpPackage))) {
11611                        continue;
11612                    }
11613                    if (!printed) {
11614                        if (needSep) pw.println();
11615                        needSep = true;
11616                        pw.println("  Foreground Processes:");
11617                        printed = true;
11618                        printedAnything = true;
11619                    }
11620                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11621                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11622                }
11623            }
11624        }
11625
11626        if (mPersistentStartingProcesses.size() > 0) {
11627            if (needSep) pw.println();
11628            needSep = true;
11629            printedAnything = true;
11630            pw.println("  Persisent processes that are starting:");
11631            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11632                    "Starting Norm", "Restarting PERS", dumpPackage);
11633        }
11634
11635        if (mRemovedProcesses.size() > 0) {
11636            if (needSep) pw.println();
11637            needSep = true;
11638            printedAnything = true;
11639            pw.println("  Processes that are being removed:");
11640            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11641                    "Removed Norm", "Removed PERS", dumpPackage);
11642        }
11643
11644        if (mProcessesOnHold.size() > 0) {
11645            if (needSep) pw.println();
11646            needSep = true;
11647            printedAnything = true;
11648            pw.println("  Processes that are on old until the system is ready:");
11649            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11650                    "OnHold Norm", "OnHold PERS", dumpPackage);
11651        }
11652
11653        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11654
11655        if (mProcessCrashTimes.getMap().size() > 0) {
11656            boolean printed = false;
11657            long now = SystemClock.uptimeMillis();
11658            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11659            final int NP = pmap.size();
11660            for (int ip=0; ip<NP; ip++) {
11661                String pname = pmap.keyAt(ip);
11662                SparseArray<Long> uids = pmap.valueAt(ip);
11663                final int N = uids.size();
11664                for (int i=0; i<N; i++) {
11665                    int puid = uids.keyAt(i);
11666                    ProcessRecord r = mProcessNames.get(pname, puid);
11667                    if (dumpPackage != null && (r == null
11668                            || !r.pkgList.containsKey(dumpPackage))) {
11669                        continue;
11670                    }
11671                    if (!printed) {
11672                        if (needSep) pw.println();
11673                        needSep = true;
11674                        pw.println("  Time since processes crashed:");
11675                        printed = true;
11676                        printedAnything = true;
11677                    }
11678                    pw.print("    Process "); pw.print(pname);
11679                            pw.print(" uid "); pw.print(puid);
11680                            pw.print(": last crashed ");
11681                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11682                            pw.println(" ago");
11683                }
11684            }
11685        }
11686
11687        if (mBadProcesses.getMap().size() > 0) {
11688            boolean printed = false;
11689            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11690            final int NP = pmap.size();
11691            for (int ip=0; ip<NP; ip++) {
11692                String pname = pmap.keyAt(ip);
11693                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11694                final int N = uids.size();
11695                for (int i=0; i<N; i++) {
11696                    int puid = uids.keyAt(i);
11697                    ProcessRecord r = mProcessNames.get(pname, puid);
11698                    if (dumpPackage != null && (r == null
11699                            || !r.pkgList.containsKey(dumpPackage))) {
11700                        continue;
11701                    }
11702                    if (!printed) {
11703                        if (needSep) pw.println();
11704                        needSep = true;
11705                        pw.println("  Bad processes:");
11706                        printedAnything = true;
11707                    }
11708                    BadProcessInfo info = uids.valueAt(i);
11709                    pw.print("    Bad process "); pw.print(pname);
11710                            pw.print(" uid "); pw.print(puid);
11711                            pw.print(": crashed at time "); pw.println(info.time);
11712                    if (info.shortMsg != null) {
11713                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11714                    }
11715                    if (info.longMsg != null) {
11716                        pw.print("      Long msg: "); pw.println(info.longMsg);
11717                    }
11718                    if (info.stack != null) {
11719                        pw.println("      Stack:");
11720                        int lastPos = 0;
11721                        for (int pos=0; pos<info.stack.length(); pos++) {
11722                            if (info.stack.charAt(pos) == '\n') {
11723                                pw.print("        ");
11724                                pw.write(info.stack, lastPos, pos-lastPos);
11725                                pw.println();
11726                                lastPos = pos+1;
11727                            }
11728                        }
11729                        if (lastPos < info.stack.length()) {
11730                            pw.print("        ");
11731                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11732                            pw.println();
11733                        }
11734                    }
11735                }
11736            }
11737        }
11738
11739        if (dumpPackage == null) {
11740            pw.println();
11741            needSep = false;
11742            pw.println("  mStartedUsers:");
11743            for (int i=0; i<mStartedUsers.size(); i++) {
11744                UserStartedState uss = mStartedUsers.valueAt(i);
11745                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11746                        pw.print(": "); uss.dump("", pw);
11747            }
11748            pw.print("  mStartedUserArray: [");
11749            for (int i=0; i<mStartedUserArray.length; i++) {
11750                if (i > 0) pw.print(", ");
11751                pw.print(mStartedUserArray[i]);
11752            }
11753            pw.println("]");
11754            pw.print("  mUserLru: [");
11755            for (int i=0; i<mUserLru.size(); i++) {
11756                if (i > 0) pw.print(", ");
11757                pw.print(mUserLru.get(i));
11758            }
11759            pw.println("]");
11760            if (dumpAll) {
11761                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11762            }
11763            synchronized (mUserProfileGroupIdsSelfLocked) {
11764                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11765                    pw.println("  mUserProfileGroupIds:");
11766                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11767                        pw.print("    User #");
11768                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11769                        pw.print(" -> profile #");
11770                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11771                    }
11772                }
11773            }
11774        }
11775        if (mHomeProcess != null && (dumpPackage == null
11776                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11777            if (needSep) {
11778                pw.println();
11779                needSep = false;
11780            }
11781            pw.println("  mHomeProcess: " + mHomeProcess);
11782        }
11783        if (mPreviousProcess != null && (dumpPackage == null
11784                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11785            if (needSep) {
11786                pw.println();
11787                needSep = false;
11788            }
11789            pw.println("  mPreviousProcess: " + mPreviousProcess);
11790        }
11791        if (dumpAll) {
11792            StringBuilder sb = new StringBuilder(128);
11793            sb.append("  mPreviousProcessVisibleTime: ");
11794            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11795            pw.println(sb);
11796        }
11797        if (mHeavyWeightProcess != null && (dumpPackage == null
11798                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11799            if (needSep) {
11800                pw.println();
11801                needSep = false;
11802            }
11803            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11804        }
11805        if (dumpPackage == null) {
11806            pw.println("  mConfiguration: " + mConfiguration);
11807        }
11808        if (dumpAll) {
11809            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11810            if (mCompatModePackages.getPackages().size() > 0) {
11811                boolean printed = false;
11812                for (Map.Entry<String, Integer> entry
11813                        : mCompatModePackages.getPackages().entrySet()) {
11814                    String pkg = entry.getKey();
11815                    int mode = entry.getValue();
11816                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11817                        continue;
11818                    }
11819                    if (!printed) {
11820                        pw.println("  mScreenCompatPackages:");
11821                        printed = true;
11822                    }
11823                    pw.print("    "); pw.print(pkg); pw.print(": ");
11824                            pw.print(mode); pw.println();
11825                }
11826            }
11827        }
11828        if (dumpPackage == null) {
11829            if (mSleeping || mWentToSleep || mLockScreenShown) {
11830                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11831                        + " mLockScreenShown " + mLockScreenShown);
11832            }
11833            if (mShuttingDown || mRunningVoice) {
11834                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11835            }
11836        }
11837        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11838                || mOrigWaitForDebugger) {
11839            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11840                    || dumpPackage.equals(mOrigDebugApp)) {
11841                if (needSep) {
11842                    pw.println();
11843                    needSep = false;
11844                }
11845                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11846                        + " mDebugTransient=" + mDebugTransient
11847                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11848            }
11849        }
11850        if (mOpenGlTraceApp != null) {
11851            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11852                if (needSep) {
11853                    pw.println();
11854                    needSep = false;
11855                }
11856                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11857            }
11858        }
11859        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11860                || mProfileFd != null) {
11861            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11862                if (needSep) {
11863                    pw.println();
11864                    needSep = false;
11865                }
11866                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11867                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11868                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11869                        + mAutoStopProfiler);
11870            }
11871        }
11872        if (dumpPackage == null) {
11873            if (mAlwaysFinishActivities || mController != null) {
11874                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11875                        + " mController=" + mController);
11876            }
11877            if (dumpAll) {
11878                pw.println("  Total persistent processes: " + numPers);
11879                pw.println("  mProcessesReady=" + mProcessesReady
11880                        + " mSystemReady=" + mSystemReady);
11881                pw.println("  mBooting=" + mBooting
11882                        + " mBooted=" + mBooted
11883                        + " mFactoryTest=" + mFactoryTest);
11884                pw.print("  mLastPowerCheckRealtime=");
11885                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11886                        pw.println("");
11887                pw.print("  mLastPowerCheckUptime=");
11888                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11889                        pw.println("");
11890                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11891                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11892                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11893                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11894                        + " (" + mLruProcesses.size() + " total)"
11895                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11896                        + " mNumServiceProcs=" + mNumServiceProcs
11897                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11898                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11899                        + " mLastMemoryLevel" + mLastMemoryLevel
11900                        + " mLastNumProcesses" + mLastNumProcesses);
11901                long now = SystemClock.uptimeMillis();
11902                pw.print("  mLastIdleTime=");
11903                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11904                        pw.print(" mLowRamSinceLastIdle=");
11905                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11906                        pw.println();
11907            }
11908        }
11909
11910        if (!printedAnything) {
11911            pw.println("  (nothing)");
11912        }
11913    }
11914
11915    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11916            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11917        if (mProcessesToGc.size() > 0) {
11918            boolean printed = false;
11919            long now = SystemClock.uptimeMillis();
11920            for (int i=0; i<mProcessesToGc.size(); i++) {
11921                ProcessRecord proc = mProcessesToGc.get(i);
11922                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11923                    continue;
11924                }
11925                if (!printed) {
11926                    if (needSep) pw.println();
11927                    needSep = true;
11928                    pw.println("  Processes that are waiting to GC:");
11929                    printed = true;
11930                }
11931                pw.print("    Process "); pw.println(proc);
11932                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11933                        pw.print(", last gced=");
11934                        pw.print(now-proc.lastRequestedGc);
11935                        pw.print(" ms ago, last lowMem=");
11936                        pw.print(now-proc.lastLowMemory);
11937                        pw.println(" ms ago");
11938
11939            }
11940        }
11941        return needSep;
11942    }
11943
11944    void printOomLevel(PrintWriter pw, String name, int adj) {
11945        pw.print("    ");
11946        if (adj >= 0) {
11947            pw.print(' ');
11948            if (adj < 10) pw.print(' ');
11949        } else {
11950            if (adj > -10) pw.print(' ');
11951        }
11952        pw.print(adj);
11953        pw.print(": ");
11954        pw.print(name);
11955        pw.print(" (");
11956        pw.print(mProcessList.getMemLevel(adj)/1024);
11957        pw.println(" kB)");
11958    }
11959
11960    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11961            int opti, boolean dumpAll) {
11962        boolean needSep = false;
11963
11964        if (mLruProcesses.size() > 0) {
11965            if (needSep) pw.println();
11966            needSep = true;
11967            pw.println("  OOM levels:");
11968            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11969            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11970            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11971            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11972            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11973            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11974            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11975            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11976            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11977            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11978            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11979            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11980            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11981
11982            if (needSep) pw.println();
11983            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11984                    pw.print(" total, non-act at ");
11985                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11986                    pw.print(", non-svc at ");
11987                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11988                    pw.println("):");
11989            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11990            needSep = true;
11991        }
11992
11993        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11994
11995        pw.println();
11996        pw.println("  mHomeProcess: " + mHomeProcess);
11997        pw.println("  mPreviousProcess: " + mPreviousProcess);
11998        if (mHeavyWeightProcess != null) {
11999            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12000        }
12001
12002        return true;
12003    }
12004
12005    /**
12006     * There are three ways to call this:
12007     *  - no provider specified: dump all the providers
12008     *  - a flattened component name that matched an existing provider was specified as the
12009     *    first arg: dump that one provider
12010     *  - the first arg isn't the flattened component name of an existing provider:
12011     *    dump all providers whose component contains the first arg as a substring
12012     */
12013    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12014            int opti, boolean dumpAll) {
12015        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12016    }
12017
12018    static class ItemMatcher {
12019        ArrayList<ComponentName> components;
12020        ArrayList<String> strings;
12021        ArrayList<Integer> objects;
12022        boolean all;
12023
12024        ItemMatcher() {
12025            all = true;
12026        }
12027
12028        void build(String name) {
12029            ComponentName componentName = ComponentName.unflattenFromString(name);
12030            if (componentName != null) {
12031                if (components == null) {
12032                    components = new ArrayList<ComponentName>();
12033                }
12034                components.add(componentName);
12035                all = false;
12036            } else {
12037                int objectId = 0;
12038                // Not a '/' separated full component name; maybe an object ID?
12039                try {
12040                    objectId = Integer.parseInt(name, 16);
12041                    if (objects == null) {
12042                        objects = new ArrayList<Integer>();
12043                    }
12044                    objects.add(objectId);
12045                    all = false;
12046                } catch (RuntimeException e) {
12047                    // Not an integer; just do string match.
12048                    if (strings == null) {
12049                        strings = new ArrayList<String>();
12050                    }
12051                    strings.add(name);
12052                    all = false;
12053                }
12054            }
12055        }
12056
12057        int build(String[] args, int opti) {
12058            for (; opti<args.length; opti++) {
12059                String name = args[opti];
12060                if ("--".equals(name)) {
12061                    return opti+1;
12062                }
12063                build(name);
12064            }
12065            return opti;
12066        }
12067
12068        boolean match(Object object, ComponentName comp) {
12069            if (all) {
12070                return true;
12071            }
12072            if (components != null) {
12073                for (int i=0; i<components.size(); i++) {
12074                    if (components.get(i).equals(comp)) {
12075                        return true;
12076                    }
12077                }
12078            }
12079            if (objects != null) {
12080                for (int i=0; i<objects.size(); i++) {
12081                    if (System.identityHashCode(object) == objects.get(i)) {
12082                        return true;
12083                    }
12084                }
12085            }
12086            if (strings != null) {
12087                String flat = comp.flattenToString();
12088                for (int i=0; i<strings.size(); i++) {
12089                    if (flat.contains(strings.get(i))) {
12090                        return true;
12091                    }
12092                }
12093            }
12094            return false;
12095        }
12096    }
12097
12098    /**
12099     * There are three things that cmd can be:
12100     *  - a flattened component name that matches an existing activity
12101     *  - the cmd arg isn't the flattened component name of an existing activity:
12102     *    dump all activity whose component contains the cmd as a substring
12103     *  - A hex number of the ActivityRecord object instance.
12104     */
12105    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12106            int opti, boolean dumpAll) {
12107        ArrayList<ActivityRecord> activities;
12108
12109        synchronized (this) {
12110            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12111        }
12112
12113        if (activities.size() <= 0) {
12114            return false;
12115        }
12116
12117        String[] newArgs = new String[args.length - opti];
12118        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12119
12120        TaskRecord lastTask = null;
12121        boolean needSep = false;
12122        for (int i=activities.size()-1; i>=0; i--) {
12123            ActivityRecord r = activities.get(i);
12124            if (needSep) {
12125                pw.println();
12126            }
12127            needSep = true;
12128            synchronized (this) {
12129                if (lastTask != r.task) {
12130                    lastTask = r.task;
12131                    pw.print("TASK "); pw.print(lastTask.affinity);
12132                            pw.print(" id="); pw.println(lastTask.taskId);
12133                    if (dumpAll) {
12134                        lastTask.dump(pw, "  ");
12135                    }
12136                }
12137            }
12138            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12139        }
12140        return true;
12141    }
12142
12143    /**
12144     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12145     * there is a thread associated with the activity.
12146     */
12147    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12148            final ActivityRecord r, String[] args, boolean dumpAll) {
12149        String innerPrefix = prefix + "  ";
12150        synchronized (this) {
12151            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12152                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12153                    pw.print(" pid=");
12154                    if (r.app != null) pw.println(r.app.pid);
12155                    else pw.println("(not running)");
12156            if (dumpAll) {
12157                r.dump(pw, innerPrefix);
12158            }
12159        }
12160        if (r.app != null && r.app.thread != null) {
12161            // flush anything that is already in the PrintWriter since the thread is going
12162            // to write to the file descriptor directly
12163            pw.flush();
12164            try {
12165                TransferPipe tp = new TransferPipe();
12166                try {
12167                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12168                            r.appToken, innerPrefix, args);
12169                    tp.go(fd);
12170                } finally {
12171                    tp.kill();
12172                }
12173            } catch (IOException e) {
12174                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12175            } catch (RemoteException e) {
12176                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12177            }
12178        }
12179    }
12180
12181    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12182            int opti, boolean dumpAll, String dumpPackage) {
12183        boolean needSep = false;
12184        boolean onlyHistory = false;
12185        boolean printedAnything = false;
12186
12187        if ("history".equals(dumpPackage)) {
12188            if (opti < args.length && "-s".equals(args[opti])) {
12189                dumpAll = false;
12190            }
12191            onlyHistory = true;
12192            dumpPackage = null;
12193        }
12194
12195        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12196        if (!onlyHistory && dumpAll) {
12197            if (mRegisteredReceivers.size() > 0) {
12198                boolean printed = false;
12199                Iterator it = mRegisteredReceivers.values().iterator();
12200                while (it.hasNext()) {
12201                    ReceiverList r = (ReceiverList)it.next();
12202                    if (dumpPackage != null && (r.app == null ||
12203                            !dumpPackage.equals(r.app.info.packageName))) {
12204                        continue;
12205                    }
12206                    if (!printed) {
12207                        pw.println("  Registered Receivers:");
12208                        needSep = true;
12209                        printed = true;
12210                        printedAnything = true;
12211                    }
12212                    pw.print("  * "); pw.println(r);
12213                    r.dump(pw, "    ");
12214                }
12215            }
12216
12217            if (mReceiverResolver.dump(pw, needSep ?
12218                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12219                    "    ", dumpPackage, false)) {
12220                needSep = true;
12221                printedAnything = true;
12222            }
12223        }
12224
12225        for (BroadcastQueue q : mBroadcastQueues) {
12226            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12227            printedAnything |= needSep;
12228        }
12229
12230        needSep = true;
12231
12232        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12233            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12234                if (needSep) {
12235                    pw.println();
12236                }
12237                needSep = true;
12238                printedAnything = true;
12239                pw.print("  Sticky broadcasts for user ");
12240                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12241                StringBuilder sb = new StringBuilder(128);
12242                for (Map.Entry<String, ArrayList<Intent>> ent
12243                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12244                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12245                    if (dumpAll) {
12246                        pw.println(":");
12247                        ArrayList<Intent> intents = ent.getValue();
12248                        final int N = intents.size();
12249                        for (int i=0; i<N; i++) {
12250                            sb.setLength(0);
12251                            sb.append("    Intent: ");
12252                            intents.get(i).toShortString(sb, false, true, false, false);
12253                            pw.println(sb.toString());
12254                            Bundle bundle = intents.get(i).getExtras();
12255                            if (bundle != null) {
12256                                pw.print("      ");
12257                                pw.println(bundle.toString());
12258                            }
12259                        }
12260                    } else {
12261                        pw.println("");
12262                    }
12263                }
12264            }
12265        }
12266
12267        if (!onlyHistory && dumpAll) {
12268            pw.println();
12269            for (BroadcastQueue queue : mBroadcastQueues) {
12270                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12271                        + queue.mBroadcastsScheduled);
12272            }
12273            pw.println("  mHandler:");
12274            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12275            needSep = true;
12276            printedAnything = true;
12277        }
12278
12279        if (!printedAnything) {
12280            pw.println("  (nothing)");
12281        }
12282    }
12283
12284    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12285            int opti, boolean dumpAll, String dumpPackage) {
12286        boolean needSep;
12287        boolean printedAnything = false;
12288
12289        ItemMatcher matcher = new ItemMatcher();
12290        matcher.build(args, opti);
12291
12292        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12293
12294        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12295        printedAnything |= needSep;
12296
12297        if (mLaunchingProviders.size() > 0) {
12298            boolean printed = false;
12299            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12300                ContentProviderRecord r = mLaunchingProviders.get(i);
12301                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12302                    continue;
12303                }
12304                if (!printed) {
12305                    if (needSep) pw.println();
12306                    needSep = true;
12307                    pw.println("  Launching content providers:");
12308                    printed = true;
12309                    printedAnything = true;
12310                }
12311                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12312                        pw.println(r);
12313            }
12314        }
12315
12316        if (mGrantedUriPermissions.size() > 0) {
12317            boolean printed = false;
12318            int dumpUid = -2;
12319            if (dumpPackage != null) {
12320                try {
12321                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12322                } catch (NameNotFoundException e) {
12323                    dumpUid = -1;
12324                }
12325            }
12326            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12327                int uid = mGrantedUriPermissions.keyAt(i);
12328                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12329                    continue;
12330                }
12331                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12332                if (!printed) {
12333                    if (needSep) pw.println();
12334                    needSep = true;
12335                    pw.println("  Granted Uri Permissions:");
12336                    printed = true;
12337                    printedAnything = true;
12338                }
12339                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12340                for (UriPermission perm : perms.values()) {
12341                    pw.print("    "); pw.println(perm);
12342                    if (dumpAll) {
12343                        perm.dump(pw, "      ");
12344                    }
12345                }
12346            }
12347        }
12348
12349        if (!printedAnything) {
12350            pw.println("  (nothing)");
12351        }
12352    }
12353
12354    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12355            int opti, boolean dumpAll, String dumpPackage) {
12356        boolean printed = false;
12357
12358        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12359
12360        if (mIntentSenderRecords.size() > 0) {
12361            Iterator<WeakReference<PendingIntentRecord>> it
12362                    = mIntentSenderRecords.values().iterator();
12363            while (it.hasNext()) {
12364                WeakReference<PendingIntentRecord> ref = it.next();
12365                PendingIntentRecord rec = ref != null ? ref.get(): null;
12366                if (dumpPackage != null && (rec == null
12367                        || !dumpPackage.equals(rec.key.packageName))) {
12368                    continue;
12369                }
12370                printed = true;
12371                if (rec != null) {
12372                    pw.print("  * "); pw.println(rec);
12373                    if (dumpAll) {
12374                        rec.dump(pw, "    ");
12375                    }
12376                } else {
12377                    pw.print("  * "); pw.println(ref);
12378                }
12379            }
12380        }
12381
12382        if (!printed) {
12383            pw.println("  (nothing)");
12384        }
12385    }
12386
12387    private static final int dumpProcessList(PrintWriter pw,
12388            ActivityManagerService service, List list,
12389            String prefix, String normalLabel, String persistentLabel,
12390            String dumpPackage) {
12391        int numPers = 0;
12392        final int N = list.size()-1;
12393        for (int i=N; i>=0; i--) {
12394            ProcessRecord r = (ProcessRecord)list.get(i);
12395            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12396                continue;
12397            }
12398            pw.println(String.format("%s%s #%2d: %s",
12399                    prefix, (r.persistent ? persistentLabel : normalLabel),
12400                    i, r.toString()));
12401            if (r.persistent) {
12402                numPers++;
12403            }
12404        }
12405        return numPers;
12406    }
12407
12408    private static final boolean dumpProcessOomList(PrintWriter pw,
12409            ActivityManagerService service, List<ProcessRecord> origList,
12410            String prefix, String normalLabel, String persistentLabel,
12411            boolean inclDetails, String dumpPackage) {
12412
12413        ArrayList<Pair<ProcessRecord, Integer>> list
12414                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12415        for (int i=0; i<origList.size(); i++) {
12416            ProcessRecord r = origList.get(i);
12417            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12418                continue;
12419            }
12420            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12421        }
12422
12423        if (list.size() <= 0) {
12424            return false;
12425        }
12426
12427        Comparator<Pair<ProcessRecord, Integer>> comparator
12428                = new Comparator<Pair<ProcessRecord, Integer>>() {
12429            @Override
12430            public int compare(Pair<ProcessRecord, Integer> object1,
12431                    Pair<ProcessRecord, Integer> object2) {
12432                if (object1.first.setAdj != object2.first.setAdj) {
12433                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12434                }
12435                if (object1.second.intValue() != object2.second.intValue()) {
12436                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12437                }
12438                return 0;
12439            }
12440        };
12441
12442        Collections.sort(list, comparator);
12443
12444        final long curRealtime = SystemClock.elapsedRealtime();
12445        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12446        final long curUptime = SystemClock.uptimeMillis();
12447        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12448
12449        for (int i=list.size()-1; i>=0; i--) {
12450            ProcessRecord r = list.get(i).first;
12451            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12452            char schedGroup;
12453            switch (r.setSchedGroup) {
12454                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12455                    schedGroup = 'B';
12456                    break;
12457                case Process.THREAD_GROUP_DEFAULT:
12458                    schedGroup = 'F';
12459                    break;
12460                default:
12461                    schedGroup = '?';
12462                    break;
12463            }
12464            char foreground;
12465            if (r.foregroundActivities) {
12466                foreground = 'A';
12467            } else if (r.foregroundServices) {
12468                foreground = 'S';
12469            } else {
12470                foreground = ' ';
12471            }
12472            String procState = ProcessList.makeProcStateString(r.curProcState);
12473            pw.print(prefix);
12474            pw.print(r.persistent ? persistentLabel : normalLabel);
12475            pw.print(" #");
12476            int num = (origList.size()-1)-list.get(i).second;
12477            if (num < 10) pw.print(' ');
12478            pw.print(num);
12479            pw.print(": ");
12480            pw.print(oomAdj);
12481            pw.print(' ');
12482            pw.print(schedGroup);
12483            pw.print('/');
12484            pw.print(foreground);
12485            pw.print('/');
12486            pw.print(procState);
12487            pw.print(" trm:");
12488            if (r.trimMemoryLevel < 10) pw.print(' ');
12489            pw.print(r.trimMemoryLevel);
12490            pw.print(' ');
12491            pw.print(r.toShortString());
12492            pw.print(" (");
12493            pw.print(r.adjType);
12494            pw.println(')');
12495            if (r.adjSource != null || r.adjTarget != null) {
12496                pw.print(prefix);
12497                pw.print("    ");
12498                if (r.adjTarget instanceof ComponentName) {
12499                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12500                } else if (r.adjTarget != null) {
12501                    pw.print(r.adjTarget.toString());
12502                } else {
12503                    pw.print("{null}");
12504                }
12505                pw.print("<=");
12506                if (r.adjSource instanceof ProcessRecord) {
12507                    pw.print("Proc{");
12508                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12509                    pw.println("}");
12510                } else if (r.adjSource != null) {
12511                    pw.println(r.adjSource.toString());
12512                } else {
12513                    pw.println("{null}");
12514                }
12515            }
12516            if (inclDetails) {
12517                pw.print(prefix);
12518                pw.print("    ");
12519                pw.print("oom: max="); pw.print(r.maxAdj);
12520                pw.print(" curRaw="); pw.print(r.curRawAdj);
12521                pw.print(" setRaw="); pw.print(r.setRawAdj);
12522                pw.print(" cur="); pw.print(r.curAdj);
12523                pw.print(" set="); pw.println(r.setAdj);
12524                pw.print(prefix);
12525                pw.print("    ");
12526                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12527                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12528                pw.print(" lastPss="); pw.print(r.lastPss);
12529                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12530                pw.print(prefix);
12531                pw.print("    ");
12532                pw.print("cached="); pw.print(r.cached);
12533                pw.print(" empty="); pw.print(r.empty);
12534                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12535
12536                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12537                    if (r.lastWakeTime != 0) {
12538                        long wtime;
12539                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12540                        synchronized (stats) {
12541                            wtime = stats.getProcessWakeTime(r.info.uid,
12542                                    r.pid, curRealtime);
12543                        }
12544                        long timeUsed = wtime - r.lastWakeTime;
12545                        pw.print(prefix);
12546                        pw.print("    ");
12547                        pw.print("keep awake over ");
12548                        TimeUtils.formatDuration(realtimeSince, pw);
12549                        pw.print(" used ");
12550                        TimeUtils.formatDuration(timeUsed, pw);
12551                        pw.print(" (");
12552                        pw.print((timeUsed*100)/realtimeSince);
12553                        pw.println("%)");
12554                    }
12555                    if (r.lastCpuTime != 0) {
12556                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12557                        pw.print(prefix);
12558                        pw.print("    ");
12559                        pw.print("run cpu over ");
12560                        TimeUtils.formatDuration(uptimeSince, pw);
12561                        pw.print(" used ");
12562                        TimeUtils.formatDuration(timeUsed, pw);
12563                        pw.print(" (");
12564                        pw.print((timeUsed*100)/uptimeSince);
12565                        pw.println("%)");
12566                    }
12567                }
12568            }
12569        }
12570        return true;
12571    }
12572
12573    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12574        ArrayList<ProcessRecord> procs;
12575        synchronized (this) {
12576            if (args != null && args.length > start
12577                    && args[start].charAt(0) != '-') {
12578                procs = new ArrayList<ProcessRecord>();
12579                int pid = -1;
12580                try {
12581                    pid = Integer.parseInt(args[start]);
12582                } catch (NumberFormatException e) {
12583                }
12584                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12585                    ProcessRecord proc = mLruProcesses.get(i);
12586                    if (proc.pid == pid) {
12587                        procs.add(proc);
12588                    } else if (proc.processName.equals(args[start])) {
12589                        procs.add(proc);
12590                    }
12591                }
12592                if (procs.size() <= 0) {
12593                    return null;
12594                }
12595            } else {
12596                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12597            }
12598        }
12599        return procs;
12600    }
12601
12602    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12603            PrintWriter pw, String[] args) {
12604        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12605        if (procs == null) {
12606            pw.println("No process found for: " + args[0]);
12607            return;
12608        }
12609
12610        long uptime = SystemClock.uptimeMillis();
12611        long realtime = SystemClock.elapsedRealtime();
12612        pw.println("Applications Graphics Acceleration Info:");
12613        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12614
12615        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12616            ProcessRecord r = procs.get(i);
12617            if (r.thread != null) {
12618                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12619                pw.flush();
12620                try {
12621                    TransferPipe tp = new TransferPipe();
12622                    try {
12623                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12624                        tp.go(fd);
12625                    } finally {
12626                        tp.kill();
12627                    }
12628                } catch (IOException e) {
12629                    pw.println("Failure while dumping the app: " + r);
12630                    pw.flush();
12631                } catch (RemoteException e) {
12632                    pw.println("Got a RemoteException while dumping the app " + r);
12633                    pw.flush();
12634                }
12635            }
12636        }
12637    }
12638
12639    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12640        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12641        if (procs == null) {
12642            pw.println("No process found for: " + args[0]);
12643            return;
12644        }
12645
12646        pw.println("Applications Database Info:");
12647
12648        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12649            ProcessRecord r = procs.get(i);
12650            if (r.thread != null) {
12651                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12652                pw.flush();
12653                try {
12654                    TransferPipe tp = new TransferPipe();
12655                    try {
12656                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12657                        tp.go(fd);
12658                    } finally {
12659                        tp.kill();
12660                    }
12661                } catch (IOException e) {
12662                    pw.println("Failure while dumping the app: " + r);
12663                    pw.flush();
12664                } catch (RemoteException e) {
12665                    pw.println("Got a RemoteException while dumping the app " + r);
12666                    pw.flush();
12667                }
12668            }
12669        }
12670    }
12671
12672    final static class MemItem {
12673        final boolean isProc;
12674        final String label;
12675        final String shortLabel;
12676        final long pss;
12677        final int id;
12678        final boolean hasActivities;
12679        ArrayList<MemItem> subitems;
12680
12681        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12682                boolean _hasActivities) {
12683            isProc = true;
12684            label = _label;
12685            shortLabel = _shortLabel;
12686            pss = _pss;
12687            id = _id;
12688            hasActivities = _hasActivities;
12689        }
12690
12691        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12692            isProc = false;
12693            label = _label;
12694            shortLabel = _shortLabel;
12695            pss = _pss;
12696            id = _id;
12697            hasActivities = false;
12698        }
12699    }
12700
12701    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12702            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12703        if (sort && !isCompact) {
12704            Collections.sort(items, new Comparator<MemItem>() {
12705                @Override
12706                public int compare(MemItem lhs, MemItem rhs) {
12707                    if (lhs.pss < rhs.pss) {
12708                        return 1;
12709                    } else if (lhs.pss > rhs.pss) {
12710                        return -1;
12711                    }
12712                    return 0;
12713                }
12714            });
12715        }
12716
12717        for (int i=0; i<items.size(); i++) {
12718            MemItem mi = items.get(i);
12719            if (!isCompact) {
12720                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12721            } else if (mi.isProc) {
12722                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12723                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12724                pw.println(mi.hasActivities ? ",a" : ",e");
12725            } else {
12726                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12727                pw.println(mi.pss);
12728            }
12729            if (mi.subitems != null) {
12730                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12731                        true, isCompact);
12732            }
12733        }
12734    }
12735
12736    // These are in KB.
12737    static final long[] DUMP_MEM_BUCKETS = new long[] {
12738        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12739        120*1024, 160*1024, 200*1024,
12740        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12741        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12742    };
12743
12744    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12745            boolean stackLike) {
12746        int start = label.lastIndexOf('.');
12747        if (start >= 0) start++;
12748        else start = 0;
12749        int end = label.length();
12750        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12751            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12752                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12753                out.append(bucket);
12754                out.append(stackLike ? "MB." : "MB ");
12755                out.append(label, start, end);
12756                return;
12757            }
12758        }
12759        out.append(memKB/1024);
12760        out.append(stackLike ? "MB." : "MB ");
12761        out.append(label, start, end);
12762    }
12763
12764    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12765            ProcessList.NATIVE_ADJ,
12766            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12767            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12768            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12769            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12770            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12771    };
12772    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12773            "Native",
12774            "System", "Persistent", "Foreground",
12775            "Visible", "Perceptible",
12776            "Heavy Weight", "Backup",
12777            "A Services", "Home",
12778            "Previous", "B Services", "Cached"
12779    };
12780    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12781            "native",
12782            "sys", "pers", "fore",
12783            "vis", "percept",
12784            "heavy", "backup",
12785            "servicea", "home",
12786            "prev", "serviceb", "cached"
12787    };
12788
12789    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12790            long realtime, boolean isCheckinRequest, boolean isCompact) {
12791        if (isCheckinRequest || isCompact) {
12792            // short checkin version
12793            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12794        } else {
12795            pw.println("Applications Memory Usage (kB):");
12796            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12797        }
12798    }
12799
12800    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12801            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12802        boolean dumpDetails = false;
12803        boolean dumpFullDetails = false;
12804        boolean dumpDalvik = false;
12805        boolean oomOnly = false;
12806        boolean isCompact = false;
12807        boolean localOnly = false;
12808
12809        int opti = 0;
12810        while (opti < args.length) {
12811            String opt = args[opti];
12812            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12813                break;
12814            }
12815            opti++;
12816            if ("-a".equals(opt)) {
12817                dumpDetails = true;
12818                dumpFullDetails = true;
12819                dumpDalvik = true;
12820            } else if ("-d".equals(opt)) {
12821                dumpDalvik = true;
12822            } else if ("-c".equals(opt)) {
12823                isCompact = true;
12824            } else if ("--oom".equals(opt)) {
12825                oomOnly = true;
12826            } else if ("--local".equals(opt)) {
12827                localOnly = true;
12828            } else if ("-h".equals(opt)) {
12829                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12830                pw.println("  -a: include all available information for each process.");
12831                pw.println("  -d: include dalvik details when dumping process details.");
12832                pw.println("  -c: dump in a compact machine-parseable representation.");
12833                pw.println("  --oom: only show processes organized by oom adj.");
12834                pw.println("  --local: only collect details locally, don't call process.");
12835                pw.println("If [process] is specified it can be the name or ");
12836                pw.println("pid of a specific process to dump.");
12837                return;
12838            } else {
12839                pw.println("Unknown argument: " + opt + "; use -h for help");
12840            }
12841        }
12842
12843        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12844        long uptime = SystemClock.uptimeMillis();
12845        long realtime = SystemClock.elapsedRealtime();
12846        final long[] tmpLong = new long[1];
12847
12848        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12849        if (procs == null) {
12850            // No Java processes.  Maybe they want to print a native process.
12851            if (args != null && args.length > opti
12852                    && args[opti].charAt(0) != '-') {
12853                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12854                        = new ArrayList<ProcessCpuTracker.Stats>();
12855                updateCpuStatsNow();
12856                int findPid = -1;
12857                try {
12858                    findPid = Integer.parseInt(args[opti]);
12859                } catch (NumberFormatException e) {
12860                }
12861                synchronized (mProcessCpuThread) {
12862                    final int N = mProcessCpuTracker.countStats();
12863                    for (int i=0; i<N; i++) {
12864                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12865                        if (st.pid == findPid || (st.baseName != null
12866                                && st.baseName.equals(args[opti]))) {
12867                            nativeProcs.add(st);
12868                        }
12869                    }
12870                }
12871                if (nativeProcs.size() > 0) {
12872                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12873                            isCompact);
12874                    Debug.MemoryInfo mi = null;
12875                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12876                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12877                        final int pid = r.pid;
12878                        if (!isCheckinRequest && dumpDetails) {
12879                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12880                        }
12881                        if (mi == null) {
12882                            mi = new Debug.MemoryInfo();
12883                        }
12884                        if (dumpDetails || (!brief && !oomOnly)) {
12885                            Debug.getMemoryInfo(pid, mi);
12886                        } else {
12887                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12888                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12889                        }
12890                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12891                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12892                        if (isCheckinRequest) {
12893                            pw.println();
12894                        }
12895                    }
12896                    return;
12897                }
12898            }
12899            pw.println("No process found for: " + args[opti]);
12900            return;
12901        }
12902
12903        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12904            dumpDetails = true;
12905        }
12906
12907        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12908
12909        String[] innerArgs = new String[args.length-opti];
12910        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12911
12912        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12913        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12914        long nativePss=0, dalvikPss=0, otherPss=0;
12915        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12916
12917        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12918        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12919                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12920
12921        long totalPss = 0;
12922        long cachedPss = 0;
12923
12924        Debug.MemoryInfo mi = null;
12925        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12926            final ProcessRecord r = procs.get(i);
12927            final IApplicationThread thread;
12928            final int pid;
12929            final int oomAdj;
12930            final boolean hasActivities;
12931            synchronized (this) {
12932                thread = r.thread;
12933                pid = r.pid;
12934                oomAdj = r.getSetAdjWithServices();
12935                hasActivities = r.activities.size() > 0;
12936            }
12937            if (thread != null) {
12938                if (!isCheckinRequest && dumpDetails) {
12939                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12940                }
12941                if (mi == null) {
12942                    mi = new Debug.MemoryInfo();
12943                }
12944                if (dumpDetails || (!brief && !oomOnly)) {
12945                    Debug.getMemoryInfo(pid, mi);
12946                } else {
12947                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12948                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12949                }
12950                if (dumpDetails) {
12951                    if (localOnly) {
12952                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12953                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12954                        if (isCheckinRequest) {
12955                            pw.println();
12956                        }
12957                    } else {
12958                        try {
12959                            pw.flush();
12960                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12961                                    dumpDalvik, innerArgs);
12962                        } catch (RemoteException e) {
12963                            if (!isCheckinRequest) {
12964                                pw.println("Got RemoteException!");
12965                                pw.flush();
12966                            }
12967                        }
12968                    }
12969                }
12970
12971                final long myTotalPss = mi.getTotalPss();
12972                final long myTotalUss = mi.getTotalUss();
12973
12974                synchronized (this) {
12975                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12976                        // Record this for posterity if the process has been stable.
12977                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12978                    }
12979                }
12980
12981                if (!isCheckinRequest && mi != null) {
12982                    totalPss += myTotalPss;
12983                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12984                            (hasActivities ? " / activities)" : ")"),
12985                            r.processName, myTotalPss, pid, hasActivities);
12986                    procMems.add(pssItem);
12987                    procMemsMap.put(pid, pssItem);
12988
12989                    nativePss += mi.nativePss;
12990                    dalvikPss += mi.dalvikPss;
12991                    otherPss += mi.otherPss;
12992                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12993                        long mem = mi.getOtherPss(j);
12994                        miscPss[j] += mem;
12995                        otherPss -= mem;
12996                    }
12997
12998                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12999                        cachedPss += myTotalPss;
13000                    }
13001
13002                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13003                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13004                                || oomIndex == (oomPss.length-1)) {
13005                            oomPss[oomIndex] += myTotalPss;
13006                            if (oomProcs[oomIndex] == null) {
13007                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13008                            }
13009                            oomProcs[oomIndex].add(pssItem);
13010                            break;
13011                        }
13012                    }
13013                }
13014            }
13015        }
13016
13017        long nativeProcTotalPss = 0;
13018
13019        if (!isCheckinRequest && procs.size() > 1) {
13020            // If we are showing aggregations, also look for native processes to
13021            // include so that our aggregations are more accurate.
13022            updateCpuStatsNow();
13023            synchronized (mProcessCpuThread) {
13024                final int N = mProcessCpuTracker.countStats();
13025                for (int i=0; i<N; i++) {
13026                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13027                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13028                        if (mi == null) {
13029                            mi = new Debug.MemoryInfo();
13030                        }
13031                        if (!brief && !oomOnly) {
13032                            Debug.getMemoryInfo(st.pid, mi);
13033                        } else {
13034                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13035                            mi.nativePrivateDirty = (int)tmpLong[0];
13036                        }
13037
13038                        final long myTotalPss = mi.getTotalPss();
13039                        totalPss += myTotalPss;
13040                        nativeProcTotalPss += myTotalPss;
13041
13042                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13043                                st.name, myTotalPss, st.pid, false);
13044                        procMems.add(pssItem);
13045
13046                        nativePss += mi.nativePss;
13047                        dalvikPss += mi.dalvikPss;
13048                        otherPss += mi.otherPss;
13049                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13050                            long mem = mi.getOtherPss(j);
13051                            miscPss[j] += mem;
13052                            otherPss -= mem;
13053                        }
13054                        oomPss[0] += myTotalPss;
13055                        if (oomProcs[0] == null) {
13056                            oomProcs[0] = new ArrayList<MemItem>();
13057                        }
13058                        oomProcs[0].add(pssItem);
13059                    }
13060                }
13061            }
13062
13063            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13064
13065            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13066            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13067            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13068            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13069                String label = Debug.MemoryInfo.getOtherLabel(j);
13070                catMems.add(new MemItem(label, label, miscPss[j], j));
13071            }
13072
13073            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13074            for (int j=0; j<oomPss.length; j++) {
13075                if (oomPss[j] != 0) {
13076                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13077                            : DUMP_MEM_OOM_LABEL[j];
13078                    MemItem item = new MemItem(label, label, oomPss[j],
13079                            DUMP_MEM_OOM_ADJ[j]);
13080                    item.subitems = oomProcs[j];
13081                    oomMems.add(item);
13082                }
13083            }
13084
13085            if (!brief && !oomOnly && !isCompact) {
13086                pw.println();
13087                pw.println("Total PSS by process:");
13088                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13089                pw.println();
13090            }
13091            if (!isCompact) {
13092                pw.println("Total PSS by OOM adjustment:");
13093            }
13094            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13095            if (!brief && !oomOnly) {
13096                PrintWriter out = categoryPw != null ? categoryPw : pw;
13097                if (!isCompact) {
13098                    out.println();
13099                    out.println("Total PSS by category:");
13100                }
13101                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13102            }
13103            if (!isCompact) {
13104                pw.println();
13105            }
13106            MemInfoReader memInfo = new MemInfoReader();
13107            memInfo.readMemInfo();
13108            if (nativeProcTotalPss > 0) {
13109                synchronized (this) {
13110                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13111                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13112                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13113                            nativeProcTotalPss);
13114                }
13115            }
13116            if (!brief) {
13117                if (!isCompact) {
13118                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13119                    pw.print(" kB (status ");
13120                    switch (mLastMemoryLevel) {
13121                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13122                            pw.println("normal)");
13123                            break;
13124                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13125                            pw.println("moderate)");
13126                            break;
13127                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13128                            pw.println("low)");
13129                            break;
13130                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13131                            pw.println("critical)");
13132                            break;
13133                        default:
13134                            pw.print(mLastMemoryLevel);
13135                            pw.println(")");
13136                            break;
13137                    }
13138                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13139                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13140                            pw.print(cachedPss); pw.print(" cached pss + ");
13141                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13142                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13143                } else {
13144                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13145                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13146                            + memInfo.getFreeSizeKb()); pw.print(",");
13147                    pw.println(totalPss - cachedPss);
13148                }
13149            }
13150            if (!isCompact) {
13151                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13152                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13153                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13154                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13155                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13156                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13157                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13158                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13159                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13160                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13161                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13162            }
13163            if (!brief) {
13164                if (memInfo.getZramTotalSizeKb() != 0) {
13165                    if (!isCompact) {
13166                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13167                                pw.print(" kB physical used for ");
13168                                pw.print(memInfo.getSwapTotalSizeKb()
13169                                        - memInfo.getSwapFreeSizeKb());
13170                                pw.print(" kB in swap (");
13171                                pw.print(memInfo.getSwapTotalSizeKb());
13172                                pw.println(" kB total swap)");
13173                    } else {
13174                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13175                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13176                                pw.println(memInfo.getSwapFreeSizeKb());
13177                    }
13178                }
13179                final int[] SINGLE_LONG_FORMAT = new int[] {
13180                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13181                };
13182                long[] longOut = new long[1];
13183                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13184                        SINGLE_LONG_FORMAT, null, longOut, null);
13185                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13186                longOut[0] = 0;
13187                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13188                        SINGLE_LONG_FORMAT, null, longOut, null);
13189                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13190                longOut[0] = 0;
13191                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13192                        SINGLE_LONG_FORMAT, null, longOut, null);
13193                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13194                longOut[0] = 0;
13195                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13196                        SINGLE_LONG_FORMAT, null, longOut, null);
13197                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13198                if (!isCompact) {
13199                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13200                        pw.print("      KSM: "); pw.print(sharing);
13201                                pw.print(" kB saved from shared ");
13202                                pw.print(shared); pw.println(" kB");
13203                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13204                                pw.print(voltile); pw.println(" kB volatile");
13205                    }
13206                    pw.print("   Tuning: ");
13207                    pw.print(ActivityManager.staticGetMemoryClass());
13208                    pw.print(" (large ");
13209                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13210                    pw.print("), oom ");
13211                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13212                    pw.print(" kB");
13213                    pw.print(", restore limit ");
13214                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13215                    pw.print(" kB");
13216                    if (ActivityManager.isLowRamDeviceStatic()) {
13217                        pw.print(" (low-ram)");
13218                    }
13219                    if (ActivityManager.isHighEndGfx()) {
13220                        pw.print(" (high-end-gfx)");
13221                    }
13222                    pw.println();
13223                } else {
13224                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13225                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13226                    pw.println(voltile);
13227                    pw.print("tuning,");
13228                    pw.print(ActivityManager.staticGetMemoryClass());
13229                    pw.print(',');
13230                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13231                    pw.print(',');
13232                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13233                    if (ActivityManager.isLowRamDeviceStatic()) {
13234                        pw.print(",low-ram");
13235                    }
13236                    if (ActivityManager.isHighEndGfx()) {
13237                        pw.print(",high-end-gfx");
13238                    }
13239                    pw.println();
13240                }
13241            }
13242        }
13243    }
13244
13245    /**
13246     * Searches array of arguments for the specified string
13247     * @param args array of argument strings
13248     * @param value value to search for
13249     * @return true if the value is contained in the array
13250     */
13251    private static boolean scanArgs(String[] args, String value) {
13252        if (args != null) {
13253            for (String arg : args) {
13254                if (value.equals(arg)) {
13255                    return true;
13256                }
13257            }
13258        }
13259        return false;
13260    }
13261
13262    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13263            ContentProviderRecord cpr, boolean always) {
13264        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13265
13266        if (!inLaunching || always) {
13267            synchronized (cpr) {
13268                cpr.launchingApp = null;
13269                cpr.notifyAll();
13270            }
13271            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13272            String names[] = cpr.info.authority.split(";");
13273            for (int j = 0; j < names.length; j++) {
13274                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13275            }
13276        }
13277
13278        for (int i=0; i<cpr.connections.size(); i++) {
13279            ContentProviderConnection conn = cpr.connections.get(i);
13280            if (conn.waiting) {
13281                // If this connection is waiting for the provider, then we don't
13282                // need to mess with its process unless we are always removing
13283                // or for some reason the provider is not currently launching.
13284                if (inLaunching && !always) {
13285                    continue;
13286                }
13287            }
13288            ProcessRecord capp = conn.client;
13289            conn.dead = true;
13290            if (conn.stableCount > 0) {
13291                if (!capp.persistent && capp.thread != null
13292                        && capp.pid != 0
13293                        && capp.pid != MY_PID) {
13294                    killUnneededProcessLocked(capp, "depends on provider "
13295                            + cpr.name.flattenToShortString()
13296                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13297                }
13298            } else if (capp.thread != null && conn.provider.provider != null) {
13299                try {
13300                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13301                } catch (RemoteException e) {
13302                }
13303                // In the protocol here, we don't expect the client to correctly
13304                // clean up this connection, we'll just remove it.
13305                cpr.connections.remove(i);
13306                conn.client.conProviders.remove(conn);
13307            }
13308        }
13309
13310        if (inLaunching && always) {
13311            mLaunchingProviders.remove(cpr);
13312        }
13313        return inLaunching;
13314    }
13315
13316    /**
13317     * Main code for cleaning up a process when it has gone away.  This is
13318     * called both as a result of the process dying, or directly when stopping
13319     * a process when running in single process mode.
13320     */
13321    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13322            boolean restarting, boolean allowRestart, int index) {
13323        if (index >= 0) {
13324            removeLruProcessLocked(app);
13325            ProcessList.remove(app.pid);
13326        }
13327
13328        mProcessesToGc.remove(app);
13329        mPendingPssProcesses.remove(app);
13330
13331        // Dismiss any open dialogs.
13332        if (app.crashDialog != null && !app.forceCrashReport) {
13333            app.crashDialog.dismiss();
13334            app.crashDialog = null;
13335        }
13336        if (app.anrDialog != null) {
13337            app.anrDialog.dismiss();
13338            app.anrDialog = null;
13339        }
13340        if (app.waitDialog != null) {
13341            app.waitDialog.dismiss();
13342            app.waitDialog = null;
13343        }
13344
13345        app.crashing = false;
13346        app.notResponding = false;
13347
13348        app.resetPackageList(mProcessStats);
13349        app.unlinkDeathRecipient();
13350        app.makeInactive(mProcessStats);
13351        app.waitingToKill = null;
13352        app.forcingToForeground = null;
13353        updateProcessForegroundLocked(app, false, false);
13354        app.foregroundActivities = false;
13355        app.hasShownUi = false;
13356        app.treatLikeActivity = false;
13357        app.hasAboveClient = false;
13358        app.hasClientActivities = false;
13359
13360        mServices.killServicesLocked(app, allowRestart);
13361
13362        boolean restart = false;
13363
13364        // Remove published content providers.
13365        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13366            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13367            final boolean always = app.bad || !allowRestart;
13368            if (removeDyingProviderLocked(app, cpr, always) || always) {
13369                // We left the provider in the launching list, need to
13370                // restart it.
13371                restart = true;
13372            }
13373
13374            cpr.provider = null;
13375            cpr.proc = null;
13376        }
13377        app.pubProviders.clear();
13378
13379        // Take care of any launching providers waiting for this process.
13380        if (checkAppInLaunchingProvidersLocked(app, false)) {
13381            restart = true;
13382        }
13383
13384        // Unregister from connected content providers.
13385        if (!app.conProviders.isEmpty()) {
13386            for (int i=0; i<app.conProviders.size(); i++) {
13387                ContentProviderConnection conn = app.conProviders.get(i);
13388                conn.provider.connections.remove(conn);
13389            }
13390            app.conProviders.clear();
13391        }
13392
13393        // At this point there may be remaining entries in mLaunchingProviders
13394        // where we were the only one waiting, so they are no longer of use.
13395        // Look for these and clean up if found.
13396        // XXX Commented out for now.  Trying to figure out a way to reproduce
13397        // the actual situation to identify what is actually going on.
13398        if (false) {
13399            for (int i=0; i<mLaunchingProviders.size(); i++) {
13400                ContentProviderRecord cpr = (ContentProviderRecord)
13401                        mLaunchingProviders.get(i);
13402                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13403                    synchronized (cpr) {
13404                        cpr.launchingApp = null;
13405                        cpr.notifyAll();
13406                    }
13407                }
13408            }
13409        }
13410
13411        skipCurrentReceiverLocked(app);
13412
13413        // Unregister any receivers.
13414        for (int i=app.receivers.size()-1; i>=0; i--) {
13415            removeReceiverLocked(app.receivers.valueAt(i));
13416        }
13417        app.receivers.clear();
13418
13419        // If the app is undergoing backup, tell the backup manager about it
13420        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13421            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13422                    + mBackupTarget.appInfo + " died during backup");
13423            try {
13424                IBackupManager bm = IBackupManager.Stub.asInterface(
13425                        ServiceManager.getService(Context.BACKUP_SERVICE));
13426                bm.agentDisconnected(app.info.packageName);
13427            } catch (RemoteException e) {
13428                // can't happen; backup manager is local
13429            }
13430        }
13431
13432        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13433            ProcessChangeItem item = mPendingProcessChanges.get(i);
13434            if (item.pid == app.pid) {
13435                mPendingProcessChanges.remove(i);
13436                mAvailProcessChanges.add(item);
13437            }
13438        }
13439        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13440
13441        // If the caller is restarting this app, then leave it in its
13442        // current lists and let the caller take care of it.
13443        if (restarting) {
13444            return;
13445        }
13446
13447        if (!app.persistent || app.isolated) {
13448            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13449                    "Removing non-persistent process during cleanup: " + app);
13450            mProcessNames.remove(app.processName, app.uid);
13451            mIsolatedProcesses.remove(app.uid);
13452            if (mHeavyWeightProcess == app) {
13453                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13454                        mHeavyWeightProcess.userId, 0));
13455                mHeavyWeightProcess = null;
13456            }
13457        } else if (!app.removed) {
13458            // This app is persistent, so we need to keep its record around.
13459            // If it is not already on the pending app list, add it there
13460            // and start a new process for it.
13461            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13462                mPersistentStartingProcesses.add(app);
13463                restart = true;
13464            }
13465        }
13466        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13467                "Clean-up removing on hold: " + app);
13468        mProcessesOnHold.remove(app);
13469
13470        if (app == mHomeProcess) {
13471            mHomeProcess = null;
13472        }
13473        if (app == mPreviousProcess) {
13474            mPreviousProcess = null;
13475        }
13476
13477        if (restart && !app.isolated) {
13478            // We have components that still need to be running in the
13479            // process, so re-launch it.
13480            mProcessNames.put(app.processName, app.uid, app);
13481            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13482        } else if (app.pid > 0 && app.pid != MY_PID) {
13483            // Goodbye!
13484            boolean removed;
13485            synchronized (mPidsSelfLocked) {
13486                mPidsSelfLocked.remove(app.pid);
13487                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13488            }
13489            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13490            if (app.isolated) {
13491                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13492            }
13493            app.setPid(0);
13494        }
13495    }
13496
13497    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13498        // Look through the content providers we are waiting to have launched,
13499        // and if any run in this process then either schedule a restart of
13500        // the process or kill the client waiting for it if this process has
13501        // gone bad.
13502        int NL = mLaunchingProviders.size();
13503        boolean restart = false;
13504        for (int i=0; i<NL; i++) {
13505            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13506            if (cpr.launchingApp == app) {
13507                if (!alwaysBad && !app.bad) {
13508                    restart = true;
13509                } else {
13510                    removeDyingProviderLocked(app, cpr, true);
13511                    // cpr should have been removed from mLaunchingProviders
13512                    NL = mLaunchingProviders.size();
13513                    i--;
13514                }
13515            }
13516        }
13517        return restart;
13518    }
13519
13520    // =========================================================
13521    // SERVICES
13522    // =========================================================
13523
13524    @Override
13525    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13526            int flags) {
13527        enforceNotIsolatedCaller("getServices");
13528        synchronized (this) {
13529            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13530        }
13531    }
13532
13533    @Override
13534    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13535        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13536        synchronized (this) {
13537            return mServices.getRunningServiceControlPanelLocked(name);
13538        }
13539    }
13540
13541    @Override
13542    public ComponentName startService(IApplicationThread caller, Intent service,
13543            String resolvedType, int userId) {
13544        enforceNotIsolatedCaller("startService");
13545        // Refuse possible leaked file descriptors
13546        if (service != null && service.hasFileDescriptors() == true) {
13547            throw new IllegalArgumentException("File descriptors passed in Intent");
13548        }
13549
13550        if (DEBUG_SERVICE)
13551            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13552        synchronized(this) {
13553            final int callingPid = Binder.getCallingPid();
13554            final int callingUid = Binder.getCallingUid();
13555            final long origId = Binder.clearCallingIdentity();
13556            ComponentName res = mServices.startServiceLocked(caller, service,
13557                    resolvedType, callingPid, callingUid, userId);
13558            Binder.restoreCallingIdentity(origId);
13559            return res;
13560        }
13561    }
13562
13563    ComponentName startServiceInPackage(int uid,
13564            Intent service, String resolvedType, int userId) {
13565        synchronized(this) {
13566            if (DEBUG_SERVICE)
13567                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13568            final long origId = Binder.clearCallingIdentity();
13569            ComponentName res = mServices.startServiceLocked(null, service,
13570                    resolvedType, -1, uid, userId);
13571            Binder.restoreCallingIdentity(origId);
13572            return res;
13573        }
13574    }
13575
13576    @Override
13577    public int stopService(IApplicationThread caller, Intent service,
13578            String resolvedType, int userId) {
13579        enforceNotIsolatedCaller("stopService");
13580        // Refuse possible leaked file descriptors
13581        if (service != null && service.hasFileDescriptors() == true) {
13582            throw new IllegalArgumentException("File descriptors passed in Intent");
13583        }
13584
13585        synchronized(this) {
13586            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13587        }
13588    }
13589
13590    @Override
13591    public IBinder peekService(Intent service, String resolvedType) {
13592        enforceNotIsolatedCaller("peekService");
13593        // Refuse possible leaked file descriptors
13594        if (service != null && service.hasFileDescriptors() == true) {
13595            throw new IllegalArgumentException("File descriptors passed in Intent");
13596        }
13597        synchronized(this) {
13598            return mServices.peekServiceLocked(service, resolvedType);
13599        }
13600    }
13601
13602    @Override
13603    public boolean stopServiceToken(ComponentName className, IBinder token,
13604            int startId) {
13605        synchronized(this) {
13606            return mServices.stopServiceTokenLocked(className, token, startId);
13607        }
13608    }
13609
13610    @Override
13611    public void setServiceForeground(ComponentName className, IBinder token,
13612            int id, Notification notification, boolean removeNotification) {
13613        synchronized(this) {
13614            mServices.setServiceForegroundLocked(className, token, id, notification,
13615                    removeNotification);
13616        }
13617    }
13618
13619    @Override
13620    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13621            boolean requireFull, String name, String callerPackage) {
13622        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13623                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13624    }
13625
13626    int unsafeConvertIncomingUser(int userId) {
13627        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13628                ? mCurrentUserId : userId;
13629    }
13630
13631    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13632            int allowMode, String name, String callerPackage) {
13633        final int callingUserId = UserHandle.getUserId(callingUid);
13634        if (callingUserId == userId) {
13635            return userId;
13636        }
13637
13638        // Note that we may be accessing mCurrentUserId outside of a lock...
13639        // shouldn't be a big deal, if this is being called outside
13640        // of a locked context there is intrinsically a race with
13641        // the value the caller will receive and someone else changing it.
13642        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13643        // we will switch to the calling user if access to the current user fails.
13644        int targetUserId = unsafeConvertIncomingUser(userId);
13645
13646        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13647            final boolean allow;
13648            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13649                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13650                // If the caller has this permission, they always pass go.  And collect $200.
13651                allow = true;
13652            } else if (allowMode == ALLOW_FULL_ONLY) {
13653                // We require full access, sucks to be you.
13654                allow = false;
13655            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13656                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13657                // If the caller does not have either permission, they are always doomed.
13658                allow = false;
13659            } else if (allowMode == ALLOW_NON_FULL) {
13660                // We are blanket allowing non-full access, you lucky caller!
13661                allow = true;
13662            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13663                // We may or may not allow this depending on whether the two users are
13664                // in the same profile.
13665                synchronized (mUserProfileGroupIdsSelfLocked) {
13666                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13667                            UserInfo.NO_PROFILE_GROUP_ID);
13668                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13669                            UserInfo.NO_PROFILE_GROUP_ID);
13670                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13671                            && callingProfile == targetProfile;
13672                }
13673            } else {
13674                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13675            }
13676            if (!allow) {
13677                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13678                    // In this case, they would like to just execute as their
13679                    // owner user instead of failing.
13680                    targetUserId = callingUserId;
13681                } else {
13682                    StringBuilder builder = new StringBuilder(128);
13683                    builder.append("Permission Denial: ");
13684                    builder.append(name);
13685                    if (callerPackage != null) {
13686                        builder.append(" from ");
13687                        builder.append(callerPackage);
13688                    }
13689                    builder.append(" asks to run as user ");
13690                    builder.append(userId);
13691                    builder.append(" but is calling from user ");
13692                    builder.append(UserHandle.getUserId(callingUid));
13693                    builder.append("; this requires ");
13694                    builder.append(INTERACT_ACROSS_USERS_FULL);
13695                    if (allowMode != ALLOW_FULL_ONLY) {
13696                        builder.append(" or ");
13697                        builder.append(INTERACT_ACROSS_USERS);
13698                    }
13699                    String msg = builder.toString();
13700                    Slog.w(TAG, msg);
13701                    throw new SecurityException(msg);
13702                }
13703            }
13704        }
13705        if (!allowAll && targetUserId < 0) {
13706            throw new IllegalArgumentException(
13707                    "Call does not support special user #" + targetUserId);
13708        }
13709        return targetUserId;
13710    }
13711
13712    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13713            String className, int flags) {
13714        boolean result = false;
13715        // For apps that don't have pre-defined UIDs, check for permission
13716        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13717            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13718                if (ActivityManager.checkUidPermission(
13719                        INTERACT_ACROSS_USERS,
13720                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13721                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13722                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13723                            + " requests FLAG_SINGLE_USER, but app does not hold "
13724                            + INTERACT_ACROSS_USERS;
13725                    Slog.w(TAG, msg);
13726                    throw new SecurityException(msg);
13727                }
13728                // Permission passed
13729                result = true;
13730            }
13731        } else if ("system".equals(componentProcessName)) {
13732            result = true;
13733        } else {
13734            // App with pre-defined UID, check if it's a persistent app
13735            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13736        }
13737        if (DEBUG_MU) {
13738            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13739                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13740        }
13741        return result;
13742    }
13743
13744    /**
13745     * Checks to see if the caller is in the same app as the singleton
13746     * component, or the component is in a special app. It allows special apps
13747     * to export singleton components but prevents exporting singleton
13748     * components for regular apps.
13749     */
13750    boolean isValidSingletonCall(int callingUid, int componentUid) {
13751        int componentAppId = UserHandle.getAppId(componentUid);
13752        return UserHandle.isSameApp(callingUid, componentUid)
13753                || componentAppId == Process.SYSTEM_UID
13754                || componentAppId == Process.PHONE_UID
13755                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13756                        == PackageManager.PERMISSION_GRANTED;
13757    }
13758
13759    public int bindService(IApplicationThread caller, IBinder token,
13760            Intent service, String resolvedType,
13761            IServiceConnection connection, int flags, int userId) {
13762        enforceNotIsolatedCaller("bindService");
13763        // Refuse possible leaked file descriptors
13764        if (service != null && service.hasFileDescriptors() == true) {
13765            throw new IllegalArgumentException("File descriptors passed in Intent");
13766        }
13767
13768        synchronized(this) {
13769            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13770                    connection, flags, userId);
13771        }
13772    }
13773
13774    public boolean unbindService(IServiceConnection connection) {
13775        synchronized (this) {
13776            return mServices.unbindServiceLocked(connection);
13777        }
13778    }
13779
13780    public void publishService(IBinder token, Intent intent, IBinder service) {
13781        // Refuse possible leaked file descriptors
13782        if (intent != null && intent.hasFileDescriptors() == true) {
13783            throw new IllegalArgumentException("File descriptors passed in Intent");
13784        }
13785
13786        synchronized(this) {
13787            if (!(token instanceof ServiceRecord)) {
13788                throw new IllegalArgumentException("Invalid service token");
13789            }
13790            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13791        }
13792    }
13793
13794    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13795        // Refuse possible leaked file descriptors
13796        if (intent != null && intent.hasFileDescriptors() == true) {
13797            throw new IllegalArgumentException("File descriptors passed in Intent");
13798        }
13799
13800        synchronized(this) {
13801            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13802        }
13803    }
13804
13805    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13806        synchronized(this) {
13807            if (!(token instanceof ServiceRecord)) {
13808                throw new IllegalArgumentException("Invalid service token");
13809            }
13810            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13811        }
13812    }
13813
13814    // =========================================================
13815    // BACKUP AND RESTORE
13816    // =========================================================
13817
13818    // Cause the target app to be launched if necessary and its backup agent
13819    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13820    // activity manager to announce its creation.
13821    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13822        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13823        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13824
13825        synchronized(this) {
13826            // !!! TODO: currently no check here that we're already bound
13827            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13828            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13829            synchronized (stats) {
13830                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13831            }
13832
13833            // Backup agent is now in use, its package can't be stopped.
13834            try {
13835                AppGlobals.getPackageManager().setPackageStoppedState(
13836                        app.packageName, false, UserHandle.getUserId(app.uid));
13837            } catch (RemoteException e) {
13838            } catch (IllegalArgumentException e) {
13839                Slog.w(TAG, "Failed trying to unstop package "
13840                        + app.packageName + ": " + e);
13841            }
13842
13843            BackupRecord r = new BackupRecord(ss, app, backupMode);
13844            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13845                    ? new ComponentName(app.packageName, app.backupAgentName)
13846                    : new ComponentName("android", "FullBackupAgent");
13847            // startProcessLocked() returns existing proc's record if it's already running
13848            ProcessRecord proc = startProcessLocked(app.processName, app,
13849                    false, 0, "backup", hostingName, false, false, false);
13850            if (proc == null) {
13851                Slog.e(TAG, "Unable to start backup agent process " + r);
13852                return false;
13853            }
13854
13855            r.app = proc;
13856            mBackupTarget = r;
13857            mBackupAppName = app.packageName;
13858
13859            // Try not to kill the process during backup
13860            updateOomAdjLocked(proc);
13861
13862            // If the process is already attached, schedule the creation of the backup agent now.
13863            // If it is not yet live, this will be done when it attaches to the framework.
13864            if (proc.thread != null) {
13865                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13866                try {
13867                    proc.thread.scheduleCreateBackupAgent(app,
13868                            compatibilityInfoForPackageLocked(app), backupMode);
13869                } catch (RemoteException e) {
13870                    // Will time out on the backup manager side
13871                }
13872            } else {
13873                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13874            }
13875            // Invariants: at this point, the target app process exists and the application
13876            // is either already running or in the process of coming up.  mBackupTarget and
13877            // mBackupAppName describe the app, so that when it binds back to the AM we
13878            // know that it's scheduled for a backup-agent operation.
13879        }
13880
13881        return true;
13882    }
13883
13884    @Override
13885    public void clearPendingBackup() {
13886        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13887        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13888
13889        synchronized (this) {
13890            mBackupTarget = null;
13891            mBackupAppName = null;
13892        }
13893    }
13894
13895    // A backup agent has just come up
13896    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13897        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13898                + " = " + agent);
13899
13900        synchronized(this) {
13901            if (!agentPackageName.equals(mBackupAppName)) {
13902                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13903                return;
13904            }
13905        }
13906
13907        long oldIdent = Binder.clearCallingIdentity();
13908        try {
13909            IBackupManager bm = IBackupManager.Stub.asInterface(
13910                    ServiceManager.getService(Context.BACKUP_SERVICE));
13911            bm.agentConnected(agentPackageName, agent);
13912        } catch (RemoteException e) {
13913            // can't happen; the backup manager service is local
13914        } catch (Exception e) {
13915            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13916            e.printStackTrace();
13917        } finally {
13918            Binder.restoreCallingIdentity(oldIdent);
13919        }
13920    }
13921
13922    // done with this agent
13923    public void unbindBackupAgent(ApplicationInfo appInfo) {
13924        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13925        if (appInfo == null) {
13926            Slog.w(TAG, "unbind backup agent for null app");
13927            return;
13928        }
13929
13930        synchronized(this) {
13931            try {
13932                if (mBackupAppName == null) {
13933                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13934                    return;
13935                }
13936
13937                if (!mBackupAppName.equals(appInfo.packageName)) {
13938                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13939                    return;
13940                }
13941
13942                // Not backing this app up any more; reset its OOM adjustment
13943                final ProcessRecord proc = mBackupTarget.app;
13944                updateOomAdjLocked(proc);
13945
13946                // If the app crashed during backup, 'thread' will be null here
13947                if (proc.thread != null) {
13948                    try {
13949                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13950                                compatibilityInfoForPackageLocked(appInfo));
13951                    } catch (Exception e) {
13952                        Slog.e(TAG, "Exception when unbinding backup agent:");
13953                        e.printStackTrace();
13954                    }
13955                }
13956            } finally {
13957                mBackupTarget = null;
13958                mBackupAppName = null;
13959            }
13960        }
13961    }
13962    // =========================================================
13963    // BROADCASTS
13964    // =========================================================
13965
13966    private final List getStickiesLocked(String action, IntentFilter filter,
13967            List cur, int userId) {
13968        final ContentResolver resolver = mContext.getContentResolver();
13969        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13970        if (stickies == null) {
13971            return cur;
13972        }
13973        final ArrayList<Intent> list = stickies.get(action);
13974        if (list == null) {
13975            return cur;
13976        }
13977        int N = list.size();
13978        for (int i=0; i<N; i++) {
13979            Intent intent = list.get(i);
13980            if (filter.match(resolver, intent, true, TAG) >= 0) {
13981                if (cur == null) {
13982                    cur = new ArrayList<Intent>();
13983                }
13984                cur.add(intent);
13985            }
13986        }
13987        return cur;
13988    }
13989
13990    boolean isPendingBroadcastProcessLocked(int pid) {
13991        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13992                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13993    }
13994
13995    void skipPendingBroadcastLocked(int pid) {
13996            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13997            for (BroadcastQueue queue : mBroadcastQueues) {
13998                queue.skipPendingBroadcastLocked(pid);
13999            }
14000    }
14001
14002    // The app just attached; send any pending broadcasts that it should receive
14003    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14004        boolean didSomething = false;
14005        for (BroadcastQueue queue : mBroadcastQueues) {
14006            didSomething |= queue.sendPendingBroadcastsLocked(app);
14007        }
14008        return didSomething;
14009    }
14010
14011    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14012            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14013        enforceNotIsolatedCaller("registerReceiver");
14014        int callingUid;
14015        int callingPid;
14016        synchronized(this) {
14017            ProcessRecord callerApp = null;
14018            if (caller != null) {
14019                callerApp = getRecordForAppLocked(caller);
14020                if (callerApp == null) {
14021                    throw new SecurityException(
14022                            "Unable to find app for caller " + caller
14023                            + " (pid=" + Binder.getCallingPid()
14024                            + ") when registering receiver " + receiver);
14025                }
14026                if (callerApp.info.uid != Process.SYSTEM_UID &&
14027                        !callerApp.pkgList.containsKey(callerPackage) &&
14028                        !"android".equals(callerPackage)) {
14029                    throw new SecurityException("Given caller package " + callerPackage
14030                            + " is not running in process " + callerApp);
14031                }
14032                callingUid = callerApp.info.uid;
14033                callingPid = callerApp.pid;
14034            } else {
14035                callerPackage = null;
14036                callingUid = Binder.getCallingUid();
14037                callingPid = Binder.getCallingPid();
14038            }
14039
14040            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14041                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14042
14043            List allSticky = null;
14044
14045            // Look for any matching sticky broadcasts...
14046            Iterator actions = filter.actionsIterator();
14047            if (actions != null) {
14048                while (actions.hasNext()) {
14049                    String action = (String)actions.next();
14050                    allSticky = getStickiesLocked(action, filter, allSticky,
14051                            UserHandle.USER_ALL);
14052                    allSticky = getStickiesLocked(action, filter, allSticky,
14053                            UserHandle.getUserId(callingUid));
14054                }
14055            } else {
14056                allSticky = getStickiesLocked(null, filter, allSticky,
14057                        UserHandle.USER_ALL);
14058                allSticky = getStickiesLocked(null, filter, allSticky,
14059                        UserHandle.getUserId(callingUid));
14060            }
14061
14062            // The first sticky in the list is returned directly back to
14063            // the client.
14064            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14065
14066            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14067                    + ": " + sticky);
14068
14069            if (receiver == null) {
14070                return sticky;
14071            }
14072
14073            ReceiverList rl
14074                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14075            if (rl == null) {
14076                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14077                        userId, receiver);
14078                if (rl.app != null) {
14079                    rl.app.receivers.add(rl);
14080                } else {
14081                    try {
14082                        receiver.asBinder().linkToDeath(rl, 0);
14083                    } catch (RemoteException e) {
14084                        return sticky;
14085                    }
14086                    rl.linkedToDeath = true;
14087                }
14088                mRegisteredReceivers.put(receiver.asBinder(), rl);
14089            } else if (rl.uid != callingUid) {
14090                throw new IllegalArgumentException(
14091                        "Receiver requested to register for uid " + callingUid
14092                        + " was previously registered for uid " + rl.uid);
14093            } else if (rl.pid != callingPid) {
14094                throw new IllegalArgumentException(
14095                        "Receiver requested to register for pid " + callingPid
14096                        + " was previously registered for pid " + rl.pid);
14097            } else if (rl.userId != userId) {
14098                throw new IllegalArgumentException(
14099                        "Receiver requested to register for user " + userId
14100                        + " was previously registered for user " + rl.userId);
14101            }
14102            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14103                    permission, callingUid, userId);
14104            rl.add(bf);
14105            if (!bf.debugCheck()) {
14106                Slog.w(TAG, "==> For Dynamic broadast");
14107            }
14108            mReceiverResolver.addFilter(bf);
14109
14110            // Enqueue broadcasts for all existing stickies that match
14111            // this filter.
14112            if (allSticky != null) {
14113                ArrayList receivers = new ArrayList();
14114                receivers.add(bf);
14115
14116                int N = allSticky.size();
14117                for (int i=0; i<N; i++) {
14118                    Intent intent = (Intent)allSticky.get(i);
14119                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14120                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14121                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14122                            null, null, false, true, true, -1);
14123                    queue.enqueueParallelBroadcastLocked(r);
14124                    queue.scheduleBroadcastsLocked();
14125                }
14126            }
14127
14128            return sticky;
14129        }
14130    }
14131
14132    public void unregisterReceiver(IIntentReceiver receiver) {
14133        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14134
14135        final long origId = Binder.clearCallingIdentity();
14136        try {
14137            boolean doTrim = false;
14138
14139            synchronized(this) {
14140                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14141                if (rl != null) {
14142                    if (rl.curBroadcast != null) {
14143                        BroadcastRecord r = rl.curBroadcast;
14144                        final boolean doNext = finishReceiverLocked(
14145                                receiver.asBinder(), r.resultCode, r.resultData,
14146                                r.resultExtras, r.resultAbort);
14147                        if (doNext) {
14148                            doTrim = true;
14149                            r.queue.processNextBroadcast(false);
14150                        }
14151                    }
14152
14153                    if (rl.app != null) {
14154                        rl.app.receivers.remove(rl);
14155                    }
14156                    removeReceiverLocked(rl);
14157                    if (rl.linkedToDeath) {
14158                        rl.linkedToDeath = false;
14159                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14160                    }
14161                }
14162            }
14163
14164            // If we actually concluded any broadcasts, we might now be able
14165            // to trim the recipients' apps from our working set
14166            if (doTrim) {
14167                trimApplications();
14168                return;
14169            }
14170
14171        } finally {
14172            Binder.restoreCallingIdentity(origId);
14173        }
14174    }
14175
14176    void removeReceiverLocked(ReceiverList rl) {
14177        mRegisteredReceivers.remove(rl.receiver.asBinder());
14178        int N = rl.size();
14179        for (int i=0; i<N; i++) {
14180            mReceiverResolver.removeFilter(rl.get(i));
14181        }
14182    }
14183
14184    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14185        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14186            ProcessRecord r = mLruProcesses.get(i);
14187            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14188                try {
14189                    r.thread.dispatchPackageBroadcast(cmd, packages);
14190                } catch (RemoteException ex) {
14191                }
14192            }
14193        }
14194    }
14195
14196    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14197            int[] users) {
14198        List<ResolveInfo> receivers = null;
14199        try {
14200            HashSet<ComponentName> singleUserReceivers = null;
14201            boolean scannedFirstReceivers = false;
14202            for (int user : users) {
14203                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14204                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14205                if (user != 0 && newReceivers != null) {
14206                    // If this is not the primary user, we need to check for
14207                    // any receivers that should be filtered out.
14208                    for (int i=0; i<newReceivers.size(); i++) {
14209                        ResolveInfo ri = newReceivers.get(i);
14210                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14211                            newReceivers.remove(i);
14212                            i--;
14213                        }
14214                    }
14215                }
14216                if (newReceivers != null && newReceivers.size() == 0) {
14217                    newReceivers = null;
14218                }
14219                if (receivers == null) {
14220                    receivers = newReceivers;
14221                } else if (newReceivers != null) {
14222                    // We need to concatenate the additional receivers
14223                    // found with what we have do far.  This would be easy,
14224                    // but we also need to de-dup any receivers that are
14225                    // singleUser.
14226                    if (!scannedFirstReceivers) {
14227                        // Collect any single user receivers we had already retrieved.
14228                        scannedFirstReceivers = true;
14229                        for (int i=0; i<receivers.size(); i++) {
14230                            ResolveInfo ri = receivers.get(i);
14231                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14232                                ComponentName cn = new ComponentName(
14233                                        ri.activityInfo.packageName, ri.activityInfo.name);
14234                                if (singleUserReceivers == null) {
14235                                    singleUserReceivers = new HashSet<ComponentName>();
14236                                }
14237                                singleUserReceivers.add(cn);
14238                            }
14239                        }
14240                    }
14241                    // Add the new results to the existing results, tracking
14242                    // and de-dupping single user receivers.
14243                    for (int i=0; i<newReceivers.size(); i++) {
14244                        ResolveInfo ri = newReceivers.get(i);
14245                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14246                            ComponentName cn = new ComponentName(
14247                                    ri.activityInfo.packageName, ri.activityInfo.name);
14248                            if (singleUserReceivers == null) {
14249                                singleUserReceivers = new HashSet<ComponentName>();
14250                            }
14251                            if (!singleUserReceivers.contains(cn)) {
14252                                singleUserReceivers.add(cn);
14253                                receivers.add(ri);
14254                            }
14255                        } else {
14256                            receivers.add(ri);
14257                        }
14258                    }
14259                }
14260            }
14261        } catch (RemoteException ex) {
14262            // pm is in same process, this will never happen.
14263        }
14264        return receivers;
14265    }
14266
14267    private final int broadcastIntentLocked(ProcessRecord callerApp,
14268            String callerPackage, Intent intent, String resolvedType,
14269            IIntentReceiver resultTo, int resultCode, String resultData,
14270            Bundle map, String requiredPermission, int appOp,
14271            boolean ordered, boolean sticky, int callingPid, int callingUid,
14272            int userId) {
14273        intent = new Intent(intent);
14274
14275        // By default broadcasts do not go to stopped apps.
14276        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14277
14278        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14279            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14280            + " ordered=" + ordered + " userid=" + userId);
14281        if ((resultTo != null) && !ordered) {
14282            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14283        }
14284
14285        userId = handleIncomingUser(callingPid, callingUid, userId,
14286                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14287
14288        // Make sure that the user who is receiving this broadcast is started.
14289        // If not, we will just skip it.
14290
14291
14292        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14293            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14294                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14295                Slog.w(TAG, "Skipping broadcast of " + intent
14296                        + ": user " + userId + " is stopped");
14297                return ActivityManager.BROADCAST_SUCCESS;
14298            }
14299        }
14300
14301        /*
14302         * Prevent non-system code (defined here to be non-persistent
14303         * processes) from sending protected broadcasts.
14304         */
14305        int callingAppId = UserHandle.getAppId(callingUid);
14306        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14307            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14308            || callingAppId == Process.NFC_UID || callingUid == 0) {
14309            // Always okay.
14310        } else if (callerApp == null || !callerApp.persistent) {
14311            try {
14312                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14313                        intent.getAction())) {
14314                    String msg = "Permission Denial: not allowed to send broadcast "
14315                            + intent.getAction() + " from pid="
14316                            + callingPid + ", uid=" + callingUid;
14317                    Slog.w(TAG, msg);
14318                    throw new SecurityException(msg);
14319                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14320                    // Special case for compatibility: we don't want apps to send this,
14321                    // but historically it has not been protected and apps may be using it
14322                    // to poke their own app widget.  So, instead of making it protected,
14323                    // just limit it to the caller.
14324                    if (callerApp == null) {
14325                        String msg = "Permission Denial: not allowed to send broadcast "
14326                                + intent.getAction() + " from unknown caller.";
14327                        Slog.w(TAG, msg);
14328                        throw new SecurityException(msg);
14329                    } else if (intent.getComponent() != null) {
14330                        // They are good enough to send to an explicit component...  verify
14331                        // it is being sent to the calling app.
14332                        if (!intent.getComponent().getPackageName().equals(
14333                                callerApp.info.packageName)) {
14334                            String msg = "Permission Denial: not allowed to send broadcast "
14335                                    + intent.getAction() + " to "
14336                                    + intent.getComponent().getPackageName() + " from "
14337                                    + callerApp.info.packageName;
14338                            Slog.w(TAG, msg);
14339                            throw new SecurityException(msg);
14340                        }
14341                    } else {
14342                        // Limit broadcast to their own package.
14343                        intent.setPackage(callerApp.info.packageName);
14344                    }
14345                }
14346            } catch (RemoteException e) {
14347                Slog.w(TAG, "Remote exception", e);
14348                return ActivityManager.BROADCAST_SUCCESS;
14349            }
14350        }
14351
14352        // Handle special intents: if this broadcast is from the package
14353        // manager about a package being removed, we need to remove all of
14354        // its activities from the history stack.
14355        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14356                intent.getAction());
14357        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14358                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14359                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14360                || uidRemoved) {
14361            if (checkComponentPermission(
14362                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14363                    callingPid, callingUid, -1, true)
14364                    == PackageManager.PERMISSION_GRANTED) {
14365                if (uidRemoved) {
14366                    final Bundle intentExtras = intent.getExtras();
14367                    final int uid = intentExtras != null
14368                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14369                    if (uid >= 0) {
14370                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14371                        synchronized (bs) {
14372                            bs.removeUidStatsLocked(uid);
14373                        }
14374                        mAppOpsService.uidRemoved(uid);
14375                    }
14376                } else {
14377                    // If resources are unavailable just force stop all
14378                    // those packages and flush the attribute cache as well.
14379                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14380                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14381                        if (list != null && (list.length > 0)) {
14382                            for (String pkg : list) {
14383                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14384                                        "storage unmount");
14385                            }
14386                            sendPackageBroadcastLocked(
14387                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14388                        }
14389                    } else {
14390                        Uri data = intent.getData();
14391                        String ssp;
14392                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14393                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14394                                    intent.getAction());
14395                            boolean fullUninstall = removed &&
14396                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14397                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14398                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14399                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14400                                        false, fullUninstall, userId,
14401                                        removed ? "pkg removed" : "pkg changed");
14402                            }
14403                            if (removed) {
14404                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14405                                        new String[] {ssp}, userId);
14406                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14407                                    mAppOpsService.packageRemoved(
14408                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14409
14410                                    // Remove all permissions granted from/to this package
14411                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14412                                }
14413                            }
14414                        }
14415                    }
14416                }
14417            } else {
14418                String msg = "Permission Denial: " + intent.getAction()
14419                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14420                        + ", uid=" + callingUid + ")"
14421                        + " requires "
14422                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14423                Slog.w(TAG, msg);
14424                throw new SecurityException(msg);
14425            }
14426
14427        // Special case for adding a package: by default turn on compatibility
14428        // mode.
14429        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14430            Uri data = intent.getData();
14431            String ssp;
14432            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14433                mCompatModePackages.handlePackageAddedLocked(ssp,
14434                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14435            }
14436        }
14437
14438        /*
14439         * If this is the time zone changed action, queue up a message that will reset the timezone
14440         * of all currently running processes. This message will get queued up before the broadcast
14441         * happens.
14442         */
14443        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14444            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14445        }
14446
14447        /*
14448         * If the user set the time, let all running processes know.
14449         */
14450        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14451            final int is24Hour = intent.getBooleanExtra(
14452                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14453            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14454        }
14455
14456        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14457            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14458        }
14459
14460        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14461            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14462            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14463        }
14464
14465        // Add to the sticky list if requested.
14466        if (sticky) {
14467            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14468                    callingPid, callingUid)
14469                    != PackageManager.PERMISSION_GRANTED) {
14470                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14471                        + callingPid + ", uid=" + callingUid
14472                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14473                Slog.w(TAG, msg);
14474                throw new SecurityException(msg);
14475            }
14476            if (requiredPermission != null) {
14477                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14478                        + " and enforce permission " + requiredPermission);
14479                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14480            }
14481            if (intent.getComponent() != null) {
14482                throw new SecurityException(
14483                        "Sticky broadcasts can't target a specific component");
14484            }
14485            // We use userId directly here, since the "all" target is maintained
14486            // as a separate set of sticky broadcasts.
14487            if (userId != UserHandle.USER_ALL) {
14488                // But first, if this is not a broadcast to all users, then
14489                // make sure it doesn't conflict with an existing broadcast to
14490                // all users.
14491                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14492                        UserHandle.USER_ALL);
14493                if (stickies != null) {
14494                    ArrayList<Intent> list = stickies.get(intent.getAction());
14495                    if (list != null) {
14496                        int N = list.size();
14497                        int i;
14498                        for (i=0; i<N; i++) {
14499                            if (intent.filterEquals(list.get(i))) {
14500                                throw new IllegalArgumentException(
14501                                        "Sticky broadcast " + intent + " for user "
14502                                        + userId + " conflicts with existing global broadcast");
14503                            }
14504                        }
14505                    }
14506                }
14507            }
14508            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14509            if (stickies == null) {
14510                stickies = new ArrayMap<String, ArrayList<Intent>>();
14511                mStickyBroadcasts.put(userId, stickies);
14512            }
14513            ArrayList<Intent> list = stickies.get(intent.getAction());
14514            if (list == null) {
14515                list = new ArrayList<Intent>();
14516                stickies.put(intent.getAction(), list);
14517            }
14518            int N = list.size();
14519            int i;
14520            for (i=0; i<N; i++) {
14521                if (intent.filterEquals(list.get(i))) {
14522                    // This sticky already exists, replace it.
14523                    list.set(i, new Intent(intent));
14524                    break;
14525                }
14526            }
14527            if (i >= N) {
14528                list.add(new Intent(intent));
14529            }
14530        }
14531
14532        int[] users;
14533        if (userId == UserHandle.USER_ALL) {
14534            // Caller wants broadcast to go to all started users.
14535            users = mStartedUserArray;
14536        } else {
14537            // Caller wants broadcast to go to one specific user.
14538            users = new int[] {userId};
14539        }
14540
14541        // Figure out who all will receive this broadcast.
14542        List receivers = null;
14543        List<BroadcastFilter> registeredReceivers = null;
14544        // Need to resolve the intent to interested receivers...
14545        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14546                 == 0) {
14547            receivers = collectReceiverComponents(intent, resolvedType, users);
14548        }
14549        if (intent.getComponent() == null) {
14550            registeredReceivers = mReceiverResolver.queryIntent(intent,
14551                    resolvedType, false, userId);
14552        }
14553
14554        final boolean replacePending =
14555                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14556
14557        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14558                + " replacePending=" + replacePending);
14559
14560        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14561        if (!ordered && NR > 0) {
14562            // If we are not serializing this broadcast, then send the
14563            // registered receivers separately so they don't wait for the
14564            // components to be launched.
14565            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14566            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14567                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14568                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14569                    ordered, sticky, false, userId);
14570            if (DEBUG_BROADCAST) Slog.v(
14571                    TAG, "Enqueueing parallel broadcast " + r);
14572            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14573            if (!replaced) {
14574                queue.enqueueParallelBroadcastLocked(r);
14575                queue.scheduleBroadcastsLocked();
14576            }
14577            registeredReceivers = null;
14578            NR = 0;
14579        }
14580
14581        // Merge into one list.
14582        int ir = 0;
14583        if (receivers != null) {
14584            // A special case for PACKAGE_ADDED: do not allow the package
14585            // being added to see this broadcast.  This prevents them from
14586            // using this as a back door to get run as soon as they are
14587            // installed.  Maybe in the future we want to have a special install
14588            // broadcast or such for apps, but we'd like to deliberately make
14589            // this decision.
14590            String skipPackages[] = null;
14591            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14592                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14593                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14594                Uri data = intent.getData();
14595                if (data != null) {
14596                    String pkgName = data.getSchemeSpecificPart();
14597                    if (pkgName != null) {
14598                        skipPackages = new String[] { pkgName };
14599                    }
14600                }
14601            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14602                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14603            }
14604            if (skipPackages != null && (skipPackages.length > 0)) {
14605                for (String skipPackage : skipPackages) {
14606                    if (skipPackage != null) {
14607                        int NT = receivers.size();
14608                        for (int it=0; it<NT; it++) {
14609                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14610                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14611                                receivers.remove(it);
14612                                it--;
14613                                NT--;
14614                            }
14615                        }
14616                    }
14617                }
14618            }
14619
14620            int NT = receivers != null ? receivers.size() : 0;
14621            int it = 0;
14622            ResolveInfo curt = null;
14623            BroadcastFilter curr = null;
14624            while (it < NT && ir < NR) {
14625                if (curt == null) {
14626                    curt = (ResolveInfo)receivers.get(it);
14627                }
14628                if (curr == null) {
14629                    curr = registeredReceivers.get(ir);
14630                }
14631                if (curr.getPriority() >= curt.priority) {
14632                    // Insert this broadcast record into the final list.
14633                    receivers.add(it, curr);
14634                    ir++;
14635                    curr = null;
14636                    it++;
14637                    NT++;
14638                } else {
14639                    // Skip to the next ResolveInfo in the final list.
14640                    it++;
14641                    curt = null;
14642                }
14643            }
14644        }
14645        while (ir < NR) {
14646            if (receivers == null) {
14647                receivers = new ArrayList();
14648            }
14649            receivers.add(registeredReceivers.get(ir));
14650            ir++;
14651        }
14652
14653        if ((receivers != null && receivers.size() > 0)
14654                || resultTo != null) {
14655            BroadcastQueue queue = broadcastQueueForIntent(intent);
14656            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14657                    callerPackage, callingPid, callingUid, resolvedType,
14658                    requiredPermission, appOp, receivers, resultTo, resultCode,
14659                    resultData, map, ordered, sticky, false, userId);
14660            if (DEBUG_BROADCAST) Slog.v(
14661                    TAG, "Enqueueing ordered broadcast " + r
14662                    + ": prev had " + queue.mOrderedBroadcasts.size());
14663            if (DEBUG_BROADCAST) {
14664                int seq = r.intent.getIntExtra("seq", -1);
14665                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14666            }
14667            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14668            if (!replaced) {
14669                queue.enqueueOrderedBroadcastLocked(r);
14670                queue.scheduleBroadcastsLocked();
14671            }
14672        }
14673
14674        return ActivityManager.BROADCAST_SUCCESS;
14675    }
14676
14677    final Intent verifyBroadcastLocked(Intent intent) {
14678        // Refuse possible leaked file descriptors
14679        if (intent != null && intent.hasFileDescriptors() == true) {
14680            throw new IllegalArgumentException("File descriptors passed in Intent");
14681        }
14682
14683        int flags = intent.getFlags();
14684
14685        if (!mProcessesReady) {
14686            // if the caller really truly claims to know what they're doing, go
14687            // ahead and allow the broadcast without launching any receivers
14688            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14689                intent = new Intent(intent);
14690                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14691            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14692                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14693                        + " before boot completion");
14694                throw new IllegalStateException("Cannot broadcast before boot completed");
14695            }
14696        }
14697
14698        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14699            throw new IllegalArgumentException(
14700                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14701        }
14702
14703        return intent;
14704    }
14705
14706    public final int broadcastIntent(IApplicationThread caller,
14707            Intent intent, String resolvedType, IIntentReceiver resultTo,
14708            int resultCode, String resultData, Bundle map,
14709            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14710        enforceNotIsolatedCaller("broadcastIntent");
14711        synchronized(this) {
14712            intent = verifyBroadcastLocked(intent);
14713
14714            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14715            final int callingPid = Binder.getCallingPid();
14716            final int callingUid = Binder.getCallingUid();
14717            final long origId = Binder.clearCallingIdentity();
14718            int res = broadcastIntentLocked(callerApp,
14719                    callerApp != null ? callerApp.info.packageName : null,
14720                    intent, resolvedType, resultTo,
14721                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14722                    callingPid, callingUid, userId);
14723            Binder.restoreCallingIdentity(origId);
14724            return res;
14725        }
14726    }
14727
14728    int broadcastIntentInPackage(String packageName, int uid,
14729            Intent intent, String resolvedType, IIntentReceiver resultTo,
14730            int resultCode, String resultData, Bundle map,
14731            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14732        synchronized(this) {
14733            intent = verifyBroadcastLocked(intent);
14734
14735            final long origId = Binder.clearCallingIdentity();
14736            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14737                    resultTo, resultCode, resultData, map, requiredPermission,
14738                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14739            Binder.restoreCallingIdentity(origId);
14740            return res;
14741        }
14742    }
14743
14744    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14745        // Refuse possible leaked file descriptors
14746        if (intent != null && intent.hasFileDescriptors() == true) {
14747            throw new IllegalArgumentException("File descriptors passed in Intent");
14748        }
14749
14750        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14751                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14752
14753        synchronized(this) {
14754            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14755                    != PackageManager.PERMISSION_GRANTED) {
14756                String msg = "Permission Denial: unbroadcastIntent() from pid="
14757                        + Binder.getCallingPid()
14758                        + ", uid=" + Binder.getCallingUid()
14759                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14760                Slog.w(TAG, msg);
14761                throw new SecurityException(msg);
14762            }
14763            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14764            if (stickies != null) {
14765                ArrayList<Intent> list = stickies.get(intent.getAction());
14766                if (list != null) {
14767                    int N = list.size();
14768                    int i;
14769                    for (i=0; i<N; i++) {
14770                        if (intent.filterEquals(list.get(i))) {
14771                            list.remove(i);
14772                            break;
14773                        }
14774                    }
14775                    if (list.size() <= 0) {
14776                        stickies.remove(intent.getAction());
14777                    }
14778                }
14779                if (stickies.size() <= 0) {
14780                    mStickyBroadcasts.remove(userId);
14781                }
14782            }
14783        }
14784    }
14785
14786    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14787            String resultData, Bundle resultExtras, boolean resultAbort) {
14788        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14789        if (r == null) {
14790            Slog.w(TAG, "finishReceiver called but not found on queue");
14791            return false;
14792        }
14793
14794        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14795    }
14796
14797    void backgroundServicesFinishedLocked(int userId) {
14798        for (BroadcastQueue queue : mBroadcastQueues) {
14799            queue.backgroundServicesFinishedLocked(userId);
14800        }
14801    }
14802
14803    public void finishReceiver(IBinder who, int resultCode, String resultData,
14804            Bundle resultExtras, boolean resultAbort) {
14805        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14806
14807        // Refuse possible leaked file descriptors
14808        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14809            throw new IllegalArgumentException("File descriptors passed in Bundle");
14810        }
14811
14812        final long origId = Binder.clearCallingIdentity();
14813        try {
14814            boolean doNext = false;
14815            BroadcastRecord r;
14816
14817            synchronized(this) {
14818                r = broadcastRecordForReceiverLocked(who);
14819                if (r != null) {
14820                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14821                        resultData, resultExtras, resultAbort, true);
14822                }
14823            }
14824
14825            if (doNext) {
14826                r.queue.processNextBroadcast(false);
14827            }
14828            trimApplications();
14829        } finally {
14830            Binder.restoreCallingIdentity(origId);
14831        }
14832    }
14833
14834    // =========================================================
14835    // INSTRUMENTATION
14836    // =========================================================
14837
14838    public boolean startInstrumentation(ComponentName className,
14839            String profileFile, int flags, Bundle arguments,
14840            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14841            int userId, String abiOverride) {
14842        enforceNotIsolatedCaller("startInstrumentation");
14843        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14844                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14845        // Refuse possible leaked file descriptors
14846        if (arguments != null && arguments.hasFileDescriptors()) {
14847            throw new IllegalArgumentException("File descriptors passed in Bundle");
14848        }
14849
14850        synchronized(this) {
14851            InstrumentationInfo ii = null;
14852            ApplicationInfo ai = null;
14853            try {
14854                ii = mContext.getPackageManager().getInstrumentationInfo(
14855                    className, STOCK_PM_FLAGS);
14856                ai = AppGlobals.getPackageManager().getApplicationInfo(
14857                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14858            } catch (PackageManager.NameNotFoundException e) {
14859            } catch (RemoteException e) {
14860            }
14861            if (ii == null) {
14862                reportStartInstrumentationFailure(watcher, className,
14863                        "Unable to find instrumentation info for: " + className);
14864                return false;
14865            }
14866            if (ai == null) {
14867                reportStartInstrumentationFailure(watcher, className,
14868                        "Unable to find instrumentation target package: " + ii.targetPackage);
14869                return false;
14870            }
14871
14872            int match = mContext.getPackageManager().checkSignatures(
14873                    ii.targetPackage, ii.packageName);
14874            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14875                String msg = "Permission Denial: starting instrumentation "
14876                        + className + " from pid="
14877                        + Binder.getCallingPid()
14878                        + ", uid=" + Binder.getCallingPid()
14879                        + " not allowed because package " + ii.packageName
14880                        + " does not have a signature matching the target "
14881                        + ii.targetPackage;
14882                reportStartInstrumentationFailure(watcher, className, msg);
14883                throw new SecurityException(msg);
14884            }
14885
14886            final long origId = Binder.clearCallingIdentity();
14887            // Instrumentation can kill and relaunch even persistent processes
14888            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14889                    "start instr");
14890            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14891            app.instrumentationClass = className;
14892            app.instrumentationInfo = ai;
14893            app.instrumentationProfileFile = profileFile;
14894            app.instrumentationArguments = arguments;
14895            app.instrumentationWatcher = watcher;
14896            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14897            app.instrumentationResultClass = className;
14898            Binder.restoreCallingIdentity(origId);
14899        }
14900
14901        return true;
14902    }
14903
14904    /**
14905     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14906     * error to the logs, but if somebody is watching, send the report there too.  This enables
14907     * the "am" command to report errors with more information.
14908     *
14909     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14910     * @param cn The component name of the instrumentation.
14911     * @param report The error report.
14912     */
14913    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14914            ComponentName cn, String report) {
14915        Slog.w(TAG, report);
14916        try {
14917            if (watcher != null) {
14918                Bundle results = new Bundle();
14919                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14920                results.putString("Error", report);
14921                watcher.instrumentationStatus(cn, -1, results);
14922            }
14923        } catch (RemoteException e) {
14924            Slog.w(TAG, e);
14925        }
14926    }
14927
14928    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14929        if (app.instrumentationWatcher != null) {
14930            try {
14931                // NOTE:  IInstrumentationWatcher *must* be oneway here
14932                app.instrumentationWatcher.instrumentationFinished(
14933                    app.instrumentationClass,
14934                    resultCode,
14935                    results);
14936            } catch (RemoteException e) {
14937            }
14938        }
14939        if (app.instrumentationUiAutomationConnection != null) {
14940            try {
14941                app.instrumentationUiAutomationConnection.shutdown();
14942            } catch (RemoteException re) {
14943                /* ignore */
14944            }
14945            // Only a UiAutomation can set this flag and now that
14946            // it is finished we make sure it is reset to its default.
14947            mUserIsMonkey = false;
14948        }
14949        app.instrumentationWatcher = null;
14950        app.instrumentationUiAutomationConnection = null;
14951        app.instrumentationClass = null;
14952        app.instrumentationInfo = null;
14953        app.instrumentationProfileFile = null;
14954        app.instrumentationArguments = null;
14955
14956        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14957                "finished inst");
14958    }
14959
14960    public void finishInstrumentation(IApplicationThread target,
14961            int resultCode, Bundle results) {
14962        int userId = UserHandle.getCallingUserId();
14963        // Refuse possible leaked file descriptors
14964        if (results != null && results.hasFileDescriptors()) {
14965            throw new IllegalArgumentException("File descriptors passed in Intent");
14966        }
14967
14968        synchronized(this) {
14969            ProcessRecord app = getRecordForAppLocked(target);
14970            if (app == null) {
14971                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14972                return;
14973            }
14974            final long origId = Binder.clearCallingIdentity();
14975            finishInstrumentationLocked(app, resultCode, results);
14976            Binder.restoreCallingIdentity(origId);
14977        }
14978    }
14979
14980    // =========================================================
14981    // CONFIGURATION
14982    // =========================================================
14983
14984    public ConfigurationInfo getDeviceConfigurationInfo() {
14985        ConfigurationInfo config = new ConfigurationInfo();
14986        synchronized (this) {
14987            config.reqTouchScreen = mConfiguration.touchscreen;
14988            config.reqKeyboardType = mConfiguration.keyboard;
14989            config.reqNavigation = mConfiguration.navigation;
14990            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14991                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14992                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14993            }
14994            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14995                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14996                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14997            }
14998            config.reqGlEsVersion = GL_ES_VERSION;
14999        }
15000        return config;
15001    }
15002
15003    ActivityStack getFocusedStack() {
15004        return mStackSupervisor.getFocusedStack();
15005    }
15006
15007    public Configuration getConfiguration() {
15008        Configuration ci;
15009        synchronized(this) {
15010            ci = new Configuration(mConfiguration);
15011        }
15012        return ci;
15013    }
15014
15015    public void updatePersistentConfiguration(Configuration values) {
15016        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15017                "updateConfiguration()");
15018        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15019                "updateConfiguration()");
15020        if (values == null) {
15021            throw new NullPointerException("Configuration must not be null");
15022        }
15023
15024        synchronized(this) {
15025            final long origId = Binder.clearCallingIdentity();
15026            updateConfigurationLocked(values, null, true, false);
15027            Binder.restoreCallingIdentity(origId);
15028        }
15029    }
15030
15031    public void updateConfiguration(Configuration values) {
15032        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15033                "updateConfiguration()");
15034
15035        synchronized(this) {
15036            if (values == null && mWindowManager != null) {
15037                // sentinel: fetch the current configuration from the window manager
15038                values = mWindowManager.computeNewConfiguration();
15039            }
15040
15041            if (mWindowManager != null) {
15042                mProcessList.applyDisplaySize(mWindowManager);
15043            }
15044
15045            final long origId = Binder.clearCallingIdentity();
15046            if (values != null) {
15047                Settings.System.clearConfiguration(values);
15048            }
15049            updateConfigurationLocked(values, null, false, false);
15050            Binder.restoreCallingIdentity(origId);
15051        }
15052    }
15053
15054    /**
15055     * Do either or both things: (1) change the current configuration, and (2)
15056     * make sure the given activity is running with the (now) current
15057     * configuration.  Returns true if the activity has been left running, or
15058     * false if <var>starting</var> is being destroyed to match the new
15059     * configuration.
15060     * @param persistent TODO
15061     */
15062    boolean updateConfigurationLocked(Configuration values,
15063            ActivityRecord starting, boolean persistent, boolean initLocale) {
15064        int changes = 0;
15065
15066        if (values != null) {
15067            Configuration newConfig = new Configuration(mConfiguration);
15068            changes = newConfig.updateFrom(values);
15069            if (changes != 0) {
15070                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15071                    Slog.i(TAG, "Updating configuration to: " + values);
15072                }
15073
15074                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15075
15076                if (values.locale != null && !initLocale) {
15077                    saveLocaleLocked(values.locale,
15078                                     !values.locale.equals(mConfiguration.locale),
15079                                     values.userSetLocale);
15080                }
15081
15082                mConfigurationSeq++;
15083                if (mConfigurationSeq <= 0) {
15084                    mConfigurationSeq = 1;
15085                }
15086                newConfig.seq = mConfigurationSeq;
15087                mConfiguration = newConfig;
15088                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15089                //mUsageStatsService.noteStartConfig(newConfig);
15090
15091                final Configuration configCopy = new Configuration(mConfiguration);
15092
15093                // TODO: If our config changes, should we auto dismiss any currently
15094                // showing dialogs?
15095                mShowDialogs = shouldShowDialogs(newConfig);
15096
15097                AttributeCache ac = AttributeCache.instance();
15098                if (ac != null) {
15099                    ac.updateConfiguration(configCopy);
15100                }
15101
15102                // Make sure all resources in our process are updated
15103                // right now, so that anyone who is going to retrieve
15104                // resource values after we return will be sure to get
15105                // the new ones.  This is especially important during
15106                // boot, where the first config change needs to guarantee
15107                // all resources have that config before following boot
15108                // code is executed.
15109                mSystemThread.applyConfigurationToResources(configCopy);
15110
15111                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15112                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15113                    msg.obj = new Configuration(configCopy);
15114                    mHandler.sendMessage(msg);
15115                }
15116
15117                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15118                    ProcessRecord app = mLruProcesses.get(i);
15119                    try {
15120                        if (app.thread != null) {
15121                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15122                                    + app.processName + " new config " + mConfiguration);
15123                            app.thread.scheduleConfigurationChanged(configCopy);
15124                        }
15125                    } catch (Exception e) {
15126                    }
15127                }
15128                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15129                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15130                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15131                        | Intent.FLAG_RECEIVER_FOREGROUND);
15132                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15133                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15134                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15135                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15136                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15137                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15138                    broadcastIntentLocked(null, null, intent,
15139                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15140                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15141                }
15142            }
15143        }
15144
15145        boolean kept = true;
15146        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15147        // mainStack is null during startup.
15148        if (mainStack != null) {
15149            if (changes != 0 && starting == null) {
15150                // If the configuration changed, and the caller is not already
15151                // in the process of starting an activity, then find the top
15152                // activity to check if its configuration needs to change.
15153                starting = mainStack.topRunningActivityLocked(null);
15154            }
15155
15156            if (starting != null) {
15157                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15158                // And we need to make sure at this point that all other activities
15159                // are made visible with the correct configuration.
15160                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15161            }
15162        }
15163
15164        if (values != null && mWindowManager != null) {
15165            mWindowManager.setNewConfiguration(mConfiguration);
15166        }
15167
15168        return kept;
15169    }
15170
15171    /**
15172     * Decide based on the configuration whether we should shouw the ANR,
15173     * crash, etc dialogs.  The idea is that if there is no affordnace to
15174     * press the on-screen buttons, we shouldn't show the dialog.
15175     *
15176     * A thought: SystemUI might also want to get told about this, the Power
15177     * dialog / global actions also might want different behaviors.
15178     */
15179    private static final boolean shouldShowDialogs(Configuration config) {
15180        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15181                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15182    }
15183
15184    /**
15185     * Save the locale.  You must be inside a synchronized (this) block.
15186     */
15187    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15188        if(isDiff) {
15189            SystemProperties.set("user.language", l.getLanguage());
15190            SystemProperties.set("user.region", l.getCountry());
15191        }
15192
15193        if(isPersist) {
15194            SystemProperties.set("persist.sys.language", l.getLanguage());
15195            SystemProperties.set("persist.sys.country", l.getCountry());
15196            SystemProperties.set("persist.sys.localevar", l.getVariant());
15197        }
15198    }
15199
15200    @Override
15201    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15202        ActivityRecord srec = ActivityRecord.forToken(token);
15203        return srec != null && srec.task.affinity != null &&
15204                srec.task.affinity.equals(destAffinity);
15205    }
15206
15207    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15208            Intent resultData) {
15209
15210        synchronized (this) {
15211            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15212            if (stack != null) {
15213                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15214            }
15215            return false;
15216        }
15217    }
15218
15219    public int getLaunchedFromUid(IBinder activityToken) {
15220        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15221        if (srec == null) {
15222            return -1;
15223        }
15224        return srec.launchedFromUid;
15225    }
15226
15227    public String getLaunchedFromPackage(IBinder activityToken) {
15228        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15229        if (srec == null) {
15230            return null;
15231        }
15232        return srec.launchedFromPackage;
15233    }
15234
15235    // =========================================================
15236    // LIFETIME MANAGEMENT
15237    // =========================================================
15238
15239    // Returns which broadcast queue the app is the current [or imminent] receiver
15240    // on, or 'null' if the app is not an active broadcast recipient.
15241    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15242        BroadcastRecord r = app.curReceiver;
15243        if (r != null) {
15244            return r.queue;
15245        }
15246
15247        // It's not the current receiver, but it might be starting up to become one
15248        synchronized (this) {
15249            for (BroadcastQueue queue : mBroadcastQueues) {
15250                r = queue.mPendingBroadcast;
15251                if (r != null && r.curApp == app) {
15252                    // found it; report which queue it's in
15253                    return queue;
15254                }
15255            }
15256        }
15257
15258        return null;
15259    }
15260
15261    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15262            boolean doingAll, long now) {
15263        if (mAdjSeq == app.adjSeq) {
15264            // This adjustment has already been computed.
15265            return app.curRawAdj;
15266        }
15267
15268        if (app.thread == null) {
15269            app.adjSeq = mAdjSeq;
15270            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15271            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15272            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15273        }
15274
15275        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15276        app.adjSource = null;
15277        app.adjTarget = null;
15278        app.empty = false;
15279        app.cached = false;
15280
15281        final int activitiesSize = app.activities.size();
15282
15283        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15284            // The max adjustment doesn't allow this app to be anything
15285            // below foreground, so it is not worth doing work for it.
15286            app.adjType = "fixed";
15287            app.adjSeq = mAdjSeq;
15288            app.curRawAdj = app.maxAdj;
15289            app.foregroundActivities = false;
15290            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15291            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15292            // System processes can do UI, and when they do we want to have
15293            // them trim their memory after the user leaves the UI.  To
15294            // facilitate this, here we need to determine whether or not it
15295            // is currently showing UI.
15296            app.systemNoUi = true;
15297            if (app == TOP_APP) {
15298                app.systemNoUi = false;
15299            } else if (activitiesSize > 0) {
15300                for (int j = 0; j < activitiesSize; j++) {
15301                    final ActivityRecord r = app.activities.get(j);
15302                    if (r.visible) {
15303                        app.systemNoUi = false;
15304                    }
15305                }
15306            }
15307            if (!app.systemNoUi) {
15308                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15309            }
15310            return (app.curAdj=app.maxAdj);
15311        }
15312
15313        app.systemNoUi = false;
15314
15315        // Determine the importance of the process, starting with most
15316        // important to least, and assign an appropriate OOM adjustment.
15317        int adj;
15318        int schedGroup;
15319        int procState;
15320        boolean foregroundActivities = false;
15321        BroadcastQueue queue;
15322        if (app == TOP_APP) {
15323            // The last app on the list is the foreground app.
15324            adj = ProcessList.FOREGROUND_APP_ADJ;
15325            schedGroup = Process.THREAD_GROUP_DEFAULT;
15326            app.adjType = "top-activity";
15327            foregroundActivities = true;
15328            procState = ActivityManager.PROCESS_STATE_TOP;
15329        } else if (app.instrumentationClass != null) {
15330            // Don't want to kill running instrumentation.
15331            adj = ProcessList.FOREGROUND_APP_ADJ;
15332            schedGroup = Process.THREAD_GROUP_DEFAULT;
15333            app.adjType = "instrumentation";
15334            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15335        } else if ((queue = isReceivingBroadcast(app)) != null) {
15336            // An app that is currently receiving a broadcast also
15337            // counts as being in the foreground for OOM killer purposes.
15338            // It's placed in a sched group based on the nature of the
15339            // broadcast as reflected by which queue it's active in.
15340            adj = ProcessList.FOREGROUND_APP_ADJ;
15341            schedGroup = (queue == mFgBroadcastQueue)
15342                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15343            app.adjType = "broadcast";
15344            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15345        } else if (app.executingServices.size() > 0) {
15346            // An app that is currently executing a service callback also
15347            // counts as being in the foreground.
15348            adj = ProcessList.FOREGROUND_APP_ADJ;
15349            schedGroup = app.execServicesFg ?
15350                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15351            app.adjType = "exec-service";
15352            procState = ActivityManager.PROCESS_STATE_SERVICE;
15353            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15354        } else {
15355            // As far as we know the process is empty.  We may change our mind later.
15356            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15357            // At this point we don't actually know the adjustment.  Use the cached adj
15358            // value that the caller wants us to.
15359            adj = cachedAdj;
15360            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15361            app.cached = true;
15362            app.empty = true;
15363            app.adjType = "cch-empty";
15364        }
15365
15366        // Examine all activities if not already foreground.
15367        if (!foregroundActivities && activitiesSize > 0) {
15368            for (int j = 0; j < activitiesSize; j++) {
15369                final ActivityRecord r = app.activities.get(j);
15370                if (r.app != app) {
15371                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15372                            + app + "?!?");
15373                    continue;
15374                }
15375                if (r.visible) {
15376                    // App has a visible activity; only upgrade adjustment.
15377                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15378                        adj = ProcessList.VISIBLE_APP_ADJ;
15379                        app.adjType = "visible";
15380                    }
15381                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15382                        procState = ActivityManager.PROCESS_STATE_TOP;
15383                    }
15384                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15385                    app.cached = false;
15386                    app.empty = false;
15387                    foregroundActivities = true;
15388                    break;
15389                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15390                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15391                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15392                        app.adjType = "pausing";
15393                    }
15394                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15395                        procState = ActivityManager.PROCESS_STATE_TOP;
15396                    }
15397                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15398                    app.cached = false;
15399                    app.empty = false;
15400                    foregroundActivities = true;
15401                } else if (r.state == ActivityState.STOPPING) {
15402                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15403                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15404                        app.adjType = "stopping";
15405                    }
15406                    // For the process state, we will at this point consider the
15407                    // process to be cached.  It will be cached either as an activity
15408                    // or empty depending on whether the activity is finishing.  We do
15409                    // this so that we can treat the process as cached for purposes of
15410                    // memory trimming (determing current memory level, trim command to
15411                    // send to process) since there can be an arbitrary number of stopping
15412                    // processes and they should soon all go into the cached state.
15413                    if (!r.finishing) {
15414                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15415                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15416                        }
15417                    }
15418                    app.cached = false;
15419                    app.empty = false;
15420                    foregroundActivities = true;
15421                } else {
15422                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15423                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15424                        app.adjType = "cch-act";
15425                    }
15426                }
15427            }
15428        }
15429
15430        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15431            if (app.foregroundServices) {
15432                // The user is aware of this app, so make it visible.
15433                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15434                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15435                app.cached = false;
15436                app.adjType = "fg-service";
15437                schedGroup = Process.THREAD_GROUP_DEFAULT;
15438            } else if (app.forcingToForeground != null) {
15439                // The user is aware of this app, so make it visible.
15440                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15441                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15442                app.cached = false;
15443                app.adjType = "force-fg";
15444                app.adjSource = app.forcingToForeground;
15445                schedGroup = Process.THREAD_GROUP_DEFAULT;
15446            }
15447        }
15448
15449        if (app == mHeavyWeightProcess) {
15450            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15451                // We don't want to kill the current heavy-weight process.
15452                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15453                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15454                app.cached = false;
15455                app.adjType = "heavy";
15456            }
15457            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15458                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15459            }
15460        }
15461
15462        if (app == mHomeProcess) {
15463            if (adj > ProcessList.HOME_APP_ADJ) {
15464                // This process is hosting what we currently consider to be the
15465                // home app, so we don't want to let it go into the background.
15466                adj = ProcessList.HOME_APP_ADJ;
15467                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15468                app.cached = false;
15469                app.adjType = "home";
15470            }
15471            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15472                procState = ActivityManager.PROCESS_STATE_HOME;
15473            }
15474        }
15475
15476        if (app == mPreviousProcess && app.activities.size() > 0) {
15477            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15478                // This was the previous process that showed UI to the user.
15479                // We want to try to keep it around more aggressively, to give
15480                // a good experience around switching between two apps.
15481                adj = ProcessList.PREVIOUS_APP_ADJ;
15482                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15483                app.cached = false;
15484                app.adjType = "previous";
15485            }
15486            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15487                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15488            }
15489        }
15490
15491        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15492                + " reason=" + app.adjType);
15493
15494        // By default, we use the computed adjustment.  It may be changed if
15495        // there are applications dependent on our services or providers, but
15496        // this gives us a baseline and makes sure we don't get into an
15497        // infinite recursion.
15498        app.adjSeq = mAdjSeq;
15499        app.curRawAdj = adj;
15500        app.hasStartedServices = false;
15501
15502        if (mBackupTarget != null && app == mBackupTarget.app) {
15503            // If possible we want to avoid killing apps while they're being backed up
15504            if (adj > ProcessList.BACKUP_APP_ADJ) {
15505                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15506                adj = ProcessList.BACKUP_APP_ADJ;
15507                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15508                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15509                }
15510                app.adjType = "backup";
15511                app.cached = false;
15512            }
15513            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15514                procState = ActivityManager.PROCESS_STATE_BACKUP;
15515            }
15516        }
15517
15518        boolean mayBeTop = false;
15519
15520        for (int is = app.services.size()-1;
15521                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15522                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15523                        || procState > ActivityManager.PROCESS_STATE_TOP);
15524                is--) {
15525            ServiceRecord s = app.services.valueAt(is);
15526            if (s.startRequested) {
15527                app.hasStartedServices = true;
15528                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15529                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15530                }
15531                if (app.hasShownUi && app != mHomeProcess) {
15532                    // If this process has shown some UI, let it immediately
15533                    // go to the LRU list because it may be pretty heavy with
15534                    // UI stuff.  We'll tag it with a label just to help
15535                    // debug and understand what is going on.
15536                    if (adj > ProcessList.SERVICE_ADJ) {
15537                        app.adjType = "cch-started-ui-services";
15538                    }
15539                } else {
15540                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15541                        // This service has seen some activity within
15542                        // recent memory, so we will keep its process ahead
15543                        // of the background processes.
15544                        if (adj > ProcessList.SERVICE_ADJ) {
15545                            adj = ProcessList.SERVICE_ADJ;
15546                            app.adjType = "started-services";
15547                            app.cached = false;
15548                        }
15549                    }
15550                    // If we have let the service slide into the background
15551                    // state, still have some text describing what it is doing
15552                    // even though the service no longer has an impact.
15553                    if (adj > ProcessList.SERVICE_ADJ) {
15554                        app.adjType = "cch-started-services";
15555                    }
15556                }
15557            }
15558            for (int conni = s.connections.size()-1;
15559                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15560                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15561                            || procState > ActivityManager.PROCESS_STATE_TOP);
15562                    conni--) {
15563                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15564                for (int i = 0;
15565                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15566                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15567                                || procState > ActivityManager.PROCESS_STATE_TOP);
15568                        i++) {
15569                    // XXX should compute this based on the max of
15570                    // all connected clients.
15571                    ConnectionRecord cr = clist.get(i);
15572                    if (cr.binding.client == app) {
15573                        // Binding to ourself is not interesting.
15574                        continue;
15575                    }
15576                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15577                        ProcessRecord client = cr.binding.client;
15578                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15579                                TOP_APP, doingAll, now);
15580                        int clientProcState = client.curProcState;
15581                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15582                            // If the other app is cached for any reason, for purposes here
15583                            // we are going to consider it empty.  The specific cached state
15584                            // doesn't propagate except under certain conditions.
15585                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15586                        }
15587                        String adjType = null;
15588                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15589                            // Not doing bind OOM management, so treat
15590                            // this guy more like a started service.
15591                            if (app.hasShownUi && app != mHomeProcess) {
15592                                // If this process has shown some UI, let it immediately
15593                                // go to the LRU list because it may be pretty heavy with
15594                                // UI stuff.  We'll tag it with a label just to help
15595                                // debug and understand what is going on.
15596                                if (adj > clientAdj) {
15597                                    adjType = "cch-bound-ui-services";
15598                                }
15599                                app.cached = false;
15600                                clientAdj = adj;
15601                                clientProcState = procState;
15602                            } else {
15603                                if (now >= (s.lastActivity
15604                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15605                                    // This service has not seen activity within
15606                                    // recent memory, so allow it to drop to the
15607                                    // LRU list if there is no other reason to keep
15608                                    // it around.  We'll also tag it with a label just
15609                                    // to help debug and undertand what is going on.
15610                                    if (adj > clientAdj) {
15611                                        adjType = "cch-bound-services";
15612                                    }
15613                                    clientAdj = adj;
15614                                }
15615                            }
15616                        }
15617                        if (adj > clientAdj) {
15618                            // If this process has recently shown UI, and
15619                            // the process that is binding to it is less
15620                            // important than being visible, then we don't
15621                            // care about the binding as much as we care
15622                            // about letting this process get into the LRU
15623                            // list to be killed and restarted if needed for
15624                            // memory.
15625                            if (app.hasShownUi && app != mHomeProcess
15626                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15627                                adjType = "cch-bound-ui-services";
15628                            } else {
15629                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15630                                        |Context.BIND_IMPORTANT)) != 0) {
15631                                    adj = clientAdj;
15632                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15633                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15634                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15635                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15636                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15637                                    adj = clientAdj;
15638                                } else {
15639                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15640                                        adj = ProcessList.VISIBLE_APP_ADJ;
15641                                    }
15642                                }
15643                                if (!client.cached) {
15644                                    app.cached = false;
15645                                }
15646                                adjType = "service";
15647                            }
15648                        }
15649                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15650                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15651                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15652                            }
15653                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15654                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15655                                    // Special handling of clients who are in the top state.
15656                                    // We *may* want to consider this process to be in the
15657                                    // top state as well, but only if there is not another
15658                                    // reason for it to be running.  Being on the top is a
15659                                    // special state, meaning you are specifically running
15660                                    // for the current top app.  If the process is already
15661                                    // running in the background for some other reason, it
15662                                    // is more important to continue considering it to be
15663                                    // in the background state.
15664                                    mayBeTop = true;
15665                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15666                                } else {
15667                                    // Special handling for above-top states (persistent
15668                                    // processes).  These should not bring the current process
15669                                    // into the top state, since they are not on top.  Instead
15670                                    // give them the best state after that.
15671                                    clientProcState =
15672                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15673                                }
15674                            }
15675                        } else {
15676                            if (clientProcState <
15677                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15678                                clientProcState =
15679                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15680                            }
15681                        }
15682                        if (procState > clientProcState) {
15683                            procState = clientProcState;
15684                        }
15685                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15686                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15687                            app.pendingUiClean = true;
15688                        }
15689                        if (adjType != null) {
15690                            app.adjType = adjType;
15691                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15692                                    .REASON_SERVICE_IN_USE;
15693                            app.adjSource = cr.binding.client;
15694                            app.adjSourceProcState = clientProcState;
15695                            app.adjTarget = s.name;
15696                        }
15697                    }
15698                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15699                        app.treatLikeActivity = true;
15700                    }
15701                    final ActivityRecord a = cr.activity;
15702                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15703                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15704                                (a.visible || a.state == ActivityState.RESUMED
15705                                 || a.state == ActivityState.PAUSING)) {
15706                            adj = ProcessList.FOREGROUND_APP_ADJ;
15707                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15708                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15709                            }
15710                            app.cached = false;
15711                            app.adjType = "service";
15712                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15713                                    .REASON_SERVICE_IN_USE;
15714                            app.adjSource = a;
15715                            app.adjSourceProcState = procState;
15716                            app.adjTarget = s.name;
15717                        }
15718                    }
15719                }
15720            }
15721        }
15722
15723        for (int provi = app.pubProviders.size()-1;
15724                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15725                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15726                        || procState > ActivityManager.PROCESS_STATE_TOP);
15727                provi--) {
15728            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15729            for (int i = cpr.connections.size()-1;
15730                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15731                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15732                            || procState > ActivityManager.PROCESS_STATE_TOP);
15733                    i--) {
15734                ContentProviderConnection conn = cpr.connections.get(i);
15735                ProcessRecord client = conn.client;
15736                if (client == app) {
15737                    // Being our own client is not interesting.
15738                    continue;
15739                }
15740                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15741                int clientProcState = client.curProcState;
15742                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15743                    // If the other app is cached for any reason, for purposes here
15744                    // we are going to consider it empty.
15745                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15746                }
15747                if (adj > clientAdj) {
15748                    if (app.hasShownUi && app != mHomeProcess
15749                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15750                        app.adjType = "cch-ui-provider";
15751                    } else {
15752                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15753                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15754                        app.adjType = "provider";
15755                    }
15756                    app.cached &= client.cached;
15757                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15758                            .REASON_PROVIDER_IN_USE;
15759                    app.adjSource = client;
15760                    app.adjSourceProcState = clientProcState;
15761                    app.adjTarget = cpr.name;
15762                }
15763                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15764                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15765                        // Special handling of clients who are in the top state.
15766                        // We *may* want to consider this process to be in the
15767                        // top state as well, but only if there is not another
15768                        // reason for it to be running.  Being on the top is a
15769                        // special state, meaning you are specifically running
15770                        // for the current top app.  If the process is already
15771                        // running in the background for some other reason, it
15772                        // is more important to continue considering it to be
15773                        // in the background state.
15774                        mayBeTop = true;
15775                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15776                    } else {
15777                        // Special handling for above-top states (persistent
15778                        // processes).  These should not bring the current process
15779                        // into the top state, since they are not on top.  Instead
15780                        // give them the best state after that.
15781                        clientProcState =
15782                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15783                    }
15784                }
15785                if (procState > clientProcState) {
15786                    procState = clientProcState;
15787                }
15788                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15789                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15790                }
15791            }
15792            // If the provider has external (non-framework) process
15793            // dependencies, ensure that its adjustment is at least
15794            // FOREGROUND_APP_ADJ.
15795            if (cpr.hasExternalProcessHandles()) {
15796                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15797                    adj = ProcessList.FOREGROUND_APP_ADJ;
15798                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15799                    app.cached = false;
15800                    app.adjType = "provider";
15801                    app.adjTarget = cpr.name;
15802                }
15803                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15804                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15805                }
15806            }
15807        }
15808
15809        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15810            // A client of one of our services or providers is in the top state.  We
15811            // *may* want to be in the top state, but not if we are already running in
15812            // the background for some other reason.  For the decision here, we are going
15813            // to pick out a few specific states that we want to remain in when a client
15814            // is top (states that tend to be longer-term) and otherwise allow it to go
15815            // to the top state.
15816            switch (procState) {
15817                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15818                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15819                case ActivityManager.PROCESS_STATE_SERVICE:
15820                    // These all are longer-term states, so pull them up to the top
15821                    // of the background states, but not all the way to the top state.
15822                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15823                    break;
15824                default:
15825                    // Otherwise, top is a better choice, so take it.
15826                    procState = ActivityManager.PROCESS_STATE_TOP;
15827                    break;
15828            }
15829        }
15830
15831        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15832            if (app.hasClientActivities) {
15833                // This is a cached process, but with client activities.  Mark it so.
15834                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15835                app.adjType = "cch-client-act";
15836            } else if (app.treatLikeActivity) {
15837                // This is a cached process, but somebody wants us to treat it like it has
15838                // an activity, okay!
15839                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15840                app.adjType = "cch-as-act";
15841            }
15842        }
15843
15844        if (adj == ProcessList.SERVICE_ADJ) {
15845            if (doingAll) {
15846                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15847                mNewNumServiceProcs++;
15848                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15849                if (!app.serviceb) {
15850                    // This service isn't far enough down on the LRU list to
15851                    // normally be a B service, but if we are low on RAM and it
15852                    // is large we want to force it down since we would prefer to
15853                    // keep launcher over it.
15854                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15855                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15856                        app.serviceHighRam = true;
15857                        app.serviceb = true;
15858                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15859                    } else {
15860                        mNewNumAServiceProcs++;
15861                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15862                    }
15863                } else {
15864                    app.serviceHighRam = false;
15865                }
15866            }
15867            if (app.serviceb) {
15868                adj = ProcessList.SERVICE_B_ADJ;
15869            }
15870        }
15871
15872        app.curRawAdj = adj;
15873
15874        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15875        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15876        if (adj > app.maxAdj) {
15877            adj = app.maxAdj;
15878            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15879                schedGroup = Process.THREAD_GROUP_DEFAULT;
15880            }
15881        }
15882
15883        // Do final modification to adj.  Everything we do between here and applying
15884        // the final setAdj must be done in this function, because we will also use
15885        // it when computing the final cached adj later.  Note that we don't need to
15886        // worry about this for max adj above, since max adj will always be used to
15887        // keep it out of the cached vaues.
15888        app.curAdj = app.modifyRawOomAdj(adj);
15889        app.curSchedGroup = schedGroup;
15890        app.curProcState = procState;
15891        app.foregroundActivities = foregroundActivities;
15892
15893        return app.curRawAdj;
15894    }
15895
15896    /**
15897     * Schedule PSS collection of a process.
15898     */
15899    void requestPssLocked(ProcessRecord proc, int procState) {
15900        if (mPendingPssProcesses.contains(proc)) {
15901            return;
15902        }
15903        if (mPendingPssProcesses.size() == 0) {
15904            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15905        }
15906        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15907        proc.pssProcState = procState;
15908        mPendingPssProcesses.add(proc);
15909    }
15910
15911    /**
15912     * Schedule PSS collection of all processes.
15913     */
15914    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15915        if (!always) {
15916            if (now < (mLastFullPssTime +
15917                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15918                return;
15919            }
15920        }
15921        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15922        mLastFullPssTime = now;
15923        mFullPssPending = true;
15924        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15925        mPendingPssProcesses.clear();
15926        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15927            ProcessRecord app = mLruProcesses.get(i);
15928            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15929                app.pssProcState = app.setProcState;
15930                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15931                        isSleeping(), now);
15932                mPendingPssProcesses.add(app);
15933            }
15934        }
15935        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15936    }
15937
15938    /**
15939     * Ask a given process to GC right now.
15940     */
15941    final void performAppGcLocked(ProcessRecord app) {
15942        try {
15943            app.lastRequestedGc = SystemClock.uptimeMillis();
15944            if (app.thread != null) {
15945                if (app.reportLowMemory) {
15946                    app.reportLowMemory = false;
15947                    app.thread.scheduleLowMemory();
15948                } else {
15949                    app.thread.processInBackground();
15950                }
15951            }
15952        } catch (Exception e) {
15953            // whatever.
15954        }
15955    }
15956
15957    /**
15958     * Returns true if things are idle enough to perform GCs.
15959     */
15960    private final boolean canGcNowLocked() {
15961        boolean processingBroadcasts = false;
15962        for (BroadcastQueue q : mBroadcastQueues) {
15963            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15964                processingBroadcasts = true;
15965            }
15966        }
15967        return !processingBroadcasts
15968                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15969    }
15970
15971    /**
15972     * Perform GCs on all processes that are waiting for it, but only
15973     * if things are idle.
15974     */
15975    final void performAppGcsLocked() {
15976        final int N = mProcessesToGc.size();
15977        if (N <= 0) {
15978            return;
15979        }
15980        if (canGcNowLocked()) {
15981            while (mProcessesToGc.size() > 0) {
15982                ProcessRecord proc = mProcessesToGc.remove(0);
15983                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15984                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15985                            <= SystemClock.uptimeMillis()) {
15986                        // To avoid spamming the system, we will GC processes one
15987                        // at a time, waiting a few seconds between each.
15988                        performAppGcLocked(proc);
15989                        scheduleAppGcsLocked();
15990                        return;
15991                    } else {
15992                        // It hasn't been long enough since we last GCed this
15993                        // process...  put it in the list to wait for its time.
15994                        addProcessToGcListLocked(proc);
15995                        break;
15996                    }
15997                }
15998            }
15999
16000            scheduleAppGcsLocked();
16001        }
16002    }
16003
16004    /**
16005     * If all looks good, perform GCs on all processes waiting for them.
16006     */
16007    final void performAppGcsIfAppropriateLocked() {
16008        if (canGcNowLocked()) {
16009            performAppGcsLocked();
16010            return;
16011        }
16012        // Still not idle, wait some more.
16013        scheduleAppGcsLocked();
16014    }
16015
16016    /**
16017     * Schedule the execution of all pending app GCs.
16018     */
16019    final void scheduleAppGcsLocked() {
16020        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16021
16022        if (mProcessesToGc.size() > 0) {
16023            // Schedule a GC for the time to the next process.
16024            ProcessRecord proc = mProcessesToGc.get(0);
16025            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16026
16027            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16028            long now = SystemClock.uptimeMillis();
16029            if (when < (now+GC_TIMEOUT)) {
16030                when = now + GC_TIMEOUT;
16031            }
16032            mHandler.sendMessageAtTime(msg, when);
16033        }
16034    }
16035
16036    /**
16037     * Add a process to the array of processes waiting to be GCed.  Keeps the
16038     * list in sorted order by the last GC time.  The process can't already be
16039     * on the list.
16040     */
16041    final void addProcessToGcListLocked(ProcessRecord proc) {
16042        boolean added = false;
16043        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16044            if (mProcessesToGc.get(i).lastRequestedGc <
16045                    proc.lastRequestedGc) {
16046                added = true;
16047                mProcessesToGc.add(i+1, proc);
16048                break;
16049            }
16050        }
16051        if (!added) {
16052            mProcessesToGc.add(0, proc);
16053        }
16054    }
16055
16056    /**
16057     * Set up to ask a process to GC itself.  This will either do it
16058     * immediately, or put it on the list of processes to gc the next
16059     * time things are idle.
16060     */
16061    final void scheduleAppGcLocked(ProcessRecord app) {
16062        long now = SystemClock.uptimeMillis();
16063        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16064            return;
16065        }
16066        if (!mProcessesToGc.contains(app)) {
16067            addProcessToGcListLocked(app);
16068            scheduleAppGcsLocked();
16069        }
16070    }
16071
16072    final void checkExcessivePowerUsageLocked(boolean doKills) {
16073        updateCpuStatsNow();
16074
16075        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16076        boolean doWakeKills = doKills;
16077        boolean doCpuKills = doKills;
16078        if (mLastPowerCheckRealtime == 0) {
16079            doWakeKills = false;
16080        }
16081        if (mLastPowerCheckUptime == 0) {
16082            doCpuKills = false;
16083        }
16084        if (stats.isScreenOn()) {
16085            doWakeKills = false;
16086        }
16087        final long curRealtime = SystemClock.elapsedRealtime();
16088        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16089        final long curUptime = SystemClock.uptimeMillis();
16090        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16091        mLastPowerCheckRealtime = curRealtime;
16092        mLastPowerCheckUptime = curUptime;
16093        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16094            doWakeKills = false;
16095        }
16096        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16097            doCpuKills = false;
16098        }
16099        int i = mLruProcesses.size();
16100        while (i > 0) {
16101            i--;
16102            ProcessRecord app = mLruProcesses.get(i);
16103            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16104                long wtime;
16105                synchronized (stats) {
16106                    wtime = stats.getProcessWakeTime(app.info.uid,
16107                            app.pid, curRealtime);
16108                }
16109                long wtimeUsed = wtime - app.lastWakeTime;
16110                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16111                if (DEBUG_POWER) {
16112                    StringBuilder sb = new StringBuilder(128);
16113                    sb.append("Wake for ");
16114                    app.toShortString(sb);
16115                    sb.append(": over ");
16116                    TimeUtils.formatDuration(realtimeSince, sb);
16117                    sb.append(" used ");
16118                    TimeUtils.formatDuration(wtimeUsed, sb);
16119                    sb.append(" (");
16120                    sb.append((wtimeUsed*100)/realtimeSince);
16121                    sb.append("%)");
16122                    Slog.i(TAG, sb.toString());
16123                    sb.setLength(0);
16124                    sb.append("CPU for ");
16125                    app.toShortString(sb);
16126                    sb.append(": over ");
16127                    TimeUtils.formatDuration(uptimeSince, sb);
16128                    sb.append(" used ");
16129                    TimeUtils.formatDuration(cputimeUsed, sb);
16130                    sb.append(" (");
16131                    sb.append((cputimeUsed*100)/uptimeSince);
16132                    sb.append("%)");
16133                    Slog.i(TAG, sb.toString());
16134                }
16135                // If a process has held a wake lock for more
16136                // than 50% of the time during this period,
16137                // that sounds bad.  Kill!
16138                if (doWakeKills && realtimeSince > 0
16139                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16140                    synchronized (stats) {
16141                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16142                                realtimeSince, wtimeUsed);
16143                    }
16144                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16145                            + " during " + realtimeSince);
16146                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16147                } else if (doCpuKills && uptimeSince > 0
16148                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16149                    synchronized (stats) {
16150                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16151                                uptimeSince, cputimeUsed);
16152                    }
16153                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16154                            + " during " + uptimeSince);
16155                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16156                } else {
16157                    app.lastWakeTime = wtime;
16158                    app.lastCpuTime = app.curCpuTime;
16159                }
16160            }
16161        }
16162    }
16163
16164    private final boolean applyOomAdjLocked(ProcessRecord app,
16165            ProcessRecord TOP_APP, boolean doingAll, long now) {
16166        boolean success = true;
16167
16168        if (app.curRawAdj != app.setRawAdj) {
16169            app.setRawAdj = app.curRawAdj;
16170        }
16171
16172        int changes = 0;
16173
16174        if (app.curAdj != app.setAdj) {
16175            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16176            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16177                TAG, "Set " + app.pid + " " + app.processName +
16178                " adj " + app.curAdj + ": " + app.adjType);
16179            app.setAdj = app.curAdj;
16180        }
16181
16182        if (app.setSchedGroup != app.curSchedGroup) {
16183            app.setSchedGroup = app.curSchedGroup;
16184            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16185                    "Setting process group of " + app.processName
16186                    + " to " + app.curSchedGroup);
16187            if (app.waitingToKill != null &&
16188                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16189                killUnneededProcessLocked(app, app.waitingToKill);
16190                success = false;
16191            } else {
16192                if (true) {
16193                    long oldId = Binder.clearCallingIdentity();
16194                    try {
16195                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16196                    } catch (Exception e) {
16197                        Slog.w(TAG, "Failed setting process group of " + app.pid
16198                                + " to " + app.curSchedGroup);
16199                        e.printStackTrace();
16200                    } finally {
16201                        Binder.restoreCallingIdentity(oldId);
16202                    }
16203                } else {
16204                    if (app.thread != null) {
16205                        try {
16206                            app.thread.setSchedulingGroup(app.curSchedGroup);
16207                        } catch (RemoteException e) {
16208                        }
16209                    }
16210                }
16211                Process.setSwappiness(app.pid,
16212                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16213            }
16214        }
16215        if (app.repForegroundActivities != app.foregroundActivities) {
16216            app.repForegroundActivities = app.foregroundActivities;
16217            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16218        }
16219        if (app.repProcState != app.curProcState) {
16220            app.repProcState = app.curProcState;
16221            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16222            if (app.thread != null) {
16223                try {
16224                    if (false) {
16225                        //RuntimeException h = new RuntimeException("here");
16226                        Slog.i(TAG, "Sending new process state " + app.repProcState
16227                                + " to " + app /*, h*/);
16228                    }
16229                    app.thread.setProcessState(app.repProcState);
16230                } catch (RemoteException e) {
16231                }
16232            }
16233        }
16234        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16235                app.setProcState)) {
16236            app.lastStateTime = now;
16237            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16238                    isSleeping(), now);
16239            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16240                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16241                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16242                    + (app.nextPssTime-now) + ": " + app);
16243        } else {
16244            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16245                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16246                requestPssLocked(app, app.setProcState);
16247                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16248                        isSleeping(), now);
16249            } else if (false && DEBUG_PSS) {
16250                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16251            }
16252        }
16253        if (app.setProcState != app.curProcState) {
16254            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16255                    "Proc state change of " + app.processName
16256                    + " to " + app.curProcState);
16257            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16258            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16259            if (setImportant && !curImportant) {
16260                // This app is no longer something we consider important enough to allow to
16261                // use arbitrary amounts of battery power.  Note
16262                // its current wake lock time to later know to kill it if
16263                // it is not behaving well.
16264                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16265                synchronized (stats) {
16266                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16267                            app.pid, SystemClock.elapsedRealtime());
16268                }
16269                app.lastCpuTime = app.curCpuTime;
16270
16271            }
16272            app.setProcState = app.curProcState;
16273            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16274                app.notCachedSinceIdle = false;
16275            }
16276            if (!doingAll) {
16277                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16278            } else {
16279                app.procStateChanged = true;
16280            }
16281        }
16282
16283        if (changes != 0) {
16284            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16285            int i = mPendingProcessChanges.size()-1;
16286            ProcessChangeItem item = null;
16287            while (i >= 0) {
16288                item = mPendingProcessChanges.get(i);
16289                if (item.pid == app.pid) {
16290                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16291                    break;
16292                }
16293                i--;
16294            }
16295            if (i < 0) {
16296                // No existing item in pending changes; need a new one.
16297                final int NA = mAvailProcessChanges.size();
16298                if (NA > 0) {
16299                    item = mAvailProcessChanges.remove(NA-1);
16300                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16301                } else {
16302                    item = new ProcessChangeItem();
16303                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16304                }
16305                item.changes = 0;
16306                item.pid = app.pid;
16307                item.uid = app.info.uid;
16308                if (mPendingProcessChanges.size() == 0) {
16309                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16310                            "*** Enqueueing dispatch processes changed!");
16311                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16312                }
16313                mPendingProcessChanges.add(item);
16314            }
16315            item.changes |= changes;
16316            item.processState = app.repProcState;
16317            item.foregroundActivities = app.repForegroundActivities;
16318            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16319                    + Integer.toHexString(System.identityHashCode(item))
16320                    + " " + app.toShortString() + ": changes=" + item.changes
16321                    + " procState=" + item.processState
16322                    + " foreground=" + item.foregroundActivities
16323                    + " type=" + app.adjType + " source=" + app.adjSource
16324                    + " target=" + app.adjTarget);
16325        }
16326
16327        return success;
16328    }
16329
16330    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16331        if (proc.thread != null) {
16332            if (proc.baseProcessTracker != null) {
16333                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16334            }
16335            if (proc.repProcState >= 0) {
16336                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16337                        proc.repProcState);
16338            }
16339        }
16340    }
16341
16342    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16343            ProcessRecord TOP_APP, boolean doingAll, long now) {
16344        if (app.thread == null) {
16345            return false;
16346        }
16347
16348        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16349
16350        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16351    }
16352
16353    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16354            boolean oomAdj) {
16355        if (isForeground != proc.foregroundServices) {
16356            proc.foregroundServices = isForeground;
16357            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16358                    proc.info.uid);
16359            if (isForeground) {
16360                if (curProcs == null) {
16361                    curProcs = new ArrayList<ProcessRecord>();
16362                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16363                }
16364                if (!curProcs.contains(proc)) {
16365                    curProcs.add(proc);
16366                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16367                            proc.info.packageName, proc.info.uid);
16368                }
16369            } else {
16370                if (curProcs != null) {
16371                    if (curProcs.remove(proc)) {
16372                        mBatteryStatsService.noteEvent(
16373                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16374                                proc.info.packageName, proc.info.uid);
16375                        if (curProcs.size() <= 0) {
16376                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16377                        }
16378                    }
16379                }
16380            }
16381            if (oomAdj) {
16382                updateOomAdjLocked();
16383            }
16384        }
16385    }
16386
16387    private final ActivityRecord resumedAppLocked() {
16388        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16389        String pkg;
16390        int uid;
16391        if (act != null) {
16392            pkg = act.packageName;
16393            uid = act.info.applicationInfo.uid;
16394        } else {
16395            pkg = null;
16396            uid = -1;
16397        }
16398        // Has the UID or resumed package name changed?
16399        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16400                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16401            if (mCurResumedPackage != null) {
16402                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16403                        mCurResumedPackage, mCurResumedUid);
16404            }
16405            mCurResumedPackage = pkg;
16406            mCurResumedUid = uid;
16407            if (mCurResumedPackage != null) {
16408                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16409                        mCurResumedPackage, mCurResumedUid);
16410            }
16411        }
16412        return act;
16413    }
16414
16415    final boolean updateOomAdjLocked(ProcessRecord app) {
16416        final ActivityRecord TOP_ACT = resumedAppLocked();
16417        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16418        final boolean wasCached = app.cached;
16419
16420        mAdjSeq++;
16421
16422        // This is the desired cached adjusment we want to tell it to use.
16423        // If our app is currently cached, we know it, and that is it.  Otherwise,
16424        // we don't know it yet, and it needs to now be cached we will then
16425        // need to do a complete oom adj.
16426        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16427                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16428        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16429                SystemClock.uptimeMillis());
16430        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16431            // Changed to/from cached state, so apps after it in the LRU
16432            // list may also be changed.
16433            updateOomAdjLocked();
16434        }
16435        return success;
16436    }
16437
16438    final void updateOomAdjLocked() {
16439        final ActivityRecord TOP_ACT = resumedAppLocked();
16440        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16441        final long now = SystemClock.uptimeMillis();
16442        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16443        final int N = mLruProcesses.size();
16444
16445        if (false) {
16446            RuntimeException e = new RuntimeException();
16447            e.fillInStackTrace();
16448            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16449        }
16450
16451        mAdjSeq++;
16452        mNewNumServiceProcs = 0;
16453        mNewNumAServiceProcs = 0;
16454
16455        final int emptyProcessLimit;
16456        final int cachedProcessLimit;
16457        if (mProcessLimit <= 0) {
16458            emptyProcessLimit = cachedProcessLimit = 0;
16459        } else if (mProcessLimit == 1) {
16460            emptyProcessLimit = 1;
16461            cachedProcessLimit = 0;
16462        } else {
16463            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16464            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16465        }
16466
16467        // Let's determine how many processes we have running vs.
16468        // how many slots we have for background processes; we may want
16469        // to put multiple processes in a slot of there are enough of
16470        // them.
16471        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16472                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16473        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16474        if (numEmptyProcs > cachedProcessLimit) {
16475            // If there are more empty processes than our limit on cached
16476            // processes, then use the cached process limit for the factor.
16477            // This ensures that the really old empty processes get pushed
16478            // down to the bottom, so if we are running low on memory we will
16479            // have a better chance at keeping around more cached processes
16480            // instead of a gazillion empty processes.
16481            numEmptyProcs = cachedProcessLimit;
16482        }
16483        int emptyFactor = numEmptyProcs/numSlots;
16484        if (emptyFactor < 1) emptyFactor = 1;
16485        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16486        if (cachedFactor < 1) cachedFactor = 1;
16487        int stepCached = 0;
16488        int stepEmpty = 0;
16489        int numCached = 0;
16490        int numEmpty = 0;
16491        int numTrimming = 0;
16492
16493        mNumNonCachedProcs = 0;
16494        mNumCachedHiddenProcs = 0;
16495
16496        // First update the OOM adjustment for each of the
16497        // application processes based on their current state.
16498        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16499        int nextCachedAdj = curCachedAdj+1;
16500        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16501        int nextEmptyAdj = curEmptyAdj+2;
16502        for (int i=N-1; i>=0; i--) {
16503            ProcessRecord app = mLruProcesses.get(i);
16504            if (!app.killedByAm && app.thread != null) {
16505                app.procStateChanged = false;
16506                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16507
16508                // If we haven't yet assigned the final cached adj
16509                // to the process, do that now.
16510                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16511                    switch (app.curProcState) {
16512                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16513                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16514                            // This process is a cached process holding activities...
16515                            // assign it the next cached value for that type, and then
16516                            // step that cached level.
16517                            app.curRawAdj = curCachedAdj;
16518                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16519                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16520                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16521                                    + ")");
16522                            if (curCachedAdj != nextCachedAdj) {
16523                                stepCached++;
16524                                if (stepCached >= cachedFactor) {
16525                                    stepCached = 0;
16526                                    curCachedAdj = nextCachedAdj;
16527                                    nextCachedAdj += 2;
16528                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16529                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16530                                    }
16531                                }
16532                            }
16533                            break;
16534                        default:
16535                            // For everything else, assign next empty cached process
16536                            // level and bump that up.  Note that this means that
16537                            // long-running services that have dropped down to the
16538                            // cached level will be treated as empty (since their process
16539                            // state is still as a service), which is what we want.
16540                            app.curRawAdj = curEmptyAdj;
16541                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16542                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16543                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16544                                    + ")");
16545                            if (curEmptyAdj != nextEmptyAdj) {
16546                                stepEmpty++;
16547                                if (stepEmpty >= emptyFactor) {
16548                                    stepEmpty = 0;
16549                                    curEmptyAdj = nextEmptyAdj;
16550                                    nextEmptyAdj += 2;
16551                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16552                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16553                                    }
16554                                }
16555                            }
16556                            break;
16557                    }
16558                }
16559
16560                applyOomAdjLocked(app, TOP_APP, true, now);
16561
16562                // Count the number of process types.
16563                switch (app.curProcState) {
16564                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16565                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16566                        mNumCachedHiddenProcs++;
16567                        numCached++;
16568                        if (numCached > cachedProcessLimit) {
16569                            killUnneededProcessLocked(app, "cached #" + numCached);
16570                        }
16571                        break;
16572                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16573                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16574                                && app.lastActivityTime < oldTime) {
16575                            killUnneededProcessLocked(app, "empty for "
16576                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16577                                    / 1000) + "s");
16578                        } else {
16579                            numEmpty++;
16580                            if (numEmpty > emptyProcessLimit) {
16581                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16582                            }
16583                        }
16584                        break;
16585                    default:
16586                        mNumNonCachedProcs++;
16587                        break;
16588                }
16589
16590                if (app.isolated && app.services.size() <= 0) {
16591                    // If this is an isolated process, and there are no
16592                    // services running in it, then the process is no longer
16593                    // needed.  We agressively kill these because we can by
16594                    // definition not re-use the same process again, and it is
16595                    // good to avoid having whatever code was running in them
16596                    // left sitting around after no longer needed.
16597                    killUnneededProcessLocked(app, "isolated not needed");
16598                }
16599
16600                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16601                        && !app.killedByAm) {
16602                    numTrimming++;
16603                }
16604            }
16605        }
16606
16607        mNumServiceProcs = mNewNumServiceProcs;
16608
16609        // Now determine the memory trimming level of background processes.
16610        // Unfortunately we need to start at the back of the list to do this
16611        // properly.  We only do this if the number of background apps we
16612        // are managing to keep around is less than half the maximum we desire;
16613        // if we are keeping a good number around, we'll let them use whatever
16614        // memory they want.
16615        final int numCachedAndEmpty = numCached + numEmpty;
16616        int memFactor;
16617        if (numCached <= ProcessList.TRIM_CACHED_APPS
16618                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16619            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16620                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16621            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16622                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16623            } else {
16624                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16625            }
16626        } else {
16627            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16628        }
16629        // We always allow the memory level to go up (better).  We only allow it to go
16630        // down if we are in a state where that is allowed, *and* the total number of processes
16631        // has gone down since last time.
16632        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16633                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16634                + " last=" + mLastNumProcesses);
16635        if (memFactor > mLastMemoryLevel) {
16636            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16637                memFactor = mLastMemoryLevel;
16638                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16639            }
16640        }
16641        mLastMemoryLevel = memFactor;
16642        mLastNumProcesses = mLruProcesses.size();
16643        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16644        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16645        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16646            if (mLowRamStartTime == 0) {
16647                mLowRamStartTime = now;
16648            }
16649            int step = 0;
16650            int fgTrimLevel;
16651            switch (memFactor) {
16652                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16653                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16654                    break;
16655                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16656                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16657                    break;
16658                default:
16659                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16660                    break;
16661            }
16662            int factor = numTrimming/3;
16663            int minFactor = 2;
16664            if (mHomeProcess != null) minFactor++;
16665            if (mPreviousProcess != null) minFactor++;
16666            if (factor < minFactor) factor = minFactor;
16667            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16668            for (int i=N-1; i>=0; i--) {
16669                ProcessRecord app = mLruProcesses.get(i);
16670                if (allChanged || app.procStateChanged) {
16671                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16672                    app.procStateChanged = false;
16673                }
16674                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16675                        && !app.killedByAm) {
16676                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16677                        try {
16678                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16679                                    "Trimming memory of " + app.processName
16680                                    + " to " + curLevel);
16681                            app.thread.scheduleTrimMemory(curLevel);
16682                        } catch (RemoteException e) {
16683                        }
16684                        if (false) {
16685                            // For now we won't do this; our memory trimming seems
16686                            // to be good enough at this point that destroying
16687                            // activities causes more harm than good.
16688                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16689                                    && app != mHomeProcess && app != mPreviousProcess) {
16690                                // Need to do this on its own message because the stack may not
16691                                // be in a consistent state at this point.
16692                                // For these apps we will also finish their activities
16693                                // to help them free memory.
16694                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16695                            }
16696                        }
16697                    }
16698                    app.trimMemoryLevel = curLevel;
16699                    step++;
16700                    if (step >= factor) {
16701                        step = 0;
16702                        switch (curLevel) {
16703                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16704                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16705                                break;
16706                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16707                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16708                                break;
16709                        }
16710                    }
16711                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16712                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16713                            && app.thread != null) {
16714                        try {
16715                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16716                                    "Trimming memory of heavy-weight " + app.processName
16717                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16718                            app.thread.scheduleTrimMemory(
16719                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16720                        } catch (RemoteException e) {
16721                        }
16722                    }
16723                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16724                } else {
16725                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16726                            || app.systemNoUi) && app.pendingUiClean) {
16727                        // If this application is now in the background and it
16728                        // had done UI, then give it the special trim level to
16729                        // have it free UI resources.
16730                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16731                        if (app.trimMemoryLevel < level && app.thread != null) {
16732                            try {
16733                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16734                                        "Trimming memory of bg-ui " + app.processName
16735                                        + " to " + level);
16736                                app.thread.scheduleTrimMemory(level);
16737                            } catch (RemoteException e) {
16738                            }
16739                        }
16740                        app.pendingUiClean = false;
16741                    }
16742                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16743                        try {
16744                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16745                                    "Trimming memory of fg " + app.processName
16746                                    + " to " + fgTrimLevel);
16747                            app.thread.scheduleTrimMemory(fgTrimLevel);
16748                        } catch (RemoteException e) {
16749                        }
16750                    }
16751                    app.trimMemoryLevel = fgTrimLevel;
16752                }
16753            }
16754        } else {
16755            if (mLowRamStartTime != 0) {
16756                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16757                mLowRamStartTime = 0;
16758            }
16759            for (int i=N-1; i>=0; i--) {
16760                ProcessRecord app = mLruProcesses.get(i);
16761                if (allChanged || app.procStateChanged) {
16762                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16763                    app.procStateChanged = false;
16764                }
16765                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16766                        || app.systemNoUi) && app.pendingUiClean) {
16767                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16768                            && app.thread != null) {
16769                        try {
16770                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16771                                    "Trimming memory of ui hidden " + app.processName
16772                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16773                            app.thread.scheduleTrimMemory(
16774                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16775                        } catch (RemoteException e) {
16776                        }
16777                    }
16778                    app.pendingUiClean = false;
16779                }
16780                app.trimMemoryLevel = 0;
16781            }
16782        }
16783
16784        if (mAlwaysFinishActivities) {
16785            // Need to do this on its own message because the stack may not
16786            // be in a consistent state at this point.
16787            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16788        }
16789
16790        if (allChanged) {
16791            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16792        }
16793
16794        if (mProcessStats.shouldWriteNowLocked(now)) {
16795            mHandler.post(new Runnable() {
16796                @Override public void run() {
16797                    synchronized (ActivityManagerService.this) {
16798                        mProcessStats.writeStateAsyncLocked();
16799                    }
16800                }
16801            });
16802        }
16803
16804        if (DEBUG_OOM_ADJ) {
16805            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16806        }
16807    }
16808
16809    final void trimApplications() {
16810        synchronized (this) {
16811            int i;
16812
16813            // First remove any unused application processes whose package
16814            // has been removed.
16815            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16816                final ProcessRecord app = mRemovedProcesses.get(i);
16817                if (app.activities.size() == 0
16818                        && app.curReceiver == null && app.services.size() == 0) {
16819                    Slog.i(
16820                        TAG, "Exiting empty application process "
16821                        + app.processName + " ("
16822                        + (app.thread != null ? app.thread.asBinder() : null)
16823                        + ")\n");
16824                    if (app.pid > 0 && app.pid != MY_PID) {
16825                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16826                                app.processName, app.setAdj, "empty");
16827                        app.killedByAm = true;
16828                        Process.killProcessQuiet(app.pid);
16829                        Process.killProcessGroup(app.info.uid, app.pid);
16830                    } else {
16831                        try {
16832                            app.thread.scheduleExit();
16833                        } catch (Exception e) {
16834                            // Ignore exceptions.
16835                        }
16836                    }
16837                    cleanUpApplicationRecordLocked(app, false, true, -1);
16838                    mRemovedProcesses.remove(i);
16839
16840                    if (app.persistent) {
16841                        addAppLocked(app.info, false, null /* ABI override */);
16842                    }
16843                }
16844            }
16845
16846            // Now update the oom adj for all processes.
16847            updateOomAdjLocked();
16848        }
16849    }
16850
16851    /** This method sends the specified signal to each of the persistent apps */
16852    public void signalPersistentProcesses(int sig) throws RemoteException {
16853        if (sig != Process.SIGNAL_USR1) {
16854            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16855        }
16856
16857        synchronized (this) {
16858            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16859                    != PackageManager.PERMISSION_GRANTED) {
16860                throw new SecurityException("Requires permission "
16861                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16862            }
16863
16864            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16865                ProcessRecord r = mLruProcesses.get(i);
16866                if (r.thread != null && r.persistent) {
16867                    Process.sendSignal(r.pid, sig);
16868                }
16869            }
16870        }
16871    }
16872
16873    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16874        if (proc == null || proc == mProfileProc) {
16875            proc = mProfileProc;
16876            path = mProfileFile;
16877            profileType = mProfileType;
16878            clearProfilerLocked();
16879        }
16880        if (proc == null) {
16881            return;
16882        }
16883        try {
16884            proc.thread.profilerControl(false, path, null, profileType);
16885        } catch (RemoteException e) {
16886            throw new IllegalStateException("Process disappeared");
16887        }
16888    }
16889
16890    private void clearProfilerLocked() {
16891        if (mProfileFd != null) {
16892            try {
16893                mProfileFd.close();
16894            } catch (IOException e) {
16895            }
16896        }
16897        mProfileApp = null;
16898        mProfileProc = null;
16899        mProfileFile = null;
16900        mProfileType = 0;
16901        mAutoStopProfiler = false;
16902    }
16903
16904    public boolean profileControl(String process, int userId, boolean start,
16905            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16906
16907        try {
16908            synchronized (this) {
16909                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16910                // its own permission.
16911                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16912                        != PackageManager.PERMISSION_GRANTED) {
16913                    throw new SecurityException("Requires permission "
16914                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16915                }
16916
16917                if (start && fd == null) {
16918                    throw new IllegalArgumentException("null fd");
16919                }
16920
16921                ProcessRecord proc = null;
16922                if (process != null) {
16923                    proc = findProcessLocked(process, userId, "profileControl");
16924                }
16925
16926                if (start && (proc == null || proc.thread == null)) {
16927                    throw new IllegalArgumentException("Unknown process: " + process);
16928                }
16929
16930                if (start) {
16931                    stopProfilerLocked(null, null, 0);
16932                    setProfileApp(proc.info, proc.processName, path, fd, false);
16933                    mProfileProc = proc;
16934                    mProfileType = profileType;
16935                    try {
16936                        fd = fd.dup();
16937                    } catch (IOException e) {
16938                        fd = null;
16939                    }
16940                    proc.thread.profilerControl(start, path, fd, profileType);
16941                    fd = null;
16942                    mProfileFd = null;
16943                } else {
16944                    stopProfilerLocked(proc, path, profileType);
16945                    if (fd != null) {
16946                        try {
16947                            fd.close();
16948                        } catch (IOException e) {
16949                        }
16950                    }
16951                }
16952
16953                return true;
16954            }
16955        } catch (RemoteException e) {
16956            throw new IllegalStateException("Process disappeared");
16957        } finally {
16958            if (fd != null) {
16959                try {
16960                    fd.close();
16961                } catch (IOException e) {
16962                }
16963            }
16964        }
16965    }
16966
16967    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16968        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16969                userId, true, ALLOW_FULL_ONLY, callName, null);
16970        ProcessRecord proc = null;
16971        try {
16972            int pid = Integer.parseInt(process);
16973            synchronized (mPidsSelfLocked) {
16974                proc = mPidsSelfLocked.get(pid);
16975            }
16976        } catch (NumberFormatException e) {
16977        }
16978
16979        if (proc == null) {
16980            ArrayMap<String, SparseArray<ProcessRecord>> all
16981                    = mProcessNames.getMap();
16982            SparseArray<ProcessRecord> procs = all.get(process);
16983            if (procs != null && procs.size() > 0) {
16984                proc = procs.valueAt(0);
16985                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16986                    for (int i=1; i<procs.size(); i++) {
16987                        ProcessRecord thisProc = procs.valueAt(i);
16988                        if (thisProc.userId == userId) {
16989                            proc = thisProc;
16990                            break;
16991                        }
16992                    }
16993                }
16994            }
16995        }
16996
16997        return proc;
16998    }
16999
17000    public boolean dumpHeap(String process, int userId, boolean managed,
17001            String path, ParcelFileDescriptor fd) throws RemoteException {
17002
17003        try {
17004            synchronized (this) {
17005                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17006                // its own permission (same as profileControl).
17007                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17008                        != PackageManager.PERMISSION_GRANTED) {
17009                    throw new SecurityException("Requires permission "
17010                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17011                }
17012
17013                if (fd == null) {
17014                    throw new IllegalArgumentException("null fd");
17015                }
17016
17017                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17018                if (proc == null || proc.thread == null) {
17019                    throw new IllegalArgumentException("Unknown process: " + process);
17020                }
17021
17022                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17023                if (!isDebuggable) {
17024                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17025                        throw new SecurityException("Process not debuggable: " + proc);
17026                    }
17027                }
17028
17029                proc.thread.dumpHeap(managed, path, fd);
17030                fd = null;
17031                return true;
17032            }
17033        } catch (RemoteException e) {
17034            throw new IllegalStateException("Process disappeared");
17035        } finally {
17036            if (fd != null) {
17037                try {
17038                    fd.close();
17039                } catch (IOException e) {
17040                }
17041            }
17042        }
17043    }
17044
17045    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17046    public void monitor() {
17047        synchronized (this) { }
17048    }
17049
17050    void onCoreSettingsChange(Bundle settings) {
17051        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17052            ProcessRecord processRecord = mLruProcesses.get(i);
17053            try {
17054                if (processRecord.thread != null) {
17055                    processRecord.thread.setCoreSettings(settings);
17056                }
17057            } catch (RemoteException re) {
17058                /* ignore */
17059            }
17060        }
17061    }
17062
17063    // Multi-user methods
17064
17065    /**
17066     * Start user, if its not already running, but don't bring it to foreground.
17067     */
17068    @Override
17069    public boolean startUserInBackground(final int userId) {
17070        return startUser(userId, /* foreground */ false);
17071    }
17072
17073    /**
17074     * Refreshes the list of users related to the current user when either a
17075     * user switch happens or when a new related user is started in the
17076     * background.
17077     */
17078    private void updateCurrentProfileIdsLocked() {
17079        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17080                mCurrentUserId, false /* enabledOnly */);
17081        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17082        for (int i = 0; i < currentProfileIds.length; i++) {
17083            currentProfileIds[i] = profiles.get(i).id;
17084        }
17085        mCurrentProfileIds = currentProfileIds;
17086
17087        synchronized (mUserProfileGroupIdsSelfLocked) {
17088            mUserProfileGroupIdsSelfLocked.clear();
17089            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17090            for (int i = 0; i < users.size(); i++) {
17091                UserInfo user = users.get(i);
17092                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17093                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17094                }
17095            }
17096        }
17097    }
17098
17099    private Set getProfileIdsLocked(int userId) {
17100        Set userIds = new HashSet<Integer>();
17101        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17102                userId, false /* enabledOnly */);
17103        for (UserInfo user : profiles) {
17104            userIds.add(Integer.valueOf(user.id));
17105        }
17106        return userIds;
17107    }
17108
17109    @Override
17110    public boolean switchUser(final int userId) {
17111        return startUser(userId, /* foregound */ true);
17112    }
17113
17114    private boolean startUser(final int userId, boolean foreground) {
17115        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17116                != PackageManager.PERMISSION_GRANTED) {
17117            String msg = "Permission Denial: switchUser() from pid="
17118                    + Binder.getCallingPid()
17119                    + ", uid=" + Binder.getCallingUid()
17120                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17121            Slog.w(TAG, msg);
17122            throw new SecurityException(msg);
17123        }
17124
17125        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17126
17127        final long ident = Binder.clearCallingIdentity();
17128        try {
17129            synchronized (this) {
17130                final int oldUserId = mCurrentUserId;
17131                if (oldUserId == userId) {
17132                    return true;
17133                }
17134
17135                mStackSupervisor.setLockTaskModeLocked(null, false);
17136
17137                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17138                if (userInfo == null) {
17139                    Slog.w(TAG, "No user info for user #" + userId);
17140                    return false;
17141                }
17142
17143                if (foreground) {
17144                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17145                            R.anim.screen_user_enter);
17146                }
17147
17148                boolean needStart = false;
17149
17150                // If the user we are switching to is not currently started, then
17151                // we need to start it now.
17152                if (mStartedUsers.get(userId) == null) {
17153                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17154                    updateStartedUserArrayLocked();
17155                    needStart = true;
17156                }
17157
17158                final Integer userIdInt = Integer.valueOf(userId);
17159                mUserLru.remove(userIdInt);
17160                mUserLru.add(userIdInt);
17161
17162                if (foreground) {
17163                    mCurrentUserId = userId;
17164                    updateCurrentProfileIdsLocked();
17165                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17166                    // Once the internal notion of the active user has switched, we lock the device
17167                    // with the option to show the user switcher on the keyguard.
17168                    mWindowManager.lockNow(null);
17169                } else {
17170                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17171                    updateCurrentProfileIdsLocked();
17172                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17173                    mUserLru.remove(currentUserIdInt);
17174                    mUserLru.add(currentUserIdInt);
17175                }
17176
17177                final UserStartedState uss = mStartedUsers.get(userId);
17178
17179                // Make sure user is in the started state.  If it is currently
17180                // stopping, we need to knock that off.
17181                if (uss.mState == UserStartedState.STATE_STOPPING) {
17182                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17183                    // so we can just fairly silently bring the user back from
17184                    // the almost-dead.
17185                    uss.mState = UserStartedState.STATE_RUNNING;
17186                    updateStartedUserArrayLocked();
17187                    needStart = true;
17188                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17189                    // This means ACTION_SHUTDOWN has been sent, so we will
17190                    // need to treat this as a new boot of the user.
17191                    uss.mState = UserStartedState.STATE_BOOTING;
17192                    updateStartedUserArrayLocked();
17193                    needStart = true;
17194                }
17195
17196                if (uss.mState == UserStartedState.STATE_BOOTING) {
17197                    // Booting up a new user, need to tell system services about it.
17198                    // Note that this is on the same handler as scheduling of broadcasts,
17199                    // which is important because it needs to go first.
17200                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17201                }
17202
17203                if (foreground) {
17204                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17205                            oldUserId));
17206                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17207                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17208                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17209                            oldUserId, userId, uss));
17210                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17211                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17212                }
17213
17214                if (needStart) {
17215                    // Send USER_STARTED broadcast
17216                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17217                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17218                            | Intent.FLAG_RECEIVER_FOREGROUND);
17219                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17220                    broadcastIntentLocked(null, null, intent,
17221                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17222                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17223                }
17224
17225                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17226                    if (userId != UserHandle.USER_OWNER) {
17227                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17228                        final ArrayList<ComponentName> doneReceivers
17229                                = new ArrayList<ComponentName>();
17230                        deliverPreBootCompleted(null, doneReceivers, userId);
17231
17232                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17233                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17234                        broadcastIntentLocked(null, null, intent, null,
17235                                new IIntentReceiver.Stub() {
17236                                    public void performReceive(Intent intent, int resultCode,
17237                                            String data, Bundle extras, boolean ordered,
17238                                            boolean sticky, int sendingUser) {
17239                                        userInitialized(uss, userId);
17240                                    }
17241                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17242                                true, false, MY_PID, Process.SYSTEM_UID,
17243                                userId);
17244                        uss.initializing = true;
17245                    } else {
17246                        getUserManagerLocked().makeInitialized(userInfo.id);
17247                    }
17248                }
17249
17250                if (foreground) {
17251                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17252                    if (homeInFront) {
17253                        startHomeActivityLocked(userId);
17254                    } else {
17255                        mStackSupervisor.resumeTopActivitiesLocked();
17256                    }
17257                    EventLogTags.writeAmSwitchUser(userId);
17258                    getUserManagerLocked().userForeground(userId);
17259                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17260                } else {
17261                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17262                }
17263
17264                if (needStart) {
17265                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17266                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17267                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17268                    broadcastIntentLocked(null, null, intent,
17269                            null, new IIntentReceiver.Stub() {
17270                                @Override
17271                                public void performReceive(Intent intent, int resultCode, String data,
17272                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17273                                        throws RemoteException {
17274                                }
17275                            }, 0, null, null,
17276                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17277                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17278                }
17279            }
17280        } finally {
17281            Binder.restoreCallingIdentity(ident);
17282        }
17283
17284        return true;
17285    }
17286
17287    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17288        long ident = Binder.clearCallingIdentity();
17289        try {
17290            Intent intent;
17291            if (oldUserId >= 0) {
17292                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17293                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17294                int count = profiles.size();
17295                for (int i = 0; i < count; i++) {
17296                    int profileUserId = profiles.get(i).id;
17297                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17298                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17299                            | Intent.FLAG_RECEIVER_FOREGROUND);
17300                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17301                    broadcastIntentLocked(null, null, intent,
17302                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17303                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17304                }
17305            }
17306            if (newUserId >= 0) {
17307                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17308                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17309                int count = profiles.size();
17310                for (int i = 0; i < count; i++) {
17311                    int profileUserId = profiles.get(i).id;
17312                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17313                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17314                            | Intent.FLAG_RECEIVER_FOREGROUND);
17315                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17316                    broadcastIntentLocked(null, null, intent,
17317                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17318                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17319                }
17320                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17321                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17322                        | Intent.FLAG_RECEIVER_FOREGROUND);
17323                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17324                broadcastIntentLocked(null, null, intent,
17325                        null, null, 0, null, null,
17326                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17327                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17328            }
17329        } finally {
17330            Binder.restoreCallingIdentity(ident);
17331        }
17332    }
17333
17334    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17335            final int newUserId) {
17336        final int N = mUserSwitchObservers.beginBroadcast();
17337        if (N > 0) {
17338            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17339                int mCount = 0;
17340                @Override
17341                public void sendResult(Bundle data) throws RemoteException {
17342                    synchronized (ActivityManagerService.this) {
17343                        if (mCurUserSwitchCallback == this) {
17344                            mCount++;
17345                            if (mCount == N) {
17346                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17347                            }
17348                        }
17349                    }
17350                }
17351            };
17352            synchronized (this) {
17353                uss.switching = true;
17354                mCurUserSwitchCallback = callback;
17355            }
17356            for (int i=0; i<N; i++) {
17357                try {
17358                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17359                            newUserId, callback);
17360                } catch (RemoteException e) {
17361                }
17362            }
17363        } else {
17364            synchronized (this) {
17365                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17366            }
17367        }
17368        mUserSwitchObservers.finishBroadcast();
17369    }
17370
17371    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17372        synchronized (this) {
17373            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17374            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17375        }
17376    }
17377
17378    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17379        mCurUserSwitchCallback = null;
17380        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17381        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17382                oldUserId, newUserId, uss));
17383    }
17384
17385    void userInitialized(UserStartedState uss, int newUserId) {
17386        completeSwitchAndInitalize(uss, newUserId, true, false);
17387    }
17388
17389    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17390        completeSwitchAndInitalize(uss, newUserId, false, true);
17391    }
17392
17393    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17394            boolean clearInitializing, boolean clearSwitching) {
17395        boolean unfrozen = false;
17396        synchronized (this) {
17397            if (clearInitializing) {
17398                uss.initializing = false;
17399                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17400            }
17401            if (clearSwitching) {
17402                uss.switching = false;
17403            }
17404            if (!uss.switching && !uss.initializing) {
17405                mWindowManager.stopFreezingScreen();
17406                unfrozen = true;
17407            }
17408        }
17409        if (unfrozen) {
17410            final int N = mUserSwitchObservers.beginBroadcast();
17411            for (int i=0; i<N; i++) {
17412                try {
17413                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17414                } catch (RemoteException e) {
17415                }
17416            }
17417            mUserSwitchObservers.finishBroadcast();
17418        }
17419    }
17420
17421    void scheduleStartProfilesLocked() {
17422        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17423            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17424                    DateUtils.SECOND_IN_MILLIS);
17425        }
17426    }
17427
17428    void startProfilesLocked() {
17429        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17430        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17431                mCurrentUserId, false /* enabledOnly */);
17432        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17433        for (UserInfo user : profiles) {
17434            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17435                    && user.id != mCurrentUserId) {
17436                toStart.add(user);
17437            }
17438        }
17439        final int n = toStart.size();
17440        int i = 0;
17441        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17442            startUserInBackground(toStart.get(i).id);
17443        }
17444        if (i < n) {
17445            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17446        }
17447    }
17448
17449    void finishUserBoot(UserStartedState uss) {
17450        synchronized (this) {
17451            if (uss.mState == UserStartedState.STATE_BOOTING
17452                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17453                uss.mState = UserStartedState.STATE_RUNNING;
17454                final int userId = uss.mHandle.getIdentifier();
17455                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17456                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17457                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17458                broadcastIntentLocked(null, null, intent,
17459                        null, null, 0, null, null,
17460                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17461                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17462            }
17463        }
17464    }
17465
17466    void finishUserSwitch(UserStartedState uss) {
17467        synchronized (this) {
17468            finishUserBoot(uss);
17469
17470            startProfilesLocked();
17471
17472            int num = mUserLru.size();
17473            int i = 0;
17474            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17475                Integer oldUserId = mUserLru.get(i);
17476                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17477                if (oldUss == null) {
17478                    // Shouldn't happen, but be sane if it does.
17479                    mUserLru.remove(i);
17480                    num--;
17481                    continue;
17482                }
17483                if (oldUss.mState == UserStartedState.STATE_STOPPING
17484                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17485                    // This user is already stopping, doesn't count.
17486                    num--;
17487                    i++;
17488                    continue;
17489                }
17490                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17491                    // Owner and current can't be stopped, but count as running.
17492                    i++;
17493                    continue;
17494                }
17495                // This is a user to be stopped.
17496                stopUserLocked(oldUserId, null);
17497                num--;
17498                i++;
17499            }
17500        }
17501    }
17502
17503    @Override
17504    public int stopUser(final int userId, final IStopUserCallback callback) {
17505        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17506                != PackageManager.PERMISSION_GRANTED) {
17507            String msg = "Permission Denial: switchUser() from pid="
17508                    + Binder.getCallingPid()
17509                    + ", uid=" + Binder.getCallingUid()
17510                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17511            Slog.w(TAG, msg);
17512            throw new SecurityException(msg);
17513        }
17514        if (userId <= 0) {
17515            throw new IllegalArgumentException("Can't stop primary user " + userId);
17516        }
17517        synchronized (this) {
17518            return stopUserLocked(userId, callback);
17519        }
17520    }
17521
17522    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17523        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17524        if (mCurrentUserId == userId) {
17525            return ActivityManager.USER_OP_IS_CURRENT;
17526        }
17527
17528        final UserStartedState uss = mStartedUsers.get(userId);
17529        if (uss == null) {
17530            // User is not started, nothing to do...  but we do need to
17531            // callback if requested.
17532            if (callback != null) {
17533                mHandler.post(new Runnable() {
17534                    @Override
17535                    public void run() {
17536                        try {
17537                            callback.userStopped(userId);
17538                        } catch (RemoteException e) {
17539                        }
17540                    }
17541                });
17542            }
17543            return ActivityManager.USER_OP_SUCCESS;
17544        }
17545
17546        if (callback != null) {
17547            uss.mStopCallbacks.add(callback);
17548        }
17549
17550        if (uss.mState != UserStartedState.STATE_STOPPING
17551                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17552            uss.mState = UserStartedState.STATE_STOPPING;
17553            updateStartedUserArrayLocked();
17554
17555            long ident = Binder.clearCallingIdentity();
17556            try {
17557                // We are going to broadcast ACTION_USER_STOPPING and then
17558                // once that is done send a final ACTION_SHUTDOWN and then
17559                // stop the user.
17560                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17561                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17562                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17563                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17564                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17565                // This is the result receiver for the final shutdown broadcast.
17566                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17567                    @Override
17568                    public void performReceive(Intent intent, int resultCode, String data,
17569                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17570                        finishUserStop(uss);
17571                    }
17572                };
17573                // This is the result receiver for the initial stopping broadcast.
17574                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17575                    @Override
17576                    public void performReceive(Intent intent, int resultCode, String data,
17577                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17578                        // On to the next.
17579                        synchronized (ActivityManagerService.this) {
17580                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17581                                // Whoops, we are being started back up.  Abort, abort!
17582                                return;
17583                            }
17584                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17585                        }
17586                        mBatteryStatsService.noteEvent(
17587                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17588                                Integer.toString(userId), userId);
17589                        mSystemServiceManager.stopUser(userId);
17590                        broadcastIntentLocked(null, null, shutdownIntent,
17591                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17592                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17593                    }
17594                };
17595                // Kick things off.
17596                broadcastIntentLocked(null, null, stoppingIntent,
17597                        null, stoppingReceiver, 0, null, null,
17598                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17599                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17600            } finally {
17601                Binder.restoreCallingIdentity(ident);
17602            }
17603        }
17604
17605        return ActivityManager.USER_OP_SUCCESS;
17606    }
17607
17608    void finishUserStop(UserStartedState uss) {
17609        final int userId = uss.mHandle.getIdentifier();
17610        boolean stopped;
17611        ArrayList<IStopUserCallback> callbacks;
17612        synchronized (this) {
17613            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17614            if (mStartedUsers.get(userId) != uss) {
17615                stopped = false;
17616            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17617                stopped = false;
17618            } else {
17619                stopped = true;
17620                // User can no longer run.
17621                mStartedUsers.remove(userId);
17622                mUserLru.remove(Integer.valueOf(userId));
17623                updateStartedUserArrayLocked();
17624
17625                // Clean up all state and processes associated with the user.
17626                // Kill all the processes for the user.
17627                forceStopUserLocked(userId, "finish user");
17628            }
17629        }
17630
17631        for (int i=0; i<callbacks.size(); i++) {
17632            try {
17633                if (stopped) callbacks.get(i).userStopped(userId);
17634                else callbacks.get(i).userStopAborted(userId);
17635            } catch (RemoteException e) {
17636            }
17637        }
17638
17639        if (stopped) {
17640            mSystemServiceManager.cleanupUser(userId);
17641            synchronized (this) {
17642                mStackSupervisor.removeUserLocked(userId);
17643            }
17644        }
17645    }
17646
17647    @Override
17648    public UserInfo getCurrentUser() {
17649        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17650                != PackageManager.PERMISSION_GRANTED) && (
17651                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17652                != PackageManager.PERMISSION_GRANTED)) {
17653            String msg = "Permission Denial: getCurrentUser() from pid="
17654                    + Binder.getCallingPid()
17655                    + ", uid=" + Binder.getCallingUid()
17656                    + " requires " + INTERACT_ACROSS_USERS;
17657            Slog.w(TAG, msg);
17658            throw new SecurityException(msg);
17659        }
17660        synchronized (this) {
17661            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17662        }
17663    }
17664
17665    int getCurrentUserIdLocked() {
17666        return mCurrentUserId;
17667    }
17668
17669    @Override
17670    public boolean isUserRunning(int userId, boolean orStopped) {
17671        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17672                != PackageManager.PERMISSION_GRANTED) {
17673            String msg = "Permission Denial: isUserRunning() from pid="
17674                    + Binder.getCallingPid()
17675                    + ", uid=" + Binder.getCallingUid()
17676                    + " requires " + INTERACT_ACROSS_USERS;
17677            Slog.w(TAG, msg);
17678            throw new SecurityException(msg);
17679        }
17680        synchronized (this) {
17681            return isUserRunningLocked(userId, orStopped);
17682        }
17683    }
17684
17685    boolean isUserRunningLocked(int userId, boolean orStopped) {
17686        UserStartedState state = mStartedUsers.get(userId);
17687        if (state == null) {
17688            return false;
17689        }
17690        if (orStopped) {
17691            return true;
17692        }
17693        return state.mState != UserStartedState.STATE_STOPPING
17694                && state.mState != UserStartedState.STATE_SHUTDOWN;
17695    }
17696
17697    @Override
17698    public int[] getRunningUserIds() {
17699        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17700                != PackageManager.PERMISSION_GRANTED) {
17701            String msg = "Permission Denial: isUserRunning() from pid="
17702                    + Binder.getCallingPid()
17703                    + ", uid=" + Binder.getCallingUid()
17704                    + " requires " + INTERACT_ACROSS_USERS;
17705            Slog.w(TAG, msg);
17706            throw new SecurityException(msg);
17707        }
17708        synchronized (this) {
17709            return mStartedUserArray;
17710        }
17711    }
17712
17713    private void updateStartedUserArrayLocked() {
17714        int num = 0;
17715        for (int i=0; i<mStartedUsers.size();  i++) {
17716            UserStartedState uss = mStartedUsers.valueAt(i);
17717            // This list does not include stopping users.
17718            if (uss.mState != UserStartedState.STATE_STOPPING
17719                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17720                num++;
17721            }
17722        }
17723        mStartedUserArray = new int[num];
17724        num = 0;
17725        for (int i=0; i<mStartedUsers.size();  i++) {
17726            UserStartedState uss = mStartedUsers.valueAt(i);
17727            if (uss.mState != UserStartedState.STATE_STOPPING
17728                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17729                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17730                num++;
17731            }
17732        }
17733    }
17734
17735    @Override
17736    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17737        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17738                != PackageManager.PERMISSION_GRANTED) {
17739            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17740                    + Binder.getCallingPid()
17741                    + ", uid=" + Binder.getCallingUid()
17742                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17743            Slog.w(TAG, msg);
17744            throw new SecurityException(msg);
17745        }
17746
17747        mUserSwitchObservers.register(observer);
17748    }
17749
17750    @Override
17751    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17752        mUserSwitchObservers.unregister(observer);
17753    }
17754
17755    private boolean userExists(int userId) {
17756        if (userId == 0) {
17757            return true;
17758        }
17759        UserManagerService ums = getUserManagerLocked();
17760        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17761    }
17762
17763    int[] getUsersLocked() {
17764        UserManagerService ums = getUserManagerLocked();
17765        return ums != null ? ums.getUserIds() : new int[] { 0 };
17766    }
17767
17768    UserManagerService getUserManagerLocked() {
17769        if (mUserManager == null) {
17770            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17771            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17772        }
17773        return mUserManager;
17774    }
17775
17776    private int applyUserId(int uid, int userId) {
17777        return UserHandle.getUid(userId, uid);
17778    }
17779
17780    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17781        if (info == null) return null;
17782        ApplicationInfo newInfo = new ApplicationInfo(info);
17783        newInfo.uid = applyUserId(info.uid, userId);
17784        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17785                + info.packageName;
17786        return newInfo;
17787    }
17788
17789    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17790        if (aInfo == null
17791                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17792            return aInfo;
17793        }
17794
17795        ActivityInfo info = new ActivityInfo(aInfo);
17796        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17797        return info;
17798    }
17799
17800    private final class LocalService extends ActivityManagerInternal {
17801        @Override
17802        public void goingToSleep() {
17803            ActivityManagerService.this.goingToSleep();
17804        }
17805
17806        @Override
17807        public void wakingUp() {
17808            ActivityManagerService.this.wakingUp();
17809        }
17810    }
17811
17812    /**
17813     * An implementation of IAppTask, that allows an app to manage its own tasks via
17814     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17815     * only the process that calls getAppTasks() can call the AppTask methods.
17816     */
17817    class AppTaskImpl extends IAppTask.Stub {
17818        private int mTaskId;
17819        private int mCallingUid;
17820
17821        public AppTaskImpl(int taskId, int callingUid) {
17822            mTaskId = taskId;
17823            mCallingUid = callingUid;
17824        }
17825
17826        @Override
17827        public void finishAndRemoveTask() {
17828            // Ensure that we are called from the same process that created this AppTask
17829            if (mCallingUid != Binder.getCallingUid()) {
17830                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17831                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17832                return;
17833            }
17834
17835            synchronized (ActivityManagerService.this) {
17836                long origId = Binder.clearCallingIdentity();
17837                try {
17838                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17839                    if (tr != null) {
17840                        // Only kill the process if we are not a new document
17841                        int flags = tr.getBaseIntent().getFlags();
17842                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17843                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17844                        removeTaskByIdLocked(mTaskId,
17845                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17846                    }
17847                } finally {
17848                    Binder.restoreCallingIdentity(origId);
17849                }
17850            }
17851        }
17852
17853        @Override
17854        public ActivityManager.RecentTaskInfo getTaskInfo() {
17855            // Ensure that we are called from the same process that created this AppTask
17856            if (mCallingUid != Binder.getCallingUid()) {
17857                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17858                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17859                return null;
17860            }
17861
17862            synchronized (ActivityManagerService.this) {
17863                long origId = Binder.clearCallingIdentity();
17864                try {
17865                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17866                    if (tr != null) {
17867                        return createRecentTaskInfoFromTaskRecord(tr);
17868                    }
17869                } finally {
17870                    Binder.restoreCallingIdentity(origId);
17871                }
17872                return null;
17873            }
17874        }
17875    }
17876}
17877