ActivityManagerService.java revision 7bd35c7e6f5e8b4085bc8ee708e67872cab9743f
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.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readBooleanAttribute;
21import static com.android.internal.util.XmlUtils.readIntAttribute;
22import static com.android.internal.util.XmlUtils.readLongAttribute;
23import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
24import static com.android.internal.util.XmlUtils.writeIntAttribute;
25import static com.android.internal.util.XmlUtils.writeLongAttribute;
26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
28import static org.xmlpull.v1.XmlPullParser.START_TAG;
29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
30
31import android.Manifest;
32import android.app.AppOpsManager;
33import android.app.IActivityContainer;
34import android.app.IActivityContainerCallback;
35import android.app.IAppTask;
36import android.app.admin.DevicePolicyManager;
37import android.appwidget.AppWidgetManager;
38import android.graphics.Rect;
39import android.os.BatteryStats;
40import android.os.PersistableBundle;
41import android.service.voice.IVoiceInteractionSession;
42import android.util.ArrayMap;
43
44import com.android.internal.R;
45import com.android.internal.annotations.GuardedBy;
46import com.android.internal.app.IAppOpsService;
47import com.android.internal.app.IVoiceInteractor;
48import com.android.internal.app.ProcessMap;
49import com.android.internal.app.ProcessStats;
50import com.android.internal.content.PackageMonitor;
51import com.android.internal.os.BackgroundThread;
52import com.android.internal.os.BatteryStatsImpl;
53import com.android.internal.os.ProcessCpuTracker;
54import com.android.internal.os.TransferPipe;
55import com.android.internal.os.Zygote;
56import com.android.internal.util.FastPrintWriter;
57import com.android.internal.util.FastXmlSerializer;
58import com.android.internal.util.MemInfoReader;
59import com.android.internal.util.Preconditions;
60import com.android.server.AppOpsService;
61import com.android.server.AttributeCache;
62import com.android.server.IntentResolver;
63import com.android.server.LocalServices;
64import com.android.server.ServiceThread;
65import com.android.server.SystemService;
66import com.android.server.SystemServiceManager;
67import com.android.server.Watchdog;
68import com.android.server.am.ActivityStack.ActivityState;
69import com.android.server.firewall.IntentFirewall;
70import com.android.server.pm.UserManagerService;
71import com.android.server.wm.AppTransition;
72import com.android.server.wm.WindowManagerService;
73import com.google.android.collect.Lists;
74import com.google.android.collect.Maps;
75
76import libcore.io.IoUtils;
77
78import org.xmlpull.v1.XmlPullParser;
79import org.xmlpull.v1.XmlPullParserException;
80import org.xmlpull.v1.XmlSerializer;
81
82import android.app.Activity;
83import android.app.ActivityManager;
84import android.app.ActivityManager.RunningTaskInfo;
85import android.app.ActivityManager.StackInfo;
86import android.app.ActivityManagerInternal;
87import android.app.ActivityManagerNative;
88import android.app.ActivityOptions;
89import android.app.ActivityThread;
90import android.app.AlertDialog;
91import android.app.AppGlobals;
92import android.app.ApplicationErrorReport;
93import android.app.Dialog;
94import android.app.IActivityController;
95import android.app.IApplicationThread;
96import android.app.IInstrumentationWatcher;
97import android.app.INotificationManager;
98import android.app.IProcessObserver;
99import android.app.IServiceConnection;
100import android.app.IStopUserCallback;
101import android.app.IUiAutomationConnection;
102import android.app.IUserSwitchObserver;
103import android.app.Instrumentation;
104import android.app.Notification;
105import android.app.NotificationManager;
106import android.app.PendingIntent;
107import android.app.backup.IBackupManager;
108import android.content.ActivityNotFoundException;
109import android.content.BroadcastReceiver;
110import android.content.ClipData;
111import android.content.ComponentCallbacks2;
112import android.content.ComponentName;
113import android.content.ContentProvider;
114import android.content.ContentResolver;
115import android.content.Context;
116import android.content.DialogInterface;
117import android.content.IContentProvider;
118import android.content.IIntentReceiver;
119import android.content.IIntentSender;
120import android.content.Intent;
121import android.content.IntentFilter;
122import android.content.IntentSender;
123import android.content.pm.ActivityInfo;
124import android.content.pm.ApplicationInfo;
125import android.content.pm.ConfigurationInfo;
126import android.content.pm.IPackageDataObserver;
127import android.content.pm.IPackageManager;
128import android.content.pm.InstrumentationInfo;
129import android.content.pm.PackageInfo;
130import android.content.pm.PackageManager;
131import android.content.pm.ParceledListSlice;
132import android.content.pm.UserInfo;
133import android.content.pm.PackageManager.NameNotFoundException;
134import android.content.pm.PathPermission;
135import android.content.pm.ProviderInfo;
136import android.content.pm.ResolveInfo;
137import android.content.pm.ServiceInfo;
138import android.content.res.CompatibilityInfo;
139import android.content.res.Configuration;
140import android.graphics.Bitmap;
141import android.net.Proxy;
142import android.net.ProxyInfo;
143import android.net.Uri;
144import android.os.Binder;
145import android.os.Build;
146import android.os.Bundle;
147import android.os.Debug;
148import android.os.DropBoxManager;
149import android.os.Environment;
150import android.os.FactoryTest;
151import android.os.FileObserver;
152import android.os.FileUtils;
153import android.os.Handler;
154import android.os.IBinder;
155import android.os.IPermissionController;
156import android.os.IRemoteCallback;
157import android.os.IUserManager;
158import android.os.Looper;
159import android.os.Message;
160import android.os.Parcel;
161import android.os.ParcelFileDescriptor;
162import android.os.Process;
163import android.os.RemoteCallbackList;
164import android.os.RemoteException;
165import android.os.SELinux;
166import android.os.ServiceManager;
167import android.os.StrictMode;
168import android.os.SystemClock;
169import android.os.SystemProperties;
170import android.os.UpdateLock;
171import android.os.UserHandle;
172import android.provider.Settings;
173import android.text.format.DateUtils;
174import android.text.format.Time;
175import android.util.AtomicFile;
176import android.util.EventLog;
177import android.util.Log;
178import android.util.Pair;
179import android.util.PrintWriterPrinter;
180import android.util.Slog;
181import android.util.SparseArray;
182import android.util.TimeUtils;
183import android.util.Xml;
184import android.view.Gravity;
185import android.view.LayoutInflater;
186import android.view.View;
187import android.view.WindowManager;
188
189import java.io.BufferedInputStream;
190import java.io.BufferedOutputStream;
191import java.io.DataInputStream;
192import java.io.DataOutputStream;
193import java.io.File;
194import java.io.FileDescriptor;
195import java.io.FileInputStream;
196import java.io.FileNotFoundException;
197import java.io.FileOutputStream;
198import java.io.IOException;
199import java.io.InputStreamReader;
200import java.io.PrintWriter;
201import java.io.StringWriter;
202import java.lang.ref.WeakReference;
203import java.util.ArrayList;
204import java.util.Arrays;
205import java.util.Collections;
206import java.util.Comparator;
207import java.util.HashMap;
208import java.util.HashSet;
209import java.util.Iterator;
210import java.util.List;
211import java.util.Locale;
212import java.util.Map;
213import java.util.Set;
214import java.util.concurrent.atomic.AtomicBoolean;
215import java.util.concurrent.atomic.AtomicLong;
216
217public final class ActivityManagerService extends ActivityManagerNative
218        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
219    private static final String USER_DATA_DIR = "/data/user/";
220    static final String TAG = "ActivityManager";
221    static final String TAG_MU = "ActivityManagerServiceMU";
222    static final boolean DEBUG = false;
223    static final boolean localLOGV = DEBUG;
224    static final boolean DEBUG_BACKUP = localLOGV || false;
225    static final boolean DEBUG_BROADCAST = localLOGV || false;
226    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
227    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_CLEANUP = localLOGV || false;
229    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
230    static final boolean DEBUG_FOCUS = false;
231    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
232    static final boolean DEBUG_MU = localLOGV || false;
233    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
234    static final boolean DEBUG_LRU = localLOGV || false;
235    static final boolean DEBUG_PAUSE = localLOGV || false;
236    static final boolean DEBUG_POWER = localLOGV || false;
237    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
238    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
239    static final boolean DEBUG_PROCESSES = localLOGV || false;
240    static final boolean DEBUG_PROVIDER = localLOGV || false;
241    static final boolean DEBUG_RESULTS = localLOGV || false;
242    static final boolean DEBUG_SERVICE = localLOGV || false;
243    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
244    static final boolean DEBUG_STACK = localLOGV || false;
245    static final boolean DEBUG_SWITCH = localLOGV || false;
246    static final boolean DEBUG_TASKS = localLOGV || false;
247    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
248    static final boolean DEBUG_TRANSITION = localLOGV || false;
249    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
250    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
251    static final boolean DEBUG_VISBILITY = localLOGV || false;
252    static final boolean DEBUG_PSS = localLOGV || false;
253    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
254    static final boolean VALIDATE_TOKENS = false;
255    static final boolean SHOW_ACTIVITY_START_TIME = true;
256
257    // Control over CPU and battery monitoring.
258    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
259    static final boolean MONITOR_CPU_USAGE = true;
260    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
261    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
262    static final boolean MONITOR_THREAD_CPU_USAGE = false;
263
264    // The flags that are set for all calls we make to the package manager.
265    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
266
267    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
268
269    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
270
271    // Maximum number of recent tasks that we can remember.
272    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
273
274    // Amount of time after a call to stopAppSwitches() during which we will
275    // prevent further untrusted switches from happening.
276    static final long APP_SWITCH_DELAY_TIME = 5*1000;
277
278    // How long we wait for a launched process to attach to the activity manager
279    // before we decide it's never going to come up for real.
280    static final int PROC_START_TIMEOUT = 10*1000;
281
282    // How long we wait for a launched process to attach to the activity manager
283    // before we decide it's never going to come up for real, when the process was
284    // started with a wrapper for instrumentation (such as Valgrind) because it
285    // could take much longer than usual.
286    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
287
288    // How long to wait after going idle before forcing apps to GC.
289    static final int GC_TIMEOUT = 5*1000;
290
291    // The minimum amount of time between successive GC requests for a process.
292    static final int GC_MIN_INTERVAL = 60*1000;
293
294    // The minimum amount of time between successive PSS requests for a process.
295    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
296
297    // The minimum amount of time between successive PSS requests for a process
298    // when the request is due to the memory state being lowered.
299    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
300
301    // The rate at which we check for apps using excessive power -- 15 mins.
302    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
303
304    // The minimum sample duration we will allow before deciding we have
305    // enough data on wake locks to start killing things.
306    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
307
308    // The minimum sample duration we will allow before deciding we have
309    // enough data on CPU usage to start killing things.
310    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
311
312    // How long we allow a receiver to run before giving up on it.
313    static final int BROADCAST_FG_TIMEOUT = 10*1000;
314    static final int BROADCAST_BG_TIMEOUT = 60*1000;
315
316    // How long we wait until we timeout on key dispatching.
317    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
318
319    // How long we wait until we timeout on key dispatching during instrumentation.
320    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
321
322    // Amount of time we wait for observers to handle a user switch before
323    // giving up on them and unfreezing the screen.
324    static final int USER_SWITCH_TIMEOUT = 2*1000;
325
326    // Maximum number of users we allow to be running at a time.
327    static final int MAX_RUNNING_USERS = 3;
328
329    // How long to wait in getAssistContextExtras for the activity and foreground services
330    // to respond with the result.
331    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
332
333    // Maximum number of persisted Uri grants a package is allowed
334    static final int MAX_PERSISTED_URI_GRANTS = 128;
335
336    static final int MY_PID = Process.myPid();
337
338    static final String[] EMPTY_STRING_ARRAY = new String[0];
339
340    // How many bytes to write into the dropbox log before truncating
341    static final int DROPBOX_MAX_SIZE = 256 * 1024;
342
343    /** All system services */
344    SystemServiceManager mSystemServiceManager;
345
346    /** Run all ActivityStacks through this */
347    ActivityStackSupervisor mStackSupervisor;
348
349    public IntentFirewall mIntentFirewall;
350
351    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
352    // default actuion automatically.  Important for devices without direct input
353    // devices.
354    private boolean mShowDialogs = true;
355
356    /**
357     * Description of a request to start a new activity, which has been held
358     * due to app switches being disabled.
359     */
360    static class PendingActivityLaunch {
361        final ActivityRecord r;
362        final ActivityRecord sourceRecord;
363        final int startFlags;
364        final ActivityStack stack;
365
366        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
367                int _startFlags, ActivityStack _stack) {
368            r = _r;
369            sourceRecord = _sourceRecord;
370            startFlags = _startFlags;
371            stack = _stack;
372        }
373    }
374
375    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
376            = new ArrayList<PendingActivityLaunch>();
377
378    BroadcastQueue mFgBroadcastQueue;
379    BroadcastQueue mBgBroadcastQueue;
380    // Convenient for easy iteration over the queues. Foreground is first
381    // so that dispatch of foreground broadcasts gets precedence.
382    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
383
384    BroadcastQueue broadcastQueueForIntent(Intent intent) {
385        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
386        if (DEBUG_BACKGROUND_BROADCAST) {
387            Slog.i(TAG, "Broadcast intent " + intent + " on "
388                    + (isFg ? "foreground" : "background")
389                    + " queue");
390        }
391        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
392    }
393
394    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
395        for (BroadcastQueue queue : mBroadcastQueues) {
396            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
397            if (r != null) {
398                return r;
399            }
400        }
401        return null;
402    }
403
404    /**
405     * Activity we have told the window manager to have key focus.
406     */
407    ActivityRecord mFocusedActivity = null;
408
409    /**
410     * List of intents that were used to start the most recent tasks.
411     */
412    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
413
414    public class PendingAssistExtras extends Binder implements Runnable {
415        public final ActivityRecord activity;
416        public boolean haveResult = false;
417        public Bundle result = null;
418        public PendingAssistExtras(ActivityRecord _activity) {
419            activity = _activity;
420        }
421        @Override
422        public void run() {
423            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
424            synchronized (this) {
425                haveResult = true;
426                notifyAll();
427            }
428        }
429    }
430
431    final ArrayList<PendingAssistExtras> mPendingAssistExtras
432            = new ArrayList<PendingAssistExtras>();
433
434    /**
435     * Process management.
436     */
437    final ProcessList mProcessList = new ProcessList();
438
439    /**
440     * All of the applications we currently have running organized by name.
441     * The keys are strings of the application package name (as
442     * returned by the package manager), and the keys are ApplicationRecord
443     * objects.
444     */
445    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
446
447    /**
448     * Tracking long-term execution of processes to look for abuse and other
449     * bad app behavior.
450     */
451    final ProcessStatsService mProcessStats;
452
453    /**
454     * The currently running isolated processes.
455     */
456    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
457
458    /**
459     * Counter for assigning isolated process uids, to avoid frequently reusing the
460     * same ones.
461     */
462    int mNextIsolatedProcessUid = 0;
463
464    /**
465     * The currently running heavy-weight process, if any.
466     */
467    ProcessRecord mHeavyWeightProcess = null;
468
469    /**
470     * The last time that various processes have crashed.
471     */
472    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
473
474    /**
475     * Information about a process that is currently marked as bad.
476     */
477    static final class BadProcessInfo {
478        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
479            this.time = time;
480            this.shortMsg = shortMsg;
481            this.longMsg = longMsg;
482            this.stack = stack;
483        }
484
485        final long time;
486        final String shortMsg;
487        final String longMsg;
488        final String stack;
489    }
490
491    /**
492     * Set of applications that we consider to be bad, and will reject
493     * incoming broadcasts from (which the user has no control over).
494     * Processes are added to this set when they have crashed twice within
495     * a minimum amount of time; they are removed from it when they are
496     * later restarted (hopefully due to some user action).  The value is the
497     * time it was added to the list.
498     */
499    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
500
501    /**
502     * All of the processes we currently have running organized by pid.
503     * The keys are the pid running the application.
504     *
505     * <p>NOTE: This object is protected by its own lock, NOT the global
506     * activity manager lock!
507     */
508    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
509
510    /**
511     * All of the processes that have been forced to be foreground.  The key
512     * is the pid of the caller who requested it (we hold a death
513     * link on it).
514     */
515    abstract class ForegroundToken implements IBinder.DeathRecipient {
516        int pid;
517        IBinder token;
518    }
519    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
520
521    /**
522     * List of records for processes that someone had tried to start before the
523     * system was ready.  We don't start them at that point, but ensure they
524     * are started by the time booting is complete.
525     */
526    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
527
528    /**
529     * List of persistent applications that are in the process
530     * of being started.
531     */
532    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
533
534    /**
535     * Processes that are being forcibly torn down.
536     */
537    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
538
539    /**
540     * List of running applications, sorted by recent usage.
541     * The first entry in the list is the least recently used.
542     */
543    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
544
545    /**
546     * Where in mLruProcesses that the processes hosting activities start.
547     */
548    int mLruProcessActivityStart = 0;
549
550    /**
551     * Where in mLruProcesses that the processes hosting services start.
552     * This is after (lower index) than mLruProcessesActivityStart.
553     */
554    int mLruProcessServiceStart = 0;
555
556    /**
557     * List of processes that should gc as soon as things are idle.
558     */
559    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
560
561    /**
562     * Processes we want to collect PSS data from.
563     */
564    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
565
566    /**
567     * Last time we requested PSS data of all processes.
568     */
569    long mLastFullPssTime = SystemClock.uptimeMillis();
570
571    /**
572     * This is the process holding what we currently consider to be
573     * the "home" activity.
574     */
575    ProcessRecord mHomeProcess;
576
577    /**
578     * This is the process holding the activity the user last visited that
579     * is in a different process from the one they are currently in.
580     */
581    ProcessRecord mPreviousProcess;
582
583    /**
584     * The time at which the previous process was last visible.
585     */
586    long mPreviousProcessVisibleTime;
587
588    /**
589     * Which uses have been started, so are allowed to run code.
590     */
591    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
592
593    /**
594     * LRU list of history of current users.  Most recently current is at the end.
595     */
596    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
597
598    /**
599     * Constant array of the users that are currently started.
600     */
601    int[] mStartedUserArray = new int[] { 0 };
602
603    /**
604     * Registered observers of the user switching mechanics.
605     */
606    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
607            = new RemoteCallbackList<IUserSwitchObserver>();
608
609    /**
610     * Currently active user switch.
611     */
612    Object mCurUserSwitchCallback;
613
614    /**
615     * Packages that the user has asked to have run in screen size
616     * compatibility mode instead of filling the screen.
617     */
618    final CompatModePackages mCompatModePackages;
619
620    /**
621     * Set of IntentSenderRecord objects that are currently active.
622     */
623    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
624            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
625
626    /**
627     * Fingerprints (hashCode()) of stack traces that we've
628     * already logged DropBox entries for.  Guarded by itself.  If
629     * something (rogue user app) forces this over
630     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
631     */
632    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
633    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
634
635    /**
636     * Strict Mode background batched logging state.
637     *
638     * The string buffer is guarded by itself, and its lock is also
639     * used to determine if another batched write is already
640     * in-flight.
641     */
642    private final StringBuilder mStrictModeBuffer = new StringBuilder();
643
644    /**
645     * Keeps track of all IIntentReceivers that have been registered for
646     * broadcasts.  Hash keys are the receiver IBinder, hash value is
647     * a ReceiverList.
648     */
649    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
650            new HashMap<IBinder, ReceiverList>();
651
652    /**
653     * Resolver for broadcast intents to registered receivers.
654     * Holds BroadcastFilter (subclass of IntentFilter).
655     */
656    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
657            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
658        @Override
659        protected boolean allowFilterResult(
660                BroadcastFilter filter, List<BroadcastFilter> dest) {
661            IBinder target = filter.receiverList.receiver.asBinder();
662            for (int i=dest.size()-1; i>=0; i--) {
663                if (dest.get(i).receiverList.receiver.asBinder() == target) {
664                    return false;
665                }
666            }
667            return true;
668        }
669
670        @Override
671        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
672            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
673                    || userId == filter.owningUserId) {
674                return super.newResult(filter, match, userId);
675            }
676            return null;
677        }
678
679        @Override
680        protected BroadcastFilter[] newArray(int size) {
681            return new BroadcastFilter[size];
682        }
683
684        @Override
685        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
686            return packageName.equals(filter.packageName);
687        }
688    };
689
690    /**
691     * State of all active sticky broadcasts per user.  Keys are the action of the
692     * sticky Intent, values are an ArrayList of all broadcasted intents with
693     * that action (which should usually be one).  The SparseArray is keyed
694     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
695     * for stickies that are sent to all users.
696     */
697    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
698            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
699
700    final ActiveServices mServices;
701
702    /**
703     * Backup/restore process management
704     */
705    String mBackupAppName = null;
706    BackupRecord mBackupTarget = null;
707
708    final ProviderMap mProviderMap;
709
710    /**
711     * List of content providers who have clients waiting for them.  The
712     * application is currently being launched and the provider will be
713     * removed from this list once it is published.
714     */
715    final ArrayList<ContentProviderRecord> mLaunchingProviders
716            = new ArrayList<ContentProviderRecord>();
717
718    /**
719     * File storing persisted {@link #mGrantedUriPermissions}.
720     */
721    private final AtomicFile mGrantFile;
722
723    /** XML constants used in {@link #mGrantFile} */
724    private static final String TAG_URI_GRANTS = "uri-grants";
725    private static final String TAG_URI_GRANT = "uri-grant";
726    private static final String ATTR_USER_HANDLE = "userHandle";
727    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
728    private static final String ATTR_TARGET_USER_ID = "targetUserId";
729    private static final String ATTR_SOURCE_PKG = "sourcePkg";
730    private static final String ATTR_TARGET_PKG = "targetPkg";
731    private static final String ATTR_URI = "uri";
732    private static final String ATTR_MODE_FLAGS = "modeFlags";
733    private static final String ATTR_CREATED_TIME = "createdTime";
734    private static final String ATTR_PREFIX = "prefix";
735
736    /**
737     * Global set of specific {@link Uri} permissions that have been granted.
738     * This optimized lookup structure maps from {@link UriPermission#targetUid}
739     * to {@link UriPermission#uri} to {@link UriPermission}.
740     */
741    @GuardedBy("this")
742    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
743            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
744
745    public static class GrantUri {
746        public final int sourceUserId;
747        public final Uri uri;
748        public boolean prefix;
749
750        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
751            this.sourceUserId = sourceUserId;
752            this.uri = uri;
753            this.prefix = prefix;
754        }
755
756        @Override
757        public int hashCode() {
758            return toString().hashCode();
759        }
760
761        @Override
762        public boolean equals(Object o) {
763            if (o instanceof GrantUri) {
764                GrantUri other = (GrantUri) o;
765                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
766                        && prefix == other.prefix;
767            }
768            return false;
769        }
770
771        @Override
772        public String toString() {
773            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
774            if (prefix) result += " [prefix]";
775            return result;
776        }
777
778        public String toSafeString() {
779            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
780            if (prefix) result += " [prefix]";
781            return result;
782        }
783
784        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
785            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
786                    ContentProvider.getUriWithoutUserId(uri), false);
787        }
788    }
789
790    CoreSettingsObserver mCoreSettingsObserver;
791
792    /**
793     * Thread-local storage used to carry caller permissions over through
794     * indirect content-provider access.
795     */
796    private class Identity {
797        public int pid;
798        public int uid;
799
800        Identity(int _pid, int _uid) {
801            pid = _pid;
802            uid = _uid;
803        }
804    }
805
806    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
807
808    /**
809     * All information we have collected about the runtime performance of
810     * any user id that can impact battery performance.
811     */
812    final BatteryStatsService mBatteryStatsService;
813
814    /**
815     * Information about component usage
816     */
817    final UsageStatsService mUsageStatsService;
818
819    /**
820     * Information about and control over application operations
821     */
822    final AppOpsService mAppOpsService;
823
824    /**
825     * Current configuration information.  HistoryRecord objects are given
826     * a reference to this object to indicate which configuration they are
827     * currently running in, so this object must be kept immutable.
828     */
829    Configuration mConfiguration = new Configuration();
830
831    /**
832     * Current sequencing integer of the configuration, for skipping old
833     * configurations.
834     */
835    int mConfigurationSeq = 0;
836
837    /**
838     * Hardware-reported OpenGLES version.
839     */
840    final int GL_ES_VERSION;
841
842    /**
843     * List of initialization arguments to pass to all processes when binding applications to them.
844     * For example, references to the commonly used services.
845     */
846    HashMap<String, IBinder> mAppBindArgs;
847
848    /**
849     * Temporary to avoid allocations.  Protected by main lock.
850     */
851    final StringBuilder mStringBuilder = new StringBuilder(256);
852
853    /**
854     * Used to control how we initialize the service.
855     */
856    ComponentName mTopComponent;
857    String mTopAction = Intent.ACTION_MAIN;
858    String mTopData;
859    boolean mProcessesReady = false;
860    boolean mSystemReady = false;
861    boolean mBooting = false;
862    boolean mWaitingUpdate = false;
863    boolean mDidUpdate = false;
864    boolean mOnBattery = false;
865    boolean mLaunchWarningShown = false;
866
867    Context mContext;
868
869    int mFactoryTest;
870
871    boolean mCheckedForSetup;
872
873    /**
874     * The time at which we will allow normal application switches again,
875     * after a call to {@link #stopAppSwitches()}.
876     */
877    long mAppSwitchesAllowedTime;
878
879    /**
880     * This is set to true after the first switch after mAppSwitchesAllowedTime
881     * is set; any switches after that will clear the time.
882     */
883    boolean mDidAppSwitch;
884
885    /**
886     * Last time (in realtime) at which we checked for power usage.
887     */
888    long mLastPowerCheckRealtime;
889
890    /**
891     * Last time (in uptime) at which we checked for power usage.
892     */
893    long mLastPowerCheckUptime;
894
895    /**
896     * Set while we are wanting to sleep, to prevent any
897     * activities from being started/resumed.
898     */
899    private boolean mSleeping = false;
900
901    /**
902     * Set while we are running a voice interaction.  This overrides
903     * sleeping while it is active.
904     */
905    private boolean mRunningVoice = false;
906
907    /**
908     * State of external calls telling us if the device is asleep.
909     */
910    private boolean mWentToSleep = false;
911
912    /**
913     * State of external call telling us if the lock screen is shown.
914     */
915    private boolean mLockScreenShown = false;
916
917    /**
918     * Set if we are shutting down the system, similar to sleeping.
919     */
920    boolean mShuttingDown = false;
921
922    /**
923     * Current sequence id for oom_adj computation traversal.
924     */
925    int mAdjSeq = 0;
926
927    /**
928     * Current sequence id for process LRU updating.
929     */
930    int mLruSeq = 0;
931
932    /**
933     * Keep track of the non-cached/empty process we last found, to help
934     * determine how to distribute cached/empty processes next time.
935     */
936    int mNumNonCachedProcs = 0;
937
938    /**
939     * Keep track of the number of cached hidden procs, to balance oom adj
940     * distribution between those and empty procs.
941     */
942    int mNumCachedHiddenProcs = 0;
943
944    /**
945     * Keep track of the number of service processes we last found, to
946     * determine on the next iteration which should be B services.
947     */
948    int mNumServiceProcs = 0;
949    int mNewNumAServiceProcs = 0;
950    int mNewNumServiceProcs = 0;
951
952    /**
953     * Allow the current computed overall memory level of the system to go down?
954     * This is set to false when we are killing processes for reasons other than
955     * memory management, so that the now smaller process list will not be taken as
956     * an indication that memory is tighter.
957     */
958    boolean mAllowLowerMemLevel = false;
959
960    /**
961     * The last computed memory level, for holding when we are in a state that
962     * processes are going away for other reasons.
963     */
964    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
965
966    /**
967     * The last total number of process we have, to determine if changes actually look
968     * like a shrinking number of process due to lower RAM.
969     */
970    int mLastNumProcesses;
971
972    /**
973     * The uptime of the last time we performed idle maintenance.
974     */
975    long mLastIdleTime = SystemClock.uptimeMillis();
976
977    /**
978     * Total time spent with RAM that has been added in the past since the last idle time.
979     */
980    long mLowRamTimeSinceLastIdle = 0;
981
982    /**
983     * If RAM is currently low, when that horrible situation started.
984     */
985    long mLowRamStartTime = 0;
986
987    /**
988     * For reporting to battery stats the current top application.
989     */
990    private String mCurResumedPackage = null;
991    private int mCurResumedUid = -1;
992
993    /**
994     * For reporting to battery stats the apps currently running foreground
995     * service.  The ProcessMap is package/uid tuples; each of these contain
996     * an array of the currently foreground processes.
997     */
998    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
999            = new ProcessMap<ArrayList<ProcessRecord>>();
1000
1001    /**
1002     * This is set if we had to do a delayed dexopt of an app before launching
1003     * it, to increase the ANR timeouts in that case.
1004     */
1005    boolean mDidDexOpt;
1006
1007    /**
1008     * Set if the systemServer made a call to enterSafeMode.
1009     */
1010    boolean mSafeMode;
1011
1012    String mDebugApp = null;
1013    boolean mWaitForDebugger = false;
1014    boolean mDebugTransient = false;
1015    String mOrigDebugApp = null;
1016    boolean mOrigWaitForDebugger = false;
1017    boolean mAlwaysFinishActivities = false;
1018    IActivityController mController = null;
1019    String mProfileApp = null;
1020    ProcessRecord mProfileProc = null;
1021    String mProfileFile;
1022    ParcelFileDescriptor mProfileFd;
1023    int mProfileType = 0;
1024    boolean mAutoStopProfiler = false;
1025    String mOpenGlTraceApp = null;
1026
1027    static class ProcessChangeItem {
1028        static final int CHANGE_ACTIVITIES = 1<<0;
1029        static final int CHANGE_PROCESS_STATE = 1<<1;
1030        int changes;
1031        int uid;
1032        int pid;
1033        int processState;
1034        boolean foregroundActivities;
1035    }
1036
1037    final RemoteCallbackList<IProcessObserver> mProcessObservers
1038            = new RemoteCallbackList<IProcessObserver>();
1039    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1040
1041    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1042            = new ArrayList<ProcessChangeItem>();
1043    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1044            = new ArrayList<ProcessChangeItem>();
1045
1046    /**
1047     * Runtime CPU use collection thread.  This object's lock is used to
1048     * protect all related state.
1049     */
1050    final Thread mProcessCpuThread;
1051
1052    /**
1053     * Used to collect process stats when showing not responding dialog.
1054     * Protected by mProcessCpuThread.
1055     */
1056    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1057            MONITOR_THREAD_CPU_USAGE);
1058    final AtomicLong mLastCpuTime = new AtomicLong(0);
1059    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1060
1061    long mLastWriteTime = 0;
1062
1063    /**
1064     * Used to retain an update lock when the foreground activity is in
1065     * immersive mode.
1066     */
1067    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1068
1069    /**
1070     * Set to true after the system has finished booting.
1071     */
1072    boolean mBooted = false;
1073
1074    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1075    int mProcessLimitOverride = -1;
1076
1077    WindowManagerService mWindowManager;
1078
1079    final ActivityThread mSystemThread;
1080
1081    int mCurrentUserId = 0;
1082    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1083    private UserManagerService mUserManager;
1084
1085    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1086        final ProcessRecord mApp;
1087        final int mPid;
1088        final IApplicationThread mAppThread;
1089
1090        AppDeathRecipient(ProcessRecord app, int pid,
1091                IApplicationThread thread) {
1092            if (localLOGV) Slog.v(
1093                TAG, "New death recipient " + this
1094                + " for thread " + thread.asBinder());
1095            mApp = app;
1096            mPid = pid;
1097            mAppThread = thread;
1098        }
1099
1100        @Override
1101        public void binderDied() {
1102            if (localLOGV) Slog.v(
1103                TAG, "Death received in " + this
1104                + " for thread " + mAppThread.asBinder());
1105            synchronized(ActivityManagerService.this) {
1106                appDiedLocked(mApp, mPid, mAppThread);
1107            }
1108        }
1109    }
1110
1111    static final int SHOW_ERROR_MSG = 1;
1112    static final int SHOW_NOT_RESPONDING_MSG = 2;
1113    static final int SHOW_FACTORY_ERROR_MSG = 3;
1114    static final int UPDATE_CONFIGURATION_MSG = 4;
1115    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1116    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1117    static final int SERVICE_TIMEOUT_MSG = 12;
1118    static final int UPDATE_TIME_ZONE = 13;
1119    static final int SHOW_UID_ERROR_MSG = 14;
1120    static final int IM_FEELING_LUCKY_MSG = 15;
1121    static final int PROC_START_TIMEOUT_MSG = 20;
1122    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1123    static final int KILL_APPLICATION_MSG = 22;
1124    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1125    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1126    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1127    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1128    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1129    static final int CLEAR_DNS_CACHE_MSG = 28;
1130    static final int UPDATE_HTTP_PROXY_MSG = 29;
1131    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1132    static final int DISPATCH_PROCESSES_CHANGED = 31;
1133    static final int DISPATCH_PROCESS_DIED = 32;
1134    static final int REPORT_MEM_USAGE_MSG = 33;
1135    static final int REPORT_USER_SWITCH_MSG = 34;
1136    static final int CONTINUE_USER_SWITCH_MSG = 35;
1137    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1138    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1139    static final int PERSIST_URI_GRANTS_MSG = 38;
1140    static final int REQUEST_ALL_PSS_MSG = 39;
1141    static final int START_PROFILES_MSG = 40;
1142    static final int UPDATE_TIME = 41;
1143    static final int SYSTEM_USER_START_MSG = 42;
1144    static final int SYSTEM_USER_CURRENT_MSG = 43;
1145
1146    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1147    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1148    static final int FIRST_COMPAT_MODE_MSG = 300;
1149    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1150
1151    AlertDialog mUidAlert;
1152    CompatModeDialog mCompatModeDialog;
1153    long mLastMemUsageReportTime = 0;
1154
1155    /**
1156     * Flag whether the current user is a "monkey", i.e. whether
1157     * the UI is driven by a UI automation tool.
1158     */
1159    private boolean mUserIsMonkey;
1160
1161    final ServiceThread mHandlerThread;
1162    final MainHandler mHandler;
1163
1164    final class MainHandler extends Handler {
1165        public MainHandler(Looper looper) {
1166            super(looper, null, true);
1167        }
1168
1169        @Override
1170        public void handleMessage(Message msg) {
1171            switch (msg.what) {
1172            case SHOW_ERROR_MSG: {
1173                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1174                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1175                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1176                synchronized (ActivityManagerService.this) {
1177                    ProcessRecord proc = (ProcessRecord)data.get("app");
1178                    AppErrorResult res = (AppErrorResult) data.get("result");
1179                    if (proc != null && proc.crashDialog != null) {
1180                        Slog.e(TAG, "App already has crash dialog: " + proc);
1181                        if (res != null) {
1182                            res.set(0);
1183                        }
1184                        return;
1185                    }
1186                    if (!showBackground && UserHandle.getAppId(proc.uid)
1187                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1188                            && proc.pid != MY_PID) {
1189                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1190                        if (res != null) {
1191                            res.set(0);
1192                        }
1193                        return;
1194                    }
1195                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1196                        Dialog d = new AppErrorDialog(mContext,
1197                                ActivityManagerService.this, res, proc);
1198                        d.show();
1199                        proc.crashDialog = d;
1200                    } else {
1201                        // The device is asleep, so just pretend that the user
1202                        // saw a crash dialog and hit "force quit".
1203                        if (res != null) {
1204                            res.set(0);
1205                        }
1206                    }
1207                }
1208
1209                ensureBootCompleted();
1210            } break;
1211            case SHOW_NOT_RESPONDING_MSG: {
1212                synchronized (ActivityManagerService.this) {
1213                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1214                    ProcessRecord proc = (ProcessRecord)data.get("app");
1215                    if (proc != null && proc.anrDialog != null) {
1216                        Slog.e(TAG, "App already has anr dialog: " + proc);
1217                        return;
1218                    }
1219
1220                    Intent intent = new Intent("android.intent.action.ANR");
1221                    if (!mProcessesReady) {
1222                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1223                                | Intent.FLAG_RECEIVER_FOREGROUND);
1224                    }
1225                    broadcastIntentLocked(null, null, intent,
1226                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1227                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1228
1229                    if (mShowDialogs) {
1230                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1231                                mContext, proc, (ActivityRecord)data.get("activity"),
1232                                msg.arg1 != 0);
1233                        d.show();
1234                        proc.anrDialog = d;
1235                    } else {
1236                        // Just kill the app if there is no dialog to be shown.
1237                        killAppAtUsersRequest(proc, null);
1238                    }
1239                }
1240
1241                ensureBootCompleted();
1242            } break;
1243            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1244                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1245                synchronized (ActivityManagerService.this) {
1246                    ProcessRecord proc = (ProcessRecord) data.get("app");
1247                    if (proc == null) {
1248                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1249                        break;
1250                    }
1251                    if (proc.crashDialog != null) {
1252                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1253                        return;
1254                    }
1255                    AppErrorResult res = (AppErrorResult) data.get("result");
1256                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1257                        Dialog d = new StrictModeViolationDialog(mContext,
1258                                ActivityManagerService.this, res, proc);
1259                        d.show();
1260                        proc.crashDialog = d;
1261                    } else {
1262                        // The device is asleep, so just pretend that the user
1263                        // saw a crash dialog and hit "force quit".
1264                        res.set(0);
1265                    }
1266                }
1267                ensureBootCompleted();
1268            } break;
1269            case SHOW_FACTORY_ERROR_MSG: {
1270                Dialog d = new FactoryErrorDialog(
1271                    mContext, msg.getData().getCharSequence("msg"));
1272                d.show();
1273                ensureBootCompleted();
1274            } break;
1275            case UPDATE_CONFIGURATION_MSG: {
1276                final ContentResolver resolver = mContext.getContentResolver();
1277                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1278            } break;
1279            case GC_BACKGROUND_PROCESSES_MSG: {
1280                synchronized (ActivityManagerService.this) {
1281                    performAppGcsIfAppropriateLocked();
1282                }
1283            } break;
1284            case WAIT_FOR_DEBUGGER_MSG: {
1285                synchronized (ActivityManagerService.this) {
1286                    ProcessRecord app = (ProcessRecord)msg.obj;
1287                    if (msg.arg1 != 0) {
1288                        if (!app.waitedForDebugger) {
1289                            Dialog d = new AppWaitingForDebuggerDialog(
1290                                    ActivityManagerService.this,
1291                                    mContext, app);
1292                            app.waitDialog = d;
1293                            app.waitedForDebugger = true;
1294                            d.show();
1295                        }
1296                    } else {
1297                        if (app.waitDialog != null) {
1298                            app.waitDialog.dismiss();
1299                            app.waitDialog = null;
1300                        }
1301                    }
1302                }
1303            } break;
1304            case SERVICE_TIMEOUT_MSG: {
1305                if (mDidDexOpt) {
1306                    mDidDexOpt = false;
1307                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1308                    nmsg.obj = msg.obj;
1309                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1310                    return;
1311                }
1312                mServices.serviceTimeout((ProcessRecord)msg.obj);
1313            } break;
1314            case UPDATE_TIME_ZONE: {
1315                synchronized (ActivityManagerService.this) {
1316                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1317                        ProcessRecord r = mLruProcesses.get(i);
1318                        if (r.thread != null) {
1319                            try {
1320                                r.thread.updateTimeZone();
1321                            } catch (RemoteException ex) {
1322                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1323                            }
1324                        }
1325                    }
1326                }
1327            } break;
1328            case CLEAR_DNS_CACHE_MSG: {
1329                synchronized (ActivityManagerService.this) {
1330                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1331                        ProcessRecord r = mLruProcesses.get(i);
1332                        if (r.thread != null) {
1333                            try {
1334                                r.thread.clearDnsCache();
1335                            } catch (RemoteException ex) {
1336                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1337                            }
1338                        }
1339                    }
1340                }
1341            } break;
1342            case UPDATE_HTTP_PROXY_MSG: {
1343                ProxyInfo proxy = (ProxyInfo)msg.obj;
1344                String host = "";
1345                String port = "";
1346                String exclList = "";
1347                Uri pacFileUrl = Uri.EMPTY;
1348                if (proxy != null) {
1349                    host = proxy.getHost();
1350                    port = Integer.toString(proxy.getPort());
1351                    exclList = proxy.getExclusionListAsString();
1352                    pacFileUrl = proxy.getPacFileUrl();
1353                }
1354                synchronized (ActivityManagerService.this) {
1355                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1356                        ProcessRecord r = mLruProcesses.get(i);
1357                        if (r.thread != null) {
1358                            try {
1359                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1360                            } catch (RemoteException ex) {
1361                                Slog.w(TAG, "Failed to update http proxy for: " +
1362                                        r.info.processName);
1363                            }
1364                        }
1365                    }
1366                }
1367            } break;
1368            case SHOW_UID_ERROR_MSG: {
1369                String title = "System UIDs Inconsistent";
1370                String text = "UIDs on the system are inconsistent, you need to wipe your"
1371                        + " data partition or your device will be unstable.";
1372                Log.e(TAG, title + ": " + text);
1373                if (mShowDialogs) {
1374                    // XXX This is a temporary dialog, no need to localize.
1375                    AlertDialog d = new BaseErrorDialog(mContext);
1376                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1377                    d.setCancelable(false);
1378                    d.setTitle(title);
1379                    d.setMessage(text);
1380                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1381                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1382                    mUidAlert = d;
1383                    d.show();
1384                }
1385            } break;
1386            case IM_FEELING_LUCKY_MSG: {
1387                if (mUidAlert != null) {
1388                    mUidAlert.dismiss();
1389                    mUidAlert = null;
1390                }
1391            } break;
1392            case PROC_START_TIMEOUT_MSG: {
1393                if (mDidDexOpt) {
1394                    mDidDexOpt = false;
1395                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1396                    nmsg.obj = msg.obj;
1397                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1398                    return;
1399                }
1400                ProcessRecord app = (ProcessRecord)msg.obj;
1401                synchronized (ActivityManagerService.this) {
1402                    processStartTimedOutLocked(app);
1403                }
1404            } break;
1405            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1406                synchronized (ActivityManagerService.this) {
1407                    doPendingActivityLaunchesLocked(true);
1408                }
1409            } break;
1410            case KILL_APPLICATION_MSG: {
1411                synchronized (ActivityManagerService.this) {
1412                    int appid = msg.arg1;
1413                    boolean restart = (msg.arg2 == 1);
1414                    Bundle bundle = (Bundle)msg.obj;
1415                    String pkg = bundle.getString("pkg");
1416                    String reason = bundle.getString("reason");
1417                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1418                            false, UserHandle.USER_ALL, reason);
1419                }
1420            } break;
1421            case FINALIZE_PENDING_INTENT_MSG: {
1422                ((PendingIntentRecord)msg.obj).completeFinalize();
1423            } break;
1424            case POST_HEAVY_NOTIFICATION_MSG: {
1425                INotificationManager inm = NotificationManager.getService();
1426                if (inm == null) {
1427                    return;
1428                }
1429
1430                ActivityRecord root = (ActivityRecord)msg.obj;
1431                ProcessRecord process = root.app;
1432                if (process == null) {
1433                    return;
1434                }
1435
1436                try {
1437                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1438                    String text = mContext.getString(R.string.heavy_weight_notification,
1439                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1440                    Notification notification = new Notification();
1441                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1442                    notification.when = 0;
1443                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1444                    notification.tickerText = text;
1445                    notification.defaults = 0; // please be quiet
1446                    notification.sound = null;
1447                    notification.vibrate = null;
1448                    notification.setLatestEventInfo(context, text,
1449                            mContext.getText(R.string.heavy_weight_notification_detail),
1450                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1451                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1452                                    new UserHandle(root.userId)));
1453
1454                    try {
1455                        int[] outId = new int[1];
1456                        inm.enqueueNotificationWithTag("android", "android", null,
1457                                R.string.heavy_weight_notification,
1458                                notification, outId, root.userId);
1459                    } catch (RuntimeException e) {
1460                        Slog.w(ActivityManagerService.TAG,
1461                                "Error showing notification for heavy-weight app", e);
1462                    } catch (RemoteException e) {
1463                    }
1464                } catch (NameNotFoundException e) {
1465                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1466                }
1467            } break;
1468            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1469                INotificationManager inm = NotificationManager.getService();
1470                if (inm == null) {
1471                    return;
1472                }
1473                try {
1474                    inm.cancelNotificationWithTag("android", null,
1475                            R.string.heavy_weight_notification,  msg.arg1);
1476                } catch (RuntimeException e) {
1477                    Slog.w(ActivityManagerService.TAG,
1478                            "Error canceling notification for service", e);
1479                } catch (RemoteException e) {
1480                }
1481            } break;
1482            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1483                synchronized (ActivityManagerService.this) {
1484                    checkExcessivePowerUsageLocked(true);
1485                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1486                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1487                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1488                }
1489            } break;
1490            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1491                synchronized (ActivityManagerService.this) {
1492                    ActivityRecord ar = (ActivityRecord)msg.obj;
1493                    if (mCompatModeDialog != null) {
1494                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1495                                ar.info.applicationInfo.packageName)) {
1496                            return;
1497                        }
1498                        mCompatModeDialog.dismiss();
1499                        mCompatModeDialog = null;
1500                    }
1501                    if (ar != null && false) {
1502                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1503                                ar.packageName)) {
1504                            int mode = mCompatModePackages.computeCompatModeLocked(
1505                                    ar.info.applicationInfo);
1506                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1507                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1508                                mCompatModeDialog = new CompatModeDialog(
1509                                        ActivityManagerService.this, mContext,
1510                                        ar.info.applicationInfo);
1511                                mCompatModeDialog.show();
1512                            }
1513                        }
1514                    }
1515                }
1516                break;
1517            }
1518            case DISPATCH_PROCESSES_CHANGED: {
1519                dispatchProcessesChanged();
1520                break;
1521            }
1522            case DISPATCH_PROCESS_DIED: {
1523                final int pid = msg.arg1;
1524                final int uid = msg.arg2;
1525                dispatchProcessDied(pid, uid);
1526                break;
1527            }
1528            case REPORT_MEM_USAGE_MSG: {
1529                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1530                Thread thread = new Thread() {
1531                    @Override public void run() {
1532                        final SparseArray<ProcessMemInfo> infoMap
1533                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1534                        for (int i=0, N=memInfos.size(); i<N; i++) {
1535                            ProcessMemInfo mi = memInfos.get(i);
1536                            infoMap.put(mi.pid, mi);
1537                        }
1538                        updateCpuStatsNow();
1539                        synchronized (mProcessCpuThread) {
1540                            final int N = mProcessCpuTracker.countStats();
1541                            for (int i=0; i<N; i++) {
1542                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1543                                if (st.vsize > 0) {
1544                                    long pss = Debug.getPss(st.pid, null);
1545                                    if (pss > 0) {
1546                                        if (infoMap.indexOfKey(st.pid) < 0) {
1547                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1548                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1549                                            mi.pss = pss;
1550                                            memInfos.add(mi);
1551                                        }
1552                                    }
1553                                }
1554                            }
1555                        }
1556
1557                        long totalPss = 0;
1558                        for (int i=0, N=memInfos.size(); i<N; i++) {
1559                            ProcessMemInfo mi = memInfos.get(i);
1560                            if (mi.pss == 0) {
1561                                mi.pss = Debug.getPss(mi.pid, null);
1562                            }
1563                            totalPss += mi.pss;
1564                        }
1565                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1566                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1567                                if (lhs.oomAdj != rhs.oomAdj) {
1568                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1569                                }
1570                                if (lhs.pss != rhs.pss) {
1571                                    return lhs.pss < rhs.pss ? 1 : -1;
1572                                }
1573                                return 0;
1574                            }
1575                        });
1576
1577                        StringBuilder tag = new StringBuilder(128);
1578                        StringBuilder stack = new StringBuilder(128);
1579                        tag.append("Low on memory -- ");
1580                        appendMemBucket(tag, totalPss, "total", false);
1581                        appendMemBucket(stack, totalPss, "total", true);
1582
1583                        StringBuilder logBuilder = new StringBuilder(1024);
1584                        logBuilder.append("Low on memory:\n");
1585
1586                        boolean firstLine = true;
1587                        int lastOomAdj = Integer.MIN_VALUE;
1588                        for (int i=0, N=memInfos.size(); i<N; i++) {
1589                            ProcessMemInfo mi = memInfos.get(i);
1590
1591                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1592                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1593                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1594                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1595                                if (lastOomAdj != mi.oomAdj) {
1596                                    lastOomAdj = mi.oomAdj;
1597                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1598                                        tag.append(" / ");
1599                                    }
1600                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1601                                        if (firstLine) {
1602                                            stack.append(":");
1603                                            firstLine = false;
1604                                        }
1605                                        stack.append("\n\t at ");
1606                                    } else {
1607                                        stack.append("$");
1608                                    }
1609                                } else {
1610                                    tag.append(" ");
1611                                    stack.append("$");
1612                                }
1613                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1614                                    appendMemBucket(tag, mi.pss, mi.name, false);
1615                                }
1616                                appendMemBucket(stack, mi.pss, mi.name, true);
1617                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1618                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1619                                    stack.append("(");
1620                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1621                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1622                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1623                                            stack.append(":");
1624                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1625                                        }
1626                                    }
1627                                    stack.append(")");
1628                                }
1629                            }
1630
1631                            logBuilder.append("  ");
1632                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1633                            logBuilder.append(' ');
1634                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1635                            logBuilder.append(' ');
1636                            ProcessList.appendRamKb(logBuilder, mi.pss);
1637                            logBuilder.append(" kB: ");
1638                            logBuilder.append(mi.name);
1639                            logBuilder.append(" (");
1640                            logBuilder.append(mi.pid);
1641                            logBuilder.append(") ");
1642                            logBuilder.append(mi.adjType);
1643                            logBuilder.append('\n');
1644                            if (mi.adjReason != null) {
1645                                logBuilder.append("                      ");
1646                                logBuilder.append(mi.adjReason);
1647                                logBuilder.append('\n');
1648                            }
1649                        }
1650
1651                        logBuilder.append("           ");
1652                        ProcessList.appendRamKb(logBuilder, totalPss);
1653                        logBuilder.append(" kB: TOTAL\n");
1654
1655                        long[] infos = new long[Debug.MEMINFO_COUNT];
1656                        Debug.getMemInfo(infos);
1657                        logBuilder.append("  MemInfo: ");
1658                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1659                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1660                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1661                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1662                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1663                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1664                            logBuilder.append("  ZRAM: ");
1665                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1666                            logBuilder.append(" kB RAM, ");
1667                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1668                            logBuilder.append(" kB swap total, ");
1669                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1670                            logBuilder.append(" kB swap free\n");
1671                        }
1672                        Slog.i(TAG, logBuilder.toString());
1673
1674                        StringBuilder dropBuilder = new StringBuilder(1024);
1675                        /*
1676                        StringWriter oomSw = new StringWriter();
1677                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1678                        StringWriter catSw = new StringWriter();
1679                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1680                        String[] emptyArgs = new String[] { };
1681                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1682                        oomPw.flush();
1683                        String oomString = oomSw.toString();
1684                        */
1685                        dropBuilder.append(stack);
1686                        dropBuilder.append('\n');
1687                        dropBuilder.append('\n');
1688                        dropBuilder.append(logBuilder);
1689                        dropBuilder.append('\n');
1690                        /*
1691                        dropBuilder.append(oomString);
1692                        dropBuilder.append('\n');
1693                        */
1694                        StringWriter catSw = new StringWriter();
1695                        synchronized (ActivityManagerService.this) {
1696                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1697                            String[] emptyArgs = new String[] { };
1698                            catPw.println();
1699                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1700                            catPw.println();
1701                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1702                                    false, false, null);
1703                            catPw.println();
1704                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1705                            catPw.flush();
1706                        }
1707                        dropBuilder.append(catSw.toString());
1708                        addErrorToDropBox("lowmem", null, "system_server", null,
1709                                null, tag.toString(), dropBuilder.toString(), null, null);
1710                        //Slog.i(TAG, "Sent to dropbox:");
1711                        //Slog.i(TAG, dropBuilder.toString());
1712                        synchronized (ActivityManagerService.this) {
1713                            long now = SystemClock.uptimeMillis();
1714                            if (mLastMemUsageReportTime < now) {
1715                                mLastMemUsageReportTime = now;
1716                            }
1717                        }
1718                    }
1719                };
1720                thread.start();
1721                break;
1722            }
1723            case REPORT_USER_SWITCH_MSG: {
1724                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1725                break;
1726            }
1727            case CONTINUE_USER_SWITCH_MSG: {
1728                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1729                break;
1730            }
1731            case USER_SWITCH_TIMEOUT_MSG: {
1732                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1733                break;
1734            }
1735            case IMMERSIVE_MODE_LOCK_MSG: {
1736                final boolean nextState = (msg.arg1 != 0);
1737                if (mUpdateLock.isHeld() != nextState) {
1738                    if (DEBUG_IMMERSIVE) {
1739                        final ActivityRecord r = (ActivityRecord) msg.obj;
1740                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1741                    }
1742                    if (nextState) {
1743                        mUpdateLock.acquire();
1744                    } else {
1745                        mUpdateLock.release();
1746                    }
1747                }
1748                break;
1749            }
1750            case PERSIST_URI_GRANTS_MSG: {
1751                writeGrantedUriPermissions();
1752                break;
1753            }
1754            case REQUEST_ALL_PSS_MSG: {
1755                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1756                break;
1757            }
1758            case START_PROFILES_MSG: {
1759                synchronized (ActivityManagerService.this) {
1760                    startProfilesLocked();
1761                }
1762                break;
1763            }
1764            case UPDATE_TIME: {
1765                synchronized (ActivityManagerService.this) {
1766                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1767                        ProcessRecord r = mLruProcesses.get(i);
1768                        if (r.thread != null) {
1769                            try {
1770                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1771                            } catch (RemoteException ex) {
1772                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1773                            }
1774                        }
1775                    }
1776                }
1777                break;
1778            }
1779            case SYSTEM_USER_START_MSG: {
1780                mSystemServiceManager.startUser(msg.arg1);
1781                break;
1782            }
1783            case SYSTEM_USER_CURRENT_MSG: {
1784                mSystemServiceManager.switchUser(msg.arg1);
1785                break;
1786            }
1787            }
1788        }
1789    };
1790
1791    static final int COLLECT_PSS_BG_MSG = 1;
1792
1793    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1794        @Override
1795        public void handleMessage(Message msg) {
1796            switch (msg.what) {
1797            case COLLECT_PSS_BG_MSG: {
1798                int i=0, num=0;
1799                long start = SystemClock.uptimeMillis();
1800                long[] tmp = new long[1];
1801                do {
1802                    ProcessRecord proc;
1803                    int procState;
1804                    int pid;
1805                    synchronized (ActivityManagerService.this) {
1806                        if (i >= mPendingPssProcesses.size()) {
1807                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1808                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1809                            mPendingPssProcesses.clear();
1810                            return;
1811                        }
1812                        proc = mPendingPssProcesses.get(i);
1813                        procState = proc.pssProcState;
1814                        if (proc.thread != null && procState == proc.setProcState) {
1815                            pid = proc.pid;
1816                        } else {
1817                            proc = null;
1818                            pid = 0;
1819                        }
1820                        i++;
1821                    }
1822                    if (proc != null) {
1823                        long pss = Debug.getPss(pid, tmp);
1824                        synchronized (ActivityManagerService.this) {
1825                            if (proc.thread != null && proc.setProcState == procState
1826                                    && proc.pid == pid) {
1827                                num++;
1828                                proc.lastPssTime = SystemClock.uptimeMillis();
1829                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1830                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1831                                        + ": " + pss + " lastPss=" + proc.lastPss
1832                                        + " state=" + ProcessList.makeProcStateString(procState));
1833                                if (proc.initialIdlePss == 0) {
1834                                    proc.initialIdlePss = pss;
1835                                }
1836                                proc.lastPss = pss;
1837                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1838                                    proc.lastCachedPss = pss;
1839                                }
1840                            }
1841                        }
1842                    }
1843                } while (true);
1844            }
1845            }
1846        }
1847    };
1848
1849    /**
1850     * Monitor for package changes and update our internal state.
1851     */
1852    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1853        @Override
1854        public void onPackageRemoved(String packageName, int uid) {
1855            // Remove all tasks with activities in the specified package from the list of recent tasks
1856            synchronized (ActivityManagerService.this) {
1857                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1858                    TaskRecord tr = mRecentTasks.get(i);
1859                    ComponentName cn = tr.intent.getComponent();
1860                    if (cn != null && cn.getPackageName().equals(packageName)) {
1861                        // If the package name matches, remove the task and kill the process
1862                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1863                    }
1864                }
1865            }
1866        }
1867
1868        @Override
1869        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1870            onPackageModified(packageName);
1871            return true;
1872        }
1873
1874        @Override
1875        public void onPackageModified(String packageName) {
1876            final PackageManager pm = mContext.getPackageManager();
1877            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1878                    new ArrayList<Pair<Intent, Integer>>();
1879            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1880            // Copy the list of recent tasks so that we don't hold onto the lock on
1881            // ActivityManagerService for long periods while checking if components exist.
1882            synchronized (ActivityManagerService.this) {
1883                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1884                    TaskRecord tr = mRecentTasks.get(i);
1885                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1886                }
1887            }
1888            // Check the recent tasks and filter out all tasks with components that no longer exist.
1889            Intent tmpI = new Intent();
1890            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1891                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1892                ComponentName cn = p.first.getComponent();
1893                if (cn != null && cn.getPackageName().equals(packageName)) {
1894                    try {
1895                        // Add the task to the list to remove if the component no longer exists
1896                        tmpI.setComponent(cn);
1897                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1898                            tasksToRemove.add(p.second);
1899                        }
1900                    } catch (Exception e) {}
1901                }
1902            }
1903            // Prune all the tasks with removed components from the list of recent tasks
1904            synchronized (ActivityManagerService.this) {
1905                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1906                    // Remove the task but don't kill the process (since other components in that
1907                    // package may still be running and in the background)
1908                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1909                }
1910            }
1911        }
1912
1913        @Override
1914        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1915            // Force stop the specified packages
1916            if (packages != null) {
1917                for (String pkg : packages) {
1918                    synchronized (ActivityManagerService.this) {
1919                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1920                                "finished booting")) {
1921                            return true;
1922                        }
1923                    }
1924                }
1925            }
1926            return false;
1927        }
1928    };
1929
1930    public void setSystemProcess() {
1931        try {
1932            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1933            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1934            ServiceManager.addService("meminfo", new MemBinder(this));
1935            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1936            ServiceManager.addService("dbinfo", new DbBinder(this));
1937            if (MONITOR_CPU_USAGE) {
1938                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1939            }
1940            ServiceManager.addService("permission", new PermissionController(this));
1941
1942            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1943                    "android", STOCK_PM_FLAGS);
1944            mSystemThread.installSystemApplicationInfo(info);
1945
1946            synchronized (this) {
1947                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1948                app.persistent = true;
1949                app.pid = MY_PID;
1950                app.maxAdj = ProcessList.SYSTEM_ADJ;
1951                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1952                mProcessNames.put(app.processName, app.uid, app);
1953                synchronized (mPidsSelfLocked) {
1954                    mPidsSelfLocked.put(app.pid, app);
1955                }
1956                updateLruProcessLocked(app, false, null);
1957                updateOomAdjLocked();
1958            }
1959        } catch (PackageManager.NameNotFoundException e) {
1960            throw new RuntimeException(
1961                    "Unable to find android system package", e);
1962        }
1963    }
1964
1965    public void setWindowManager(WindowManagerService wm) {
1966        mWindowManager = wm;
1967        mStackSupervisor.setWindowManager(wm);
1968    }
1969
1970    public void startObservingNativeCrashes() {
1971        final NativeCrashListener ncl = new NativeCrashListener(this);
1972        ncl.start();
1973    }
1974
1975    public IAppOpsService getAppOpsService() {
1976        return mAppOpsService;
1977    }
1978
1979    static class MemBinder extends Binder {
1980        ActivityManagerService mActivityManagerService;
1981        MemBinder(ActivityManagerService activityManagerService) {
1982            mActivityManagerService = activityManagerService;
1983        }
1984
1985        @Override
1986        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1987            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1988                    != PackageManager.PERMISSION_GRANTED) {
1989                pw.println("Permission Denial: can't dump meminfo from from pid="
1990                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1991                        + " without permission " + android.Manifest.permission.DUMP);
1992                return;
1993            }
1994
1995            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1996        }
1997    }
1998
1999    static class GraphicsBinder extends Binder {
2000        ActivityManagerService mActivityManagerService;
2001        GraphicsBinder(ActivityManagerService activityManagerService) {
2002            mActivityManagerService = activityManagerService;
2003        }
2004
2005        @Override
2006        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2007            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2008                    != PackageManager.PERMISSION_GRANTED) {
2009                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2010                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2011                        + " without permission " + android.Manifest.permission.DUMP);
2012                return;
2013            }
2014
2015            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2016        }
2017    }
2018
2019    static class DbBinder extends Binder {
2020        ActivityManagerService mActivityManagerService;
2021        DbBinder(ActivityManagerService activityManagerService) {
2022            mActivityManagerService = activityManagerService;
2023        }
2024
2025        @Override
2026        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2027            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2028                    != PackageManager.PERMISSION_GRANTED) {
2029                pw.println("Permission Denial: can't dump dbinfo from from pid="
2030                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2031                        + " without permission " + android.Manifest.permission.DUMP);
2032                return;
2033            }
2034
2035            mActivityManagerService.dumpDbInfo(fd, pw, args);
2036        }
2037    }
2038
2039    static class CpuBinder extends Binder {
2040        ActivityManagerService mActivityManagerService;
2041        CpuBinder(ActivityManagerService activityManagerService) {
2042            mActivityManagerService = activityManagerService;
2043        }
2044
2045        @Override
2046        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2047            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2048                    != PackageManager.PERMISSION_GRANTED) {
2049                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2050                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2051                        + " without permission " + android.Manifest.permission.DUMP);
2052                return;
2053            }
2054
2055            synchronized (mActivityManagerService.mProcessCpuThread) {
2056                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2057                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2058                        SystemClock.uptimeMillis()));
2059            }
2060        }
2061    }
2062
2063    public static final class Lifecycle extends SystemService {
2064        private final ActivityManagerService mService;
2065
2066        public Lifecycle(Context context) {
2067            super(context);
2068            mService = new ActivityManagerService(context);
2069        }
2070
2071        @Override
2072        public void onStart() {
2073            mService.start();
2074        }
2075
2076        public ActivityManagerService getService() {
2077            return mService;
2078        }
2079    }
2080
2081    // Note: This method is invoked on the main thread but may need to attach various
2082    // handlers to other threads.  So take care to be explicit about the looper.
2083    public ActivityManagerService(Context systemContext) {
2084        mContext = systemContext;
2085        mFactoryTest = FactoryTest.getMode();
2086        mSystemThread = ActivityThread.currentActivityThread();
2087
2088        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2089
2090        mHandlerThread = new ServiceThread(TAG,
2091                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2092        mHandlerThread.start();
2093        mHandler = new MainHandler(mHandlerThread.getLooper());
2094
2095        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2096                "foreground", BROADCAST_FG_TIMEOUT, false);
2097        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2098                "background", BROADCAST_BG_TIMEOUT, true);
2099        mBroadcastQueues[0] = mFgBroadcastQueue;
2100        mBroadcastQueues[1] = mBgBroadcastQueue;
2101
2102        mServices = new ActiveServices(this);
2103        mProviderMap = new ProviderMap(this);
2104
2105        // TODO: Move creation of battery stats service outside of activity manager service.
2106        File dataDir = Environment.getDataDirectory();
2107        File systemDir = new File(dataDir, "system");
2108        systemDir.mkdirs();
2109        mBatteryStatsService = new BatteryStatsService(new File(
2110                systemDir, "batterystats.bin").toString(), mHandler);
2111        mBatteryStatsService.getActiveStatistics().readLocked();
2112        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2113        mOnBattery = DEBUG_POWER ? true
2114                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2115        mBatteryStatsService.getActiveStatistics().setCallback(this);
2116
2117        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2118
2119        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2120        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2121
2122        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2123
2124        // User 0 is the first and only user that runs at boot.
2125        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2126        mUserLru.add(Integer.valueOf(0));
2127        updateStartedUserArrayLocked();
2128
2129        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2130            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2131
2132        mConfiguration.setToDefaults();
2133        mConfiguration.setLocale(Locale.getDefault());
2134
2135        mConfigurationSeq = mConfiguration.seq = 1;
2136        mProcessCpuTracker.init();
2137
2138        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2139        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2140        mStackSupervisor = new ActivityStackSupervisor(this);
2141
2142        mProcessCpuThread = new Thread("CpuTracker") {
2143            @Override
2144            public void run() {
2145                while (true) {
2146                    try {
2147                        try {
2148                            synchronized(this) {
2149                                final long now = SystemClock.uptimeMillis();
2150                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2151                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2152                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2153                                //        + ", write delay=" + nextWriteDelay);
2154                                if (nextWriteDelay < nextCpuDelay) {
2155                                    nextCpuDelay = nextWriteDelay;
2156                                }
2157                                if (nextCpuDelay > 0) {
2158                                    mProcessCpuMutexFree.set(true);
2159                                    this.wait(nextCpuDelay);
2160                                }
2161                            }
2162                        } catch (InterruptedException e) {
2163                        }
2164                        updateCpuStatsNow();
2165                    } catch (Exception e) {
2166                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2167                    }
2168                }
2169            }
2170        };
2171
2172        Watchdog.getInstance().addMonitor(this);
2173        Watchdog.getInstance().addThread(mHandler);
2174    }
2175
2176    public void setSystemServiceManager(SystemServiceManager mgr) {
2177        mSystemServiceManager = mgr;
2178    }
2179
2180    private void start() {
2181        mProcessCpuThread.start();
2182
2183        mBatteryStatsService.publish(mContext);
2184        mUsageStatsService.publish(mContext);
2185        mAppOpsService.publish(mContext);
2186
2187        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2188    }
2189
2190    @Override
2191    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2192            throws RemoteException {
2193        if (code == SYSPROPS_TRANSACTION) {
2194            // We need to tell all apps about the system property change.
2195            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2196            synchronized(this) {
2197                final int NP = mProcessNames.getMap().size();
2198                for (int ip=0; ip<NP; ip++) {
2199                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2200                    final int NA = apps.size();
2201                    for (int ia=0; ia<NA; ia++) {
2202                        ProcessRecord app = apps.valueAt(ia);
2203                        if (app.thread != null) {
2204                            procs.add(app.thread.asBinder());
2205                        }
2206                    }
2207                }
2208            }
2209
2210            int N = procs.size();
2211            for (int i=0; i<N; i++) {
2212                Parcel data2 = Parcel.obtain();
2213                try {
2214                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2215                } catch (RemoteException e) {
2216                }
2217                data2.recycle();
2218            }
2219        }
2220        try {
2221            return super.onTransact(code, data, reply, flags);
2222        } catch (RuntimeException e) {
2223            // The activity manager only throws security exceptions, so let's
2224            // log all others.
2225            if (!(e instanceof SecurityException)) {
2226                Slog.wtf(TAG, "Activity Manager Crash", e);
2227            }
2228            throw e;
2229        }
2230    }
2231
2232    void updateCpuStats() {
2233        final long now = SystemClock.uptimeMillis();
2234        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2235            return;
2236        }
2237        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2238            synchronized (mProcessCpuThread) {
2239                mProcessCpuThread.notify();
2240            }
2241        }
2242    }
2243
2244    void updateCpuStatsNow() {
2245        synchronized (mProcessCpuThread) {
2246            mProcessCpuMutexFree.set(false);
2247            final long now = SystemClock.uptimeMillis();
2248            boolean haveNewCpuStats = false;
2249
2250            if (MONITOR_CPU_USAGE &&
2251                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2252                mLastCpuTime.set(now);
2253                haveNewCpuStats = true;
2254                mProcessCpuTracker.update();
2255                //Slog.i(TAG, mProcessCpu.printCurrentState());
2256                //Slog.i(TAG, "Total CPU usage: "
2257                //        + mProcessCpu.getTotalCpuPercent() + "%");
2258
2259                // Slog the cpu usage if the property is set.
2260                if ("true".equals(SystemProperties.get("events.cpu"))) {
2261                    int user = mProcessCpuTracker.getLastUserTime();
2262                    int system = mProcessCpuTracker.getLastSystemTime();
2263                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2264                    int irq = mProcessCpuTracker.getLastIrqTime();
2265                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2266                    int idle = mProcessCpuTracker.getLastIdleTime();
2267
2268                    int total = user + system + iowait + irq + softIrq + idle;
2269                    if (total == 0) total = 1;
2270
2271                    EventLog.writeEvent(EventLogTags.CPU,
2272                            ((user+system+iowait+irq+softIrq) * 100) / total,
2273                            (user * 100) / total,
2274                            (system * 100) / total,
2275                            (iowait * 100) / total,
2276                            (irq * 100) / total,
2277                            (softIrq * 100) / total);
2278                }
2279            }
2280
2281            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2282            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2283            synchronized(bstats) {
2284                synchronized(mPidsSelfLocked) {
2285                    if (haveNewCpuStats) {
2286                        if (mOnBattery) {
2287                            int perc = bstats.startAddingCpuLocked();
2288                            int totalUTime = 0;
2289                            int totalSTime = 0;
2290                            final int N = mProcessCpuTracker.countStats();
2291                            for (int i=0; i<N; i++) {
2292                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2293                                if (!st.working) {
2294                                    continue;
2295                                }
2296                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2297                                int otherUTime = (st.rel_utime*perc)/100;
2298                                int otherSTime = (st.rel_stime*perc)/100;
2299                                totalUTime += otherUTime;
2300                                totalSTime += otherSTime;
2301                                if (pr != null) {
2302                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2303                                    if (ps == null || !ps.isActive()) {
2304                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2305                                                pr.info.uid, pr.processName);
2306                                    }
2307                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2308                                            st.rel_stime-otherSTime);
2309                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2310                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2311                                } else {
2312                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2313                                    if (ps == null || !ps.isActive()) {
2314                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2315                                                bstats.mapUid(st.uid), st.name);
2316                                    }
2317                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2318                                            st.rel_stime-otherSTime);
2319                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2320                                }
2321                            }
2322                            bstats.finishAddingCpuLocked(perc, totalUTime,
2323                                    totalSTime, cpuSpeedTimes);
2324                        }
2325                    }
2326                }
2327
2328                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2329                    mLastWriteTime = now;
2330                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2331                }
2332            }
2333        }
2334    }
2335
2336    @Override
2337    public void batteryNeedsCpuUpdate() {
2338        updateCpuStatsNow();
2339    }
2340
2341    @Override
2342    public void batteryPowerChanged(boolean onBattery) {
2343        // When plugging in, update the CPU stats first before changing
2344        // the plug state.
2345        updateCpuStatsNow();
2346        synchronized (this) {
2347            synchronized(mPidsSelfLocked) {
2348                mOnBattery = DEBUG_POWER ? true : onBattery;
2349            }
2350        }
2351    }
2352
2353    /**
2354     * Initialize the application bind args. These are passed to each
2355     * process when the bindApplication() IPC is sent to the process. They're
2356     * lazily setup to make sure the services are running when they're asked for.
2357     */
2358    private HashMap<String, IBinder> getCommonServicesLocked() {
2359        if (mAppBindArgs == null) {
2360            mAppBindArgs = new HashMap<String, IBinder>();
2361
2362            // Setup the application init args
2363            mAppBindArgs.put("package", ServiceManager.getService("package"));
2364            mAppBindArgs.put("window", ServiceManager.getService("window"));
2365            mAppBindArgs.put(Context.ALARM_SERVICE,
2366                    ServiceManager.getService(Context.ALARM_SERVICE));
2367        }
2368        return mAppBindArgs;
2369    }
2370
2371    final void setFocusedActivityLocked(ActivityRecord r) {
2372        if (mFocusedActivity != r) {
2373            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2374            mFocusedActivity = r;
2375            if (r.task != null && r.task.voiceInteractor != null) {
2376                startRunningVoiceLocked();
2377            } else {
2378                finishRunningVoiceLocked();
2379            }
2380            mStackSupervisor.setFocusedStack(r);
2381            if (r != null) {
2382                mWindowManager.setFocusedApp(r.appToken, true);
2383            }
2384            applyUpdateLockStateLocked(r);
2385        }
2386    }
2387
2388    final void clearFocusedActivity(ActivityRecord r) {
2389        if (mFocusedActivity == r) {
2390            mFocusedActivity = null;
2391        }
2392    }
2393
2394    @Override
2395    public void setFocusedStack(int stackId) {
2396        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2397        synchronized (ActivityManagerService.this) {
2398            ActivityStack stack = mStackSupervisor.getStack(stackId);
2399            if (stack != null) {
2400                ActivityRecord r = stack.topRunningActivityLocked(null);
2401                if (r != null) {
2402                    setFocusedActivityLocked(r);
2403                }
2404            }
2405        }
2406    }
2407
2408    @Override
2409    public void notifyActivityDrawn(IBinder token) {
2410        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2411        synchronized (this) {
2412            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2413            if (r != null) {
2414                r.task.stack.notifyActivityDrawnLocked(r);
2415            }
2416        }
2417    }
2418
2419    final void applyUpdateLockStateLocked(ActivityRecord r) {
2420        // Modifications to the UpdateLock state are done on our handler, outside
2421        // the activity manager's locks.  The new state is determined based on the
2422        // state *now* of the relevant activity record.  The object is passed to
2423        // the handler solely for logging detail, not to be consulted/modified.
2424        final boolean nextState = r != null && r.immersive;
2425        mHandler.sendMessage(
2426                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2427    }
2428
2429    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2430        Message msg = Message.obtain();
2431        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2432        msg.obj = r.task.askedCompatMode ? null : r;
2433        mHandler.sendMessage(msg);
2434    }
2435
2436    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2437            String what, Object obj, ProcessRecord srcApp) {
2438        app.lastActivityTime = now;
2439
2440        if (app.activities.size() > 0) {
2441            // Don't want to touch dependent processes that are hosting activities.
2442            return index;
2443        }
2444
2445        int lrui = mLruProcesses.lastIndexOf(app);
2446        if (lrui < 0) {
2447            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2448                    + what + " " + obj + " from " + srcApp);
2449            return index;
2450        }
2451
2452        if (lrui >= index) {
2453            // Don't want to cause this to move dependent processes *back* in the
2454            // list as if they were less frequently used.
2455            return index;
2456        }
2457
2458        if (lrui >= mLruProcessActivityStart) {
2459            // Don't want to touch dependent processes that are hosting activities.
2460            return index;
2461        }
2462
2463        mLruProcesses.remove(lrui);
2464        if (index > 0) {
2465            index--;
2466        }
2467        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2468                + " in LRU list: " + app);
2469        mLruProcesses.add(index, app);
2470        return index;
2471    }
2472
2473    final void removeLruProcessLocked(ProcessRecord app) {
2474        int lrui = mLruProcesses.lastIndexOf(app);
2475        if (lrui >= 0) {
2476            if (lrui <= mLruProcessActivityStart) {
2477                mLruProcessActivityStart--;
2478            }
2479            if (lrui <= mLruProcessServiceStart) {
2480                mLruProcessServiceStart--;
2481            }
2482            mLruProcesses.remove(lrui);
2483        }
2484    }
2485
2486    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2487            ProcessRecord client) {
2488        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2489                || app.treatLikeActivity;
2490        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2491        if (!activityChange && hasActivity) {
2492            // The process has activities, so we are only allowing activity-based adjustments
2493            // to move it.  It should be kept in the front of the list with other
2494            // processes that have activities, and we don't want those to change their
2495            // order except due to activity operations.
2496            return;
2497        }
2498
2499        mLruSeq++;
2500        final long now = SystemClock.uptimeMillis();
2501        app.lastActivityTime = now;
2502
2503        // First a quick reject: if the app is already at the position we will
2504        // put it, then there is nothing to do.
2505        if (hasActivity) {
2506            final int N = mLruProcesses.size();
2507            if (N > 0 && mLruProcesses.get(N-1) == app) {
2508                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2509                return;
2510            }
2511        } else {
2512            if (mLruProcessServiceStart > 0
2513                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2514                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2515                return;
2516            }
2517        }
2518
2519        int lrui = mLruProcesses.lastIndexOf(app);
2520
2521        if (app.persistent && lrui >= 0) {
2522            // We don't care about the position of persistent processes, as long as
2523            // they are in the list.
2524            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2525            return;
2526        }
2527
2528        /* In progress: compute new position first, so we can avoid doing work
2529           if the process is not actually going to move.  Not yet working.
2530        int addIndex;
2531        int nextIndex;
2532        boolean inActivity = false, inService = false;
2533        if (hasActivity) {
2534            // Process has activities, put it at the very tipsy-top.
2535            addIndex = mLruProcesses.size();
2536            nextIndex = mLruProcessServiceStart;
2537            inActivity = true;
2538        } else if (hasService) {
2539            // Process has services, put it at the top of the service list.
2540            addIndex = mLruProcessActivityStart;
2541            nextIndex = mLruProcessServiceStart;
2542            inActivity = true;
2543            inService = true;
2544        } else  {
2545            // Process not otherwise of interest, it goes to the top of the non-service area.
2546            addIndex = mLruProcessServiceStart;
2547            if (client != null) {
2548                int clientIndex = mLruProcesses.lastIndexOf(client);
2549                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2550                        + app);
2551                if (clientIndex >= 0 && addIndex > clientIndex) {
2552                    addIndex = clientIndex;
2553                }
2554            }
2555            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2556        }
2557
2558        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2559                + mLruProcessActivityStart + "): " + app);
2560        */
2561
2562        if (lrui >= 0) {
2563            if (lrui < mLruProcessActivityStart) {
2564                mLruProcessActivityStart--;
2565            }
2566            if (lrui < mLruProcessServiceStart) {
2567                mLruProcessServiceStart--;
2568            }
2569            /*
2570            if (addIndex > lrui) {
2571                addIndex--;
2572            }
2573            if (nextIndex > lrui) {
2574                nextIndex--;
2575            }
2576            */
2577            mLruProcesses.remove(lrui);
2578        }
2579
2580        /*
2581        mLruProcesses.add(addIndex, app);
2582        if (inActivity) {
2583            mLruProcessActivityStart++;
2584        }
2585        if (inService) {
2586            mLruProcessActivityStart++;
2587        }
2588        */
2589
2590        int nextIndex;
2591        if (hasActivity) {
2592            final int N = mLruProcesses.size();
2593            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2594                // Process doesn't have activities, but has clients with
2595                // activities...  move it up, but one below the top (the top
2596                // should always have a real activity).
2597                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2598                mLruProcesses.add(N-1, app);
2599                // To keep it from spamming the LRU list (by making a bunch of clients),
2600                // we will push down any other entries owned by the app.
2601                final int uid = app.info.uid;
2602                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2603                    ProcessRecord subProc = mLruProcesses.get(i);
2604                    if (subProc.info.uid == uid) {
2605                        // We want to push this one down the list.  If the process after
2606                        // it is for the same uid, however, don't do so, because we don't
2607                        // want them internally to be re-ordered.
2608                        if (mLruProcesses.get(i-1).info.uid != uid) {
2609                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2610                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2611                            ProcessRecord tmp = mLruProcesses.get(i);
2612                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2613                            mLruProcesses.set(i-1, tmp);
2614                            i--;
2615                        }
2616                    } else {
2617                        // A gap, we can stop here.
2618                        break;
2619                    }
2620                }
2621            } else {
2622                // Process has activities, put it at the very tipsy-top.
2623                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2624                mLruProcesses.add(app);
2625            }
2626            nextIndex = mLruProcessServiceStart;
2627        } else if (hasService) {
2628            // Process has services, put it at the top of the service list.
2629            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2630            mLruProcesses.add(mLruProcessActivityStart, app);
2631            nextIndex = mLruProcessServiceStart;
2632            mLruProcessActivityStart++;
2633        } else  {
2634            // Process not otherwise of interest, it goes to the top of the non-service area.
2635            int index = mLruProcessServiceStart;
2636            if (client != null) {
2637                // If there is a client, don't allow the process to be moved up higher
2638                // in the list than that client.
2639                int clientIndex = mLruProcesses.lastIndexOf(client);
2640                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2641                        + " when updating " + app);
2642                if (clientIndex <= lrui) {
2643                    // Don't allow the client index restriction to push it down farther in the
2644                    // list than it already is.
2645                    clientIndex = lrui;
2646                }
2647                if (clientIndex >= 0 && index > clientIndex) {
2648                    index = clientIndex;
2649                }
2650            }
2651            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2652            mLruProcesses.add(index, app);
2653            nextIndex = index-1;
2654            mLruProcessActivityStart++;
2655            mLruProcessServiceStart++;
2656        }
2657
2658        // If the app is currently using a content provider or service,
2659        // bump those processes as well.
2660        for (int j=app.connections.size()-1; j>=0; j--) {
2661            ConnectionRecord cr = app.connections.valueAt(j);
2662            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2663                    && cr.binding.service.app != null
2664                    && cr.binding.service.app.lruSeq != mLruSeq
2665                    && !cr.binding.service.app.persistent) {
2666                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2667                        "service connection", cr, app);
2668            }
2669        }
2670        for (int j=app.conProviders.size()-1; j>=0; j--) {
2671            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2672            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2673                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2674                        "provider reference", cpr, app);
2675            }
2676        }
2677    }
2678
2679    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2680        if (uid == Process.SYSTEM_UID) {
2681            // The system gets to run in any process.  If there are multiple
2682            // processes with the same uid, just pick the first (this
2683            // should never happen).
2684            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2685            if (procs == null) return null;
2686            final int N = procs.size();
2687            for (int i = 0; i < N; i++) {
2688                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2689            }
2690        }
2691        ProcessRecord proc = mProcessNames.get(processName, uid);
2692        if (false && proc != null && !keepIfLarge
2693                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2694                && proc.lastCachedPss >= 4000) {
2695            // Turn this condition on to cause killing to happen regularly, for testing.
2696            if (proc.baseProcessTracker != null) {
2697                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2698            }
2699            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2700                    + "k from cached");
2701        } else if (proc != null && !keepIfLarge
2702                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2703                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2704            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2705            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2706                if (proc.baseProcessTracker != null) {
2707                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2708                }
2709                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2710                        + "k from cached");
2711            }
2712        }
2713        return proc;
2714    }
2715
2716    void ensurePackageDexOpt(String packageName) {
2717        IPackageManager pm = AppGlobals.getPackageManager();
2718        try {
2719            if (pm.performDexOpt(packageName)) {
2720                mDidDexOpt = true;
2721            }
2722        } catch (RemoteException e) {
2723        }
2724    }
2725
2726    boolean isNextTransitionForward() {
2727        int transit = mWindowManager.getPendingAppTransition();
2728        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2729                || transit == AppTransition.TRANSIT_TASK_OPEN
2730                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2731    }
2732
2733    final ProcessRecord startProcessLocked(String processName,
2734            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2735            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2736            boolean isolated, boolean keepIfLarge) {
2737        ProcessRecord app;
2738        if (!isolated) {
2739            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2740        } else {
2741            // If this is an isolated process, it can't re-use an existing process.
2742            app = null;
2743        }
2744        // We don't have to do anything more if:
2745        // (1) There is an existing application record; and
2746        // (2) The caller doesn't think it is dead, OR there is no thread
2747        //     object attached to it so we know it couldn't have crashed; and
2748        // (3) There is a pid assigned to it, so it is either starting or
2749        //     already running.
2750        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2751                + " app=" + app + " knownToBeDead=" + knownToBeDead
2752                + " thread=" + (app != null ? app.thread : null)
2753                + " pid=" + (app != null ? app.pid : -1));
2754        if (app != null && app.pid > 0) {
2755            if (!knownToBeDead || app.thread == null) {
2756                // We already have the app running, or are waiting for it to
2757                // come up (we have a pid but not yet its thread), so keep it.
2758                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2759                // If this is a new package in the process, add the package to the list
2760                app.addPackage(info.packageName, mProcessStats);
2761                return app;
2762            }
2763
2764            // An application record is attached to a previous process,
2765            // clean it up now.
2766            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2767            handleAppDiedLocked(app, true, true);
2768        }
2769
2770        String hostingNameStr = hostingName != null
2771                ? hostingName.flattenToShortString() : null;
2772
2773        if (!isolated) {
2774            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2775                // If we are in the background, then check to see if this process
2776                // is bad.  If so, we will just silently fail.
2777                if (mBadProcesses.get(info.processName, info.uid) != null) {
2778                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2779                            + "/" + info.processName);
2780                    return null;
2781                }
2782            } else {
2783                // When the user is explicitly starting a process, then clear its
2784                // crash count so that we won't make it bad until they see at
2785                // least one crash dialog again, and make the process good again
2786                // if it had been bad.
2787                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2788                        + "/" + info.processName);
2789                mProcessCrashTimes.remove(info.processName, info.uid);
2790                if (mBadProcesses.get(info.processName, info.uid) != null) {
2791                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2792                            UserHandle.getUserId(info.uid), info.uid,
2793                            info.processName);
2794                    mBadProcesses.remove(info.processName, info.uid);
2795                    if (app != null) {
2796                        app.bad = false;
2797                    }
2798                }
2799            }
2800        }
2801
2802        if (app == null) {
2803            app = newProcessRecordLocked(info, processName, isolated);
2804            if (app == null) {
2805                Slog.w(TAG, "Failed making new process record for "
2806                        + processName + "/" + info.uid + " isolated=" + isolated);
2807                return null;
2808            }
2809            mProcessNames.put(processName, app.uid, app);
2810            if (isolated) {
2811                mIsolatedProcesses.put(app.uid, app);
2812            }
2813        } else {
2814            // If this is a new package in the process, add the package to the list
2815            app.addPackage(info.packageName, mProcessStats);
2816        }
2817
2818        // If the system is not ready yet, then hold off on starting this
2819        // process until it is.
2820        if (!mProcessesReady
2821                && !isAllowedWhileBooting(info)
2822                && !allowWhileBooting) {
2823            if (!mProcessesOnHold.contains(app)) {
2824                mProcessesOnHold.add(app);
2825            }
2826            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2827            return app;
2828        }
2829
2830        startProcessLocked(app, hostingType, hostingNameStr);
2831        return (app.pid != 0) ? app : null;
2832    }
2833
2834    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2835        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2836    }
2837
2838    private final void startProcessLocked(ProcessRecord app,
2839            String hostingType, String hostingNameStr) {
2840        if (app.pid > 0 && app.pid != MY_PID) {
2841            synchronized (mPidsSelfLocked) {
2842                mPidsSelfLocked.remove(app.pid);
2843                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2844            }
2845            app.setPid(0);
2846        }
2847
2848        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2849                "startProcessLocked removing on hold: " + app);
2850        mProcessesOnHold.remove(app);
2851
2852        updateCpuStats();
2853
2854        try {
2855            int uid = app.uid;
2856
2857            int[] gids = null;
2858            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2859            if (!app.isolated) {
2860                int[] permGids = null;
2861                try {
2862                    final PackageManager pm = mContext.getPackageManager();
2863                    permGids = pm.getPackageGids(app.info.packageName);
2864
2865                    if (Environment.isExternalStorageEmulated()) {
2866                        if (pm.checkPermission(
2867                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2868                                app.info.packageName) == PERMISSION_GRANTED) {
2869                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2870                        } else {
2871                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2872                        }
2873                    }
2874                } catch (PackageManager.NameNotFoundException e) {
2875                    Slog.w(TAG, "Unable to retrieve gids", e);
2876                }
2877
2878                /*
2879                 * Add shared application GID so applications can share some
2880                 * resources like shared libraries
2881                 */
2882                if (permGids == null) {
2883                    gids = new int[1];
2884                } else {
2885                    gids = new int[permGids.length + 1];
2886                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2887                }
2888                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2889            }
2890            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2891                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2892                        && mTopComponent != null
2893                        && app.processName.equals(mTopComponent.getPackageName())) {
2894                    uid = 0;
2895                }
2896                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2897                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2898                    uid = 0;
2899                }
2900            }
2901            int debugFlags = 0;
2902            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2903                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2904                // Also turn on CheckJNI for debuggable apps. It's quite
2905                // awkward to turn on otherwise.
2906                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2907            }
2908            // Run the app in safe mode if its manifest requests so or the
2909            // system is booted in safe mode.
2910            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2911                mSafeMode == true) {
2912                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2913            }
2914            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2915                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2916            }
2917            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2918                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2919            }
2920            if ("1".equals(SystemProperties.get("debug.assert"))) {
2921                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2922            }
2923
2924            String requiredAbi = app.info.cpuAbi;
2925            if (requiredAbi == null) {
2926                requiredAbi = Build.SUPPORTED_ABIS[0];
2927            }
2928
2929            // Start the process.  It will either succeed and return a result containing
2930            // the PID of the new process, or else throw a RuntimeException.
2931            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2932                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2933                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2934
2935            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2936            synchronized (bs) {
2937                if (bs.isOnBattery()) {
2938                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2939                }
2940            }
2941
2942            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2943                    UserHandle.getUserId(uid), startResult.pid, uid,
2944                    app.processName, hostingType,
2945                    hostingNameStr != null ? hostingNameStr : "");
2946
2947            if (app.persistent) {
2948                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2949            }
2950
2951            StringBuilder buf = mStringBuilder;
2952            buf.setLength(0);
2953            buf.append("Start proc ");
2954            buf.append(app.processName);
2955            buf.append(" for ");
2956            buf.append(hostingType);
2957            if (hostingNameStr != null) {
2958                buf.append(" ");
2959                buf.append(hostingNameStr);
2960            }
2961            buf.append(": pid=");
2962            buf.append(startResult.pid);
2963            buf.append(" uid=");
2964            buf.append(uid);
2965            buf.append(" gids={");
2966            if (gids != null) {
2967                for (int gi=0; gi<gids.length; gi++) {
2968                    if (gi != 0) buf.append(", ");
2969                    buf.append(gids[gi]);
2970
2971                }
2972            }
2973            buf.append("}");
2974            Slog.i(TAG, buf.toString());
2975            app.setPid(startResult.pid);
2976            app.usingWrapper = startResult.usingWrapper;
2977            app.removed = false;
2978            synchronized (mPidsSelfLocked) {
2979                this.mPidsSelfLocked.put(startResult.pid, app);
2980                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2981                msg.obj = app;
2982                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2983                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2984            }
2985            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2986                    app.processName, app.info.uid);
2987            if (app.isolated) {
2988                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2989            }
2990        } catch (RuntimeException e) {
2991            // XXX do better error recovery.
2992            app.setPid(0);
2993            Slog.e(TAG, "Failure starting process " + app.processName, e);
2994        }
2995    }
2996
2997    void updateUsageStats(ActivityRecord component, boolean resumed) {
2998        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2999        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3000        if (resumed) {
3001            mUsageStatsService.noteResumeComponent(component.realActivity);
3002            synchronized (stats) {
3003                stats.noteActivityResumedLocked(component.app.uid);
3004            }
3005        } else {
3006            mUsageStatsService.notePauseComponent(component.realActivity);
3007            synchronized (stats) {
3008                stats.noteActivityPausedLocked(component.app.uid);
3009            }
3010        }
3011    }
3012
3013    Intent getHomeIntent() {
3014        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3015        intent.setComponent(mTopComponent);
3016        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3017            intent.addCategory(Intent.CATEGORY_HOME);
3018        }
3019        return intent;
3020    }
3021
3022    boolean startHomeActivityLocked(int userId) {
3023        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3024                && mTopAction == null) {
3025            // We are running in factory test mode, but unable to find
3026            // the factory test app, so just sit around displaying the
3027            // error message and don't try to start anything.
3028            return false;
3029        }
3030        Intent intent = getHomeIntent();
3031        ActivityInfo aInfo =
3032            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3033        if (aInfo != null) {
3034            intent.setComponent(new ComponentName(
3035                    aInfo.applicationInfo.packageName, aInfo.name));
3036            // Don't do this if the home app is currently being
3037            // instrumented.
3038            aInfo = new ActivityInfo(aInfo);
3039            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3040            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3041                    aInfo.applicationInfo.uid, true);
3042            if (app == null || app.instrumentationClass == null) {
3043                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3044                mStackSupervisor.startHomeActivity(intent, aInfo);
3045            }
3046        }
3047
3048        return true;
3049    }
3050
3051    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3052        ActivityInfo ai = null;
3053        ComponentName comp = intent.getComponent();
3054        try {
3055            if (comp != null) {
3056                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3057            } else {
3058                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3059                        intent,
3060                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3061                            flags, userId);
3062
3063                if (info != null) {
3064                    ai = info.activityInfo;
3065                }
3066            }
3067        } catch (RemoteException e) {
3068            // ignore
3069        }
3070
3071        return ai;
3072    }
3073
3074    /**
3075     * Starts the "new version setup screen" if appropriate.
3076     */
3077    void startSetupActivityLocked() {
3078        // Only do this once per boot.
3079        if (mCheckedForSetup) {
3080            return;
3081        }
3082
3083        // We will show this screen if the current one is a different
3084        // version than the last one shown, and we are not running in
3085        // low-level factory test mode.
3086        final ContentResolver resolver = mContext.getContentResolver();
3087        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3088                Settings.Global.getInt(resolver,
3089                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3090            mCheckedForSetup = true;
3091
3092            // See if we should be showing the platform update setup UI.
3093            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3094            List<ResolveInfo> ris = mContext.getPackageManager()
3095                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3096
3097            // We don't allow third party apps to replace this.
3098            ResolveInfo ri = null;
3099            for (int i=0; ris != null && i<ris.size(); i++) {
3100                if ((ris.get(i).activityInfo.applicationInfo.flags
3101                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3102                    ri = ris.get(i);
3103                    break;
3104                }
3105            }
3106
3107            if (ri != null) {
3108                String vers = ri.activityInfo.metaData != null
3109                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3110                        : null;
3111                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3112                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3113                            Intent.METADATA_SETUP_VERSION);
3114                }
3115                String lastVers = Settings.Secure.getString(
3116                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3117                if (vers != null && !vers.equals(lastVers)) {
3118                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3119                    intent.setComponent(new ComponentName(
3120                            ri.activityInfo.packageName, ri.activityInfo.name));
3121                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3122                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3123                }
3124            }
3125        }
3126    }
3127
3128    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3129        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3130    }
3131
3132    void enforceNotIsolatedCaller(String caller) {
3133        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3134            throw new SecurityException("Isolated process not allowed to call " + caller);
3135        }
3136    }
3137
3138    @Override
3139    public int getFrontActivityScreenCompatMode() {
3140        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3141        synchronized (this) {
3142            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3143        }
3144    }
3145
3146    @Override
3147    public void setFrontActivityScreenCompatMode(int mode) {
3148        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3149                "setFrontActivityScreenCompatMode");
3150        synchronized (this) {
3151            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3152        }
3153    }
3154
3155    @Override
3156    public int getPackageScreenCompatMode(String packageName) {
3157        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3158        synchronized (this) {
3159            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3160        }
3161    }
3162
3163    @Override
3164    public void setPackageScreenCompatMode(String packageName, int mode) {
3165        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3166                "setPackageScreenCompatMode");
3167        synchronized (this) {
3168            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3169        }
3170    }
3171
3172    @Override
3173    public boolean getPackageAskScreenCompat(String packageName) {
3174        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3175        synchronized (this) {
3176            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3177        }
3178    }
3179
3180    @Override
3181    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3182        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3183                "setPackageAskScreenCompat");
3184        synchronized (this) {
3185            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3186        }
3187    }
3188
3189    private void dispatchProcessesChanged() {
3190        int N;
3191        synchronized (this) {
3192            N = mPendingProcessChanges.size();
3193            if (mActiveProcessChanges.length < N) {
3194                mActiveProcessChanges = new ProcessChangeItem[N];
3195            }
3196            mPendingProcessChanges.toArray(mActiveProcessChanges);
3197            mAvailProcessChanges.addAll(mPendingProcessChanges);
3198            mPendingProcessChanges.clear();
3199            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3200        }
3201
3202        int i = mProcessObservers.beginBroadcast();
3203        while (i > 0) {
3204            i--;
3205            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3206            if (observer != null) {
3207                try {
3208                    for (int j=0; j<N; j++) {
3209                        ProcessChangeItem item = mActiveProcessChanges[j];
3210                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3211                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3212                                    + item.pid + " uid=" + item.uid + ": "
3213                                    + item.foregroundActivities);
3214                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3215                                    item.foregroundActivities);
3216                        }
3217                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3218                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3219                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3220                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3221                        }
3222                    }
3223                } catch (RemoteException e) {
3224                }
3225            }
3226        }
3227        mProcessObservers.finishBroadcast();
3228    }
3229
3230    private void dispatchProcessDied(int pid, int uid) {
3231        int i = mProcessObservers.beginBroadcast();
3232        while (i > 0) {
3233            i--;
3234            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3235            if (observer != null) {
3236                try {
3237                    observer.onProcessDied(pid, uid);
3238                } catch (RemoteException e) {
3239                }
3240            }
3241        }
3242        mProcessObservers.finishBroadcast();
3243    }
3244
3245    final void doPendingActivityLaunchesLocked(boolean doResume) {
3246        final int N = mPendingActivityLaunches.size();
3247        if (N <= 0) {
3248            return;
3249        }
3250        for (int i=0; i<N; i++) {
3251            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3252            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3253                    doResume && i == (N-1), null);
3254        }
3255        mPendingActivityLaunches.clear();
3256    }
3257
3258    @Override
3259    public final int startActivity(IApplicationThread caller, String callingPackage,
3260            Intent intent, String resolvedType, IBinder resultTo,
3261            String resultWho, int requestCode, int startFlags,
3262            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3263        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3264                resultWho, requestCode,
3265                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3266    }
3267
3268    @Override
3269    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3270            Intent intent, String resolvedType, IBinder resultTo,
3271            String resultWho, int requestCode, int startFlags,
3272            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3273        enforceNotIsolatedCaller("startActivity");
3274        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3275                false, true, "startActivity", null);
3276        // TODO: Switch to user app stacks here.
3277        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3278                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3279                null, null, options, userId, null);
3280    }
3281
3282    @Override
3283    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3284            Intent intent, String resolvedType, IBinder resultTo,
3285            String resultWho, int requestCode, int startFlags, String profileFile,
3286            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3287        enforceNotIsolatedCaller("startActivityAndWait");
3288        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3289                false, true, "startActivityAndWait", null);
3290        WaitResult res = new WaitResult();
3291        // TODO: Switch to user app stacks here.
3292        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3293                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3294                res, null, options, UserHandle.getCallingUserId(), null);
3295        return res;
3296    }
3297
3298    @Override
3299    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3300            Intent intent, String resolvedType, IBinder resultTo,
3301            String resultWho, int requestCode, int startFlags, Configuration config,
3302            Bundle options, int userId) {
3303        enforceNotIsolatedCaller("startActivityWithConfig");
3304        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3305                false, true, "startActivityWithConfig", null);
3306        // TODO: Switch to user app stacks here.
3307        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3308                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3309                null, null, null, config, options, userId, null);
3310        return ret;
3311    }
3312
3313    @Override
3314    public int startActivityIntentSender(IApplicationThread caller,
3315            IntentSender intent, Intent fillInIntent, String resolvedType,
3316            IBinder resultTo, String resultWho, int requestCode,
3317            int flagsMask, int flagsValues, Bundle options) {
3318        enforceNotIsolatedCaller("startActivityIntentSender");
3319        // Refuse possible leaked file descriptors
3320        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3321            throw new IllegalArgumentException("File descriptors passed in Intent");
3322        }
3323
3324        IIntentSender sender = intent.getTarget();
3325        if (!(sender instanceof PendingIntentRecord)) {
3326            throw new IllegalArgumentException("Bad PendingIntent object");
3327        }
3328
3329        PendingIntentRecord pir = (PendingIntentRecord)sender;
3330
3331        synchronized (this) {
3332            // If this is coming from the currently resumed activity, it is
3333            // effectively saying that app switches are allowed at this point.
3334            final ActivityStack stack = getFocusedStack();
3335            if (stack.mResumedActivity != null &&
3336                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3337                mAppSwitchesAllowedTime = 0;
3338            }
3339        }
3340        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3341                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3342        return ret;
3343    }
3344
3345    @Override
3346    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3347            Intent intent, String resolvedType, IVoiceInteractionSession session,
3348            IVoiceInteractor interactor, int startFlags, String profileFile,
3349            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3350        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3351                != PackageManager.PERMISSION_GRANTED) {
3352            String msg = "Permission Denial: startVoiceActivity() from pid="
3353                    + Binder.getCallingPid()
3354                    + ", uid=" + Binder.getCallingUid()
3355                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3356            Slog.w(TAG, msg);
3357            throw new SecurityException(msg);
3358        }
3359        if (session == null || interactor == null) {
3360            throw new NullPointerException("null session or interactor");
3361        }
3362        userId = handleIncomingUser(callingPid, callingUid, userId,
3363                false, true, "startVoiceActivity", null);
3364        // TODO: Switch to user app stacks here.
3365        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3366                resolvedType, session, interactor, null, null, 0, startFlags,
3367                profileFile, profileFd, null, null, options, userId, null);
3368    }
3369
3370    @Override
3371    public boolean startNextMatchingActivity(IBinder callingActivity,
3372            Intent intent, Bundle options) {
3373        // Refuse possible leaked file descriptors
3374        if (intent != null && intent.hasFileDescriptors() == true) {
3375            throw new IllegalArgumentException("File descriptors passed in Intent");
3376        }
3377
3378        synchronized (this) {
3379            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3380            if (r == null) {
3381                ActivityOptions.abort(options);
3382                return false;
3383            }
3384            if (r.app == null || r.app.thread == null) {
3385                // The caller is not running...  d'oh!
3386                ActivityOptions.abort(options);
3387                return false;
3388            }
3389            intent = new Intent(intent);
3390            // The caller is not allowed to change the data.
3391            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3392            // And we are resetting to find the next component...
3393            intent.setComponent(null);
3394
3395            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3396
3397            ActivityInfo aInfo = null;
3398            try {
3399                List<ResolveInfo> resolves =
3400                    AppGlobals.getPackageManager().queryIntentActivities(
3401                            intent, r.resolvedType,
3402                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3403                            UserHandle.getCallingUserId());
3404
3405                // Look for the original activity in the list...
3406                final int N = resolves != null ? resolves.size() : 0;
3407                for (int i=0; i<N; i++) {
3408                    ResolveInfo rInfo = resolves.get(i);
3409                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3410                            && rInfo.activityInfo.name.equals(r.info.name)) {
3411                        // We found the current one...  the next matching is
3412                        // after it.
3413                        i++;
3414                        if (i<N) {
3415                            aInfo = resolves.get(i).activityInfo;
3416                        }
3417                        if (debug) {
3418                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3419                                    + "/" + r.info.name);
3420                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3421                                    + "/" + aInfo.name);
3422                        }
3423                        break;
3424                    }
3425                }
3426            } catch (RemoteException e) {
3427            }
3428
3429            if (aInfo == null) {
3430                // Nobody who is next!
3431                ActivityOptions.abort(options);
3432                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3433                return false;
3434            }
3435
3436            intent.setComponent(new ComponentName(
3437                    aInfo.applicationInfo.packageName, aInfo.name));
3438            intent.setFlags(intent.getFlags()&~(
3439                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3440                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3441                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3442                    Intent.FLAG_ACTIVITY_NEW_TASK));
3443
3444            // Okay now we need to start the new activity, replacing the
3445            // currently running activity.  This is a little tricky because
3446            // we want to start the new one as if the current one is finished,
3447            // but not finish the current one first so that there is no flicker.
3448            // And thus...
3449            final boolean wasFinishing = r.finishing;
3450            r.finishing = true;
3451
3452            // Propagate reply information over to the new activity.
3453            final ActivityRecord resultTo = r.resultTo;
3454            final String resultWho = r.resultWho;
3455            final int requestCode = r.requestCode;
3456            r.resultTo = null;
3457            if (resultTo != null) {
3458                resultTo.removeResultsLocked(r, resultWho, requestCode);
3459            }
3460
3461            final long origId = Binder.clearCallingIdentity();
3462            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3463                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3464                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3465                    options, false, null, null);
3466            Binder.restoreCallingIdentity(origId);
3467
3468            r.finishing = wasFinishing;
3469            if (res != ActivityManager.START_SUCCESS) {
3470                return false;
3471            }
3472            return true;
3473        }
3474    }
3475
3476    final int startActivityInPackage(int uid, String callingPackage,
3477            Intent intent, String resolvedType, IBinder resultTo,
3478            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3479                    IActivityContainer container) {
3480
3481        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3482                false, true, "startActivityInPackage", null);
3483
3484        // TODO: Switch to user app stacks here.
3485        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3486                null, null, resultTo, resultWho, requestCode, startFlags,
3487                null, null, null, null, options, userId, container);
3488        return ret;
3489    }
3490
3491    @Override
3492    public final int startActivities(IApplicationThread caller, String callingPackage,
3493            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3494            int userId) {
3495        enforceNotIsolatedCaller("startActivities");
3496        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3497                false, true, "startActivity", null);
3498        // TODO: Switch to user app stacks here.
3499        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3500                resolvedTypes, resultTo, options, userId);
3501        return ret;
3502    }
3503
3504    final int startActivitiesInPackage(int uid, String callingPackage,
3505            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3506            Bundle options, int userId) {
3507
3508        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3509                false, true, "startActivityInPackage", null);
3510        // TODO: Switch to user app stacks here.
3511        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3512                resultTo, options, userId);
3513        return ret;
3514    }
3515
3516    final void addRecentTaskLocked(TaskRecord task) {
3517        int N = mRecentTasks.size();
3518        // Quick case: check if the top-most recent task is the same.
3519        if (N > 0 && mRecentTasks.get(0) == task) {
3520            return;
3521        }
3522        // Another quick case: never add voice sessions.
3523        if (task.voiceSession != null) {
3524            return;
3525        }
3526        // Remove any existing entries that are the same kind of task.
3527        final Intent intent = task.intent;
3528        final boolean document = intent != null && intent.isDocument();
3529        for (int i=0; i<N; i++) {
3530            TaskRecord tr = mRecentTasks.get(i);
3531            if (task != tr) {
3532                if (task.userId != tr.userId) {
3533                    continue;
3534                }
3535                final Intent trIntent = tr.intent;
3536                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3537                    (intent == null || !intent.filterEquals(trIntent))) {
3538                    continue;
3539                }
3540                if (document || trIntent != null && trIntent.isDocument()) {
3541                    // Document tasks do not match other tasks.
3542                    continue;
3543                }
3544            }
3545
3546            // Either task and tr are the same or, their affinities match or their intents match
3547            // and neither of them is a document.
3548            tr.disposeThumbnail();
3549            mRecentTasks.remove(i);
3550            i--;
3551            N--;
3552            if (task.intent == null) {
3553                // If the new recent task we are adding is not fully
3554                // specified, then replace it with the existing recent task.
3555                task = tr;
3556            }
3557        }
3558        if (N >= MAX_RECENT_TASKS) {
3559            mRecentTasks.remove(N-1).disposeThumbnail();
3560        }
3561        mRecentTasks.add(0, task);
3562    }
3563
3564    @Override
3565    public void reportActivityFullyDrawn(IBinder token) {
3566        synchronized (this) {
3567            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3568            if (r == null) {
3569                return;
3570            }
3571            r.reportFullyDrawnLocked();
3572        }
3573    }
3574
3575    @Override
3576    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3577        synchronized (this) {
3578            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3579            if (r == null) {
3580                return;
3581            }
3582            final long origId = Binder.clearCallingIdentity();
3583            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3584            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3585                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3586            if (config != null) {
3587                r.frozenBeforeDestroy = true;
3588                if (!updateConfigurationLocked(config, r, false, false)) {
3589                    mStackSupervisor.resumeTopActivitiesLocked();
3590                }
3591            }
3592            Binder.restoreCallingIdentity(origId);
3593        }
3594    }
3595
3596    @Override
3597    public int getRequestedOrientation(IBinder token) {
3598        synchronized (this) {
3599            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3600            if (r == null) {
3601                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3602            }
3603            return mWindowManager.getAppOrientation(r.appToken);
3604        }
3605    }
3606
3607    /**
3608     * This is the internal entry point for handling Activity.finish().
3609     *
3610     * @param token The Binder token referencing the Activity we want to finish.
3611     * @param resultCode Result code, if any, from this Activity.
3612     * @param resultData Result data (Intent), if any, from this Activity.
3613     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3614     *            the root Activity in the task.
3615     *
3616     * @return Returns true if the activity successfully finished, or false if it is still running.
3617     */
3618    @Override
3619    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3620            boolean finishTask) {
3621        // Refuse possible leaked file descriptors
3622        if (resultData != null && resultData.hasFileDescriptors() == true) {
3623            throw new IllegalArgumentException("File descriptors passed in Intent");
3624        }
3625
3626        synchronized(this) {
3627            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3628            if (r == null) {
3629                return true;
3630            }
3631            // Keep track of the root activity of the task before we finish it
3632            TaskRecord tr = r.task;
3633            ActivityRecord rootR = tr.getRootActivity();
3634            if (mController != null) {
3635                // Find the first activity that is not finishing.
3636                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3637                if (next != null) {
3638                    // ask watcher if this is allowed
3639                    boolean resumeOK = true;
3640                    try {
3641                        resumeOK = mController.activityResuming(next.packageName);
3642                    } catch (RemoteException e) {
3643                        mController = null;
3644                        Watchdog.getInstance().setActivityController(null);
3645                    }
3646
3647                    if (!resumeOK) {
3648                        return false;
3649                    }
3650                }
3651            }
3652            final long origId = Binder.clearCallingIdentity();
3653            try {
3654                boolean res;
3655                if (finishTask && r == rootR) {
3656                    // If requested, remove the task that is associated to this activity only if it
3657                    // was the root activity in the task.  The result code and data is ignored because
3658                    // we don't support returning them across task boundaries.
3659                    res = removeTaskByIdLocked(tr.taskId, 0);
3660                } else {
3661                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3662                            resultData, "app-request", true);
3663                }
3664                return res;
3665            } finally {
3666                Binder.restoreCallingIdentity(origId);
3667            }
3668        }
3669    }
3670
3671    @Override
3672    public final void finishHeavyWeightApp() {
3673        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3674                != PackageManager.PERMISSION_GRANTED) {
3675            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3676                    + Binder.getCallingPid()
3677                    + ", uid=" + Binder.getCallingUid()
3678                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3679            Slog.w(TAG, msg);
3680            throw new SecurityException(msg);
3681        }
3682
3683        synchronized(this) {
3684            if (mHeavyWeightProcess == null) {
3685                return;
3686            }
3687
3688            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3689                    mHeavyWeightProcess.activities);
3690            for (int i=0; i<activities.size(); i++) {
3691                ActivityRecord r = activities.get(i);
3692                if (!r.finishing) {
3693                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3694                            null, "finish-heavy", true);
3695                }
3696            }
3697
3698            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3699                    mHeavyWeightProcess.userId, 0));
3700            mHeavyWeightProcess = null;
3701        }
3702    }
3703
3704    @Override
3705    public void crashApplication(int uid, int initialPid, String packageName,
3706            String message) {
3707        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3708                != PackageManager.PERMISSION_GRANTED) {
3709            String msg = "Permission Denial: crashApplication() from pid="
3710                    + Binder.getCallingPid()
3711                    + ", uid=" + Binder.getCallingUid()
3712                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3713            Slog.w(TAG, msg);
3714            throw new SecurityException(msg);
3715        }
3716
3717        synchronized(this) {
3718            ProcessRecord proc = null;
3719
3720            // Figure out which process to kill.  We don't trust that initialPid
3721            // still has any relation to current pids, so must scan through the
3722            // list.
3723            synchronized (mPidsSelfLocked) {
3724                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3725                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3726                    if (p.uid != uid) {
3727                        continue;
3728                    }
3729                    if (p.pid == initialPid) {
3730                        proc = p;
3731                        break;
3732                    }
3733                    if (p.pkgList.containsKey(packageName)) {
3734                        proc = p;
3735                    }
3736                }
3737            }
3738
3739            if (proc == null) {
3740                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3741                        + " initialPid=" + initialPid
3742                        + " packageName=" + packageName);
3743                return;
3744            }
3745
3746            if (proc.thread != null) {
3747                if (proc.pid == Process.myPid()) {
3748                    Log.w(TAG, "crashApplication: trying to crash self!");
3749                    return;
3750                }
3751                long ident = Binder.clearCallingIdentity();
3752                try {
3753                    proc.thread.scheduleCrash(message);
3754                } catch (RemoteException e) {
3755                }
3756                Binder.restoreCallingIdentity(ident);
3757            }
3758        }
3759    }
3760
3761    @Override
3762    public final void finishSubActivity(IBinder token, String resultWho,
3763            int requestCode) {
3764        synchronized(this) {
3765            final long origId = Binder.clearCallingIdentity();
3766            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3767            if (r != null) {
3768                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3769            }
3770            Binder.restoreCallingIdentity(origId);
3771        }
3772    }
3773
3774    @Override
3775    public boolean finishActivityAffinity(IBinder token) {
3776        synchronized(this) {
3777            final long origId = Binder.clearCallingIdentity();
3778            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3779            boolean res = false;
3780            if (r != null) {
3781                res = r.task.stack.finishActivityAffinityLocked(r);
3782            }
3783            Binder.restoreCallingIdentity(origId);
3784            return res;
3785        }
3786    }
3787
3788    @Override
3789    public boolean willActivityBeVisible(IBinder token) {
3790        synchronized(this) {
3791            ActivityStack stack = ActivityRecord.getStackLocked(token);
3792            if (stack != null) {
3793                return stack.willActivityBeVisibleLocked(token);
3794            }
3795            return false;
3796        }
3797    }
3798
3799    @Override
3800    public void overridePendingTransition(IBinder token, String packageName,
3801            int enterAnim, int exitAnim) {
3802        synchronized(this) {
3803            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3804            if (self == null) {
3805                return;
3806            }
3807
3808            final long origId = Binder.clearCallingIdentity();
3809
3810            if (self.state == ActivityState.RESUMED
3811                    || self.state == ActivityState.PAUSING) {
3812                mWindowManager.overridePendingAppTransition(packageName,
3813                        enterAnim, exitAnim, null);
3814            }
3815
3816            Binder.restoreCallingIdentity(origId);
3817        }
3818    }
3819
3820    /**
3821     * Main function for removing an existing process from the activity manager
3822     * as a result of that process going away.  Clears out all connections
3823     * to the process.
3824     */
3825    private final void handleAppDiedLocked(ProcessRecord app,
3826            boolean restarting, boolean allowRestart) {
3827        int pid = app.pid;
3828        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3829        if (!restarting) {
3830            removeLruProcessLocked(app);
3831            if (pid > 0) {
3832                ProcessList.remove(pid);
3833            }
3834        }
3835
3836        if (mProfileProc == app) {
3837            clearProfilerLocked();
3838        }
3839
3840        // Remove this application's activities from active lists.
3841        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3842
3843        app.activities.clear();
3844
3845        if (app.instrumentationClass != null) {
3846            Slog.w(TAG, "Crash of app " + app.processName
3847                  + " running instrumentation " + app.instrumentationClass);
3848            Bundle info = new Bundle();
3849            info.putString("shortMsg", "Process crashed.");
3850            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3851        }
3852
3853        if (!restarting) {
3854            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3855                // If there was nothing to resume, and we are not already
3856                // restarting this process, but there is a visible activity that
3857                // is hosted by the process...  then make sure all visible
3858                // activities are running, taking care of restarting this
3859                // process.
3860                if (hasVisibleActivities) {
3861                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3862                }
3863            }
3864        }
3865    }
3866
3867    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3868        IBinder threadBinder = thread.asBinder();
3869        // Find the application record.
3870        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3871            ProcessRecord rec = mLruProcesses.get(i);
3872            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3873                return i;
3874            }
3875        }
3876        return -1;
3877    }
3878
3879    final ProcessRecord getRecordForAppLocked(
3880            IApplicationThread thread) {
3881        if (thread == null) {
3882            return null;
3883        }
3884
3885        int appIndex = getLRURecordIndexForAppLocked(thread);
3886        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3887    }
3888
3889    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3890        // If there are no longer any background processes running,
3891        // and the app that died was not running instrumentation,
3892        // then tell everyone we are now low on memory.
3893        boolean haveBg = false;
3894        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3895            ProcessRecord rec = mLruProcesses.get(i);
3896            if (rec.thread != null
3897                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3898                haveBg = true;
3899                break;
3900            }
3901        }
3902
3903        if (!haveBg) {
3904            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3905            if (doReport) {
3906                long now = SystemClock.uptimeMillis();
3907                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3908                    doReport = false;
3909                } else {
3910                    mLastMemUsageReportTime = now;
3911                }
3912            }
3913            final ArrayList<ProcessMemInfo> memInfos
3914                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3915            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3916            long now = SystemClock.uptimeMillis();
3917            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3918                ProcessRecord rec = mLruProcesses.get(i);
3919                if (rec == dyingProc || rec.thread == null) {
3920                    continue;
3921                }
3922                if (doReport) {
3923                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3924                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3925                }
3926                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3927                    // The low memory report is overriding any current
3928                    // state for a GC request.  Make sure to do
3929                    // heavy/important/visible/foreground processes first.
3930                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3931                        rec.lastRequestedGc = 0;
3932                    } else {
3933                        rec.lastRequestedGc = rec.lastLowMemory;
3934                    }
3935                    rec.reportLowMemory = true;
3936                    rec.lastLowMemory = now;
3937                    mProcessesToGc.remove(rec);
3938                    addProcessToGcListLocked(rec);
3939                }
3940            }
3941            if (doReport) {
3942                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3943                mHandler.sendMessage(msg);
3944            }
3945            scheduleAppGcsLocked();
3946        }
3947    }
3948
3949    final void appDiedLocked(ProcessRecord app, int pid,
3950            IApplicationThread thread) {
3951
3952        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3953        synchronized (stats) {
3954            stats.noteProcessDiedLocked(app.info.uid, pid);
3955        }
3956
3957        // Clean up already done if the process has been re-started.
3958        if (app.pid == pid && app.thread != null &&
3959                app.thread.asBinder() == thread.asBinder()) {
3960            boolean doLowMem = app.instrumentationClass == null;
3961            boolean doOomAdj = doLowMem;
3962            if (!app.killedByAm) {
3963                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3964                        + ") has died.");
3965                mAllowLowerMemLevel = true;
3966            } else {
3967                // Note that we always want to do oom adj to update our state with the
3968                // new number of procs.
3969                mAllowLowerMemLevel = false;
3970                doLowMem = false;
3971            }
3972            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3973            if (DEBUG_CLEANUP) Slog.v(
3974                TAG, "Dying app: " + app + ", pid: " + pid
3975                + ", thread: " + thread.asBinder());
3976            handleAppDiedLocked(app, false, true);
3977
3978            if (doOomAdj) {
3979                updateOomAdjLocked();
3980            }
3981            if (doLowMem) {
3982                doLowMemReportIfNeededLocked(app);
3983            }
3984        } else if (app.pid != pid) {
3985            // A new process has already been started.
3986            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3987                    + ") has died and restarted (pid " + app.pid + ").");
3988            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3989        } else if (DEBUG_PROCESSES) {
3990            Slog.d(TAG, "Received spurious death notification for thread "
3991                    + thread.asBinder());
3992        }
3993    }
3994
3995    /**
3996     * If a stack trace dump file is configured, dump process stack traces.
3997     * @param clearTraces causes the dump file to be erased prior to the new
3998     *    traces being written, if true; when false, the new traces will be
3999     *    appended to any existing file content.
4000     * @param firstPids of dalvik VM processes to dump stack traces for first
4001     * @param lastPids of dalvik VM processes to dump stack traces for last
4002     * @param nativeProcs optional list of native process names to dump stack crawls
4003     * @return file containing stack traces, or null if no dump file is configured
4004     */
4005    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4006            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4007        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4008        if (tracesPath == null || tracesPath.length() == 0) {
4009            return null;
4010        }
4011
4012        File tracesFile = new File(tracesPath);
4013        try {
4014            File tracesDir = tracesFile.getParentFile();
4015            if (!tracesDir.exists()) {
4016                tracesFile.mkdirs();
4017                if (!SELinux.restorecon(tracesDir)) {
4018                    return null;
4019                }
4020            }
4021            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4022
4023            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4024            tracesFile.createNewFile();
4025            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4026        } catch (IOException e) {
4027            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4028            return null;
4029        }
4030
4031        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4032        return tracesFile;
4033    }
4034
4035    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4036            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4037        // Use a FileObserver to detect when traces finish writing.
4038        // The order of traces is considered important to maintain for legibility.
4039        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4040            @Override
4041            public synchronized void onEvent(int event, String path) { notify(); }
4042        };
4043
4044        try {
4045            observer.startWatching();
4046
4047            // First collect all of the stacks of the most important pids.
4048            if (firstPids != null) {
4049                try {
4050                    int num = firstPids.size();
4051                    for (int i = 0; i < num; i++) {
4052                        synchronized (observer) {
4053                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4054                            observer.wait(200);  // Wait for write-close, give up after 200msec
4055                        }
4056                    }
4057                } catch (InterruptedException e) {
4058                    Log.wtf(TAG, e);
4059                }
4060            }
4061
4062            // Next collect the stacks of the native pids
4063            if (nativeProcs != null) {
4064                int[] pids = Process.getPidsForCommands(nativeProcs);
4065                if (pids != null) {
4066                    for (int pid : pids) {
4067                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4068                    }
4069                }
4070            }
4071
4072            // Lastly, measure CPU usage.
4073            if (processCpuTracker != null) {
4074                processCpuTracker.init();
4075                System.gc();
4076                processCpuTracker.update();
4077                try {
4078                    synchronized (processCpuTracker) {
4079                        processCpuTracker.wait(500); // measure over 1/2 second.
4080                    }
4081                } catch (InterruptedException e) {
4082                }
4083                processCpuTracker.update();
4084
4085                // We'll take the stack crawls of just the top apps using CPU.
4086                final int N = processCpuTracker.countWorkingStats();
4087                int numProcs = 0;
4088                for (int i=0; i<N && numProcs<5; i++) {
4089                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4090                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4091                        numProcs++;
4092                        try {
4093                            synchronized (observer) {
4094                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4095                                observer.wait(200);  // Wait for write-close, give up after 200msec
4096                            }
4097                        } catch (InterruptedException e) {
4098                            Log.wtf(TAG, e);
4099                        }
4100
4101                    }
4102                }
4103            }
4104        } finally {
4105            observer.stopWatching();
4106        }
4107    }
4108
4109    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4110        if (true || IS_USER_BUILD) {
4111            return;
4112        }
4113        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4114        if (tracesPath == null || tracesPath.length() == 0) {
4115            return;
4116        }
4117
4118        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4119        StrictMode.allowThreadDiskWrites();
4120        try {
4121            final File tracesFile = new File(tracesPath);
4122            final File tracesDir = tracesFile.getParentFile();
4123            final File tracesTmp = new File(tracesDir, "__tmp__");
4124            try {
4125                if (!tracesDir.exists()) {
4126                    tracesFile.mkdirs();
4127                    if (!SELinux.restorecon(tracesDir.getPath())) {
4128                        return;
4129                    }
4130                }
4131                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4132
4133                if (tracesFile.exists()) {
4134                    tracesTmp.delete();
4135                    tracesFile.renameTo(tracesTmp);
4136                }
4137                StringBuilder sb = new StringBuilder();
4138                Time tobj = new Time();
4139                tobj.set(System.currentTimeMillis());
4140                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4141                sb.append(": ");
4142                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4143                sb.append(" since ");
4144                sb.append(msg);
4145                FileOutputStream fos = new FileOutputStream(tracesFile);
4146                fos.write(sb.toString().getBytes());
4147                if (app == null) {
4148                    fos.write("\n*** No application process!".getBytes());
4149                }
4150                fos.close();
4151                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4152            } catch (IOException e) {
4153                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4154                return;
4155            }
4156
4157            if (app != null) {
4158                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4159                firstPids.add(app.pid);
4160                dumpStackTraces(tracesPath, firstPids, null, null, null);
4161            }
4162
4163            File lastTracesFile = null;
4164            File curTracesFile = null;
4165            for (int i=9; i>=0; i--) {
4166                String name = String.format(Locale.US, "slow%02d.txt", i);
4167                curTracesFile = new File(tracesDir, name);
4168                if (curTracesFile.exists()) {
4169                    if (lastTracesFile != null) {
4170                        curTracesFile.renameTo(lastTracesFile);
4171                    } else {
4172                        curTracesFile.delete();
4173                    }
4174                }
4175                lastTracesFile = curTracesFile;
4176            }
4177            tracesFile.renameTo(curTracesFile);
4178            if (tracesTmp.exists()) {
4179                tracesTmp.renameTo(tracesFile);
4180            }
4181        } finally {
4182            StrictMode.setThreadPolicy(oldPolicy);
4183        }
4184    }
4185
4186    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4187            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4188        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4189        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4190
4191        if (mController != null) {
4192            try {
4193                // 0 == continue, -1 = kill process immediately
4194                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4195                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4196            } catch (RemoteException e) {
4197                mController = null;
4198                Watchdog.getInstance().setActivityController(null);
4199            }
4200        }
4201
4202        long anrTime = SystemClock.uptimeMillis();
4203        if (MONITOR_CPU_USAGE) {
4204            updateCpuStatsNow();
4205        }
4206
4207        synchronized (this) {
4208            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4209            if (mShuttingDown) {
4210                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4211                return;
4212            } else if (app.notResponding) {
4213                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4214                return;
4215            } else if (app.crashing) {
4216                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4217                return;
4218            }
4219
4220            // In case we come through here for the same app before completing
4221            // this one, mark as anring now so we will bail out.
4222            app.notResponding = true;
4223
4224            // Log the ANR to the event log.
4225            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4226                    app.processName, app.info.flags, annotation);
4227
4228            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4229            firstPids.add(app.pid);
4230
4231            int parentPid = app.pid;
4232            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4233            if (parentPid != app.pid) firstPids.add(parentPid);
4234
4235            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4236
4237            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4238                ProcessRecord r = mLruProcesses.get(i);
4239                if (r != null && r.thread != null) {
4240                    int pid = r.pid;
4241                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4242                        if (r.persistent) {
4243                            firstPids.add(pid);
4244                        } else {
4245                            lastPids.put(pid, Boolean.TRUE);
4246                        }
4247                    }
4248                }
4249            }
4250        }
4251
4252        // Log the ANR to the main log.
4253        StringBuilder info = new StringBuilder();
4254        info.setLength(0);
4255        info.append("ANR in ").append(app.processName);
4256        if (activity != null && activity.shortComponentName != null) {
4257            info.append(" (").append(activity.shortComponentName).append(")");
4258        }
4259        info.append("\n");
4260        info.append("PID: ").append(app.pid).append("\n");
4261        if (annotation != null) {
4262            info.append("Reason: ").append(annotation).append("\n");
4263        }
4264        if (parent != null && parent != activity) {
4265            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4266        }
4267
4268        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4269
4270        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4271                NATIVE_STACKS_OF_INTEREST);
4272
4273        String cpuInfo = null;
4274        if (MONITOR_CPU_USAGE) {
4275            updateCpuStatsNow();
4276            synchronized (mProcessCpuThread) {
4277                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4278            }
4279            info.append(processCpuTracker.printCurrentLoad());
4280            info.append(cpuInfo);
4281        }
4282
4283        info.append(processCpuTracker.printCurrentState(anrTime));
4284
4285        Slog.e(TAG, info.toString());
4286        if (tracesFile == null) {
4287            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4288            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4289        }
4290
4291        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4292                cpuInfo, tracesFile, null);
4293
4294        if (mController != null) {
4295            try {
4296                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4297                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4298                if (res != 0) {
4299                    if (res < 0 && app.pid != MY_PID) {
4300                        Process.killProcess(app.pid);
4301                    } else {
4302                        synchronized (this) {
4303                            mServices.scheduleServiceTimeoutLocked(app);
4304                        }
4305                    }
4306                    return;
4307                }
4308            } catch (RemoteException e) {
4309                mController = null;
4310                Watchdog.getInstance().setActivityController(null);
4311            }
4312        }
4313
4314        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4315        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4316                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4317
4318        synchronized (this) {
4319            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4320                killUnneededProcessLocked(app, "background ANR");
4321                return;
4322            }
4323
4324            // Set the app's notResponding state, and look up the errorReportReceiver
4325            makeAppNotRespondingLocked(app,
4326                    activity != null ? activity.shortComponentName : null,
4327                    annotation != null ? "ANR " + annotation : "ANR",
4328                    info.toString());
4329
4330            // Bring up the infamous App Not Responding dialog
4331            Message msg = Message.obtain();
4332            HashMap<String, Object> map = new HashMap<String, Object>();
4333            msg.what = SHOW_NOT_RESPONDING_MSG;
4334            msg.obj = map;
4335            msg.arg1 = aboveSystem ? 1 : 0;
4336            map.put("app", app);
4337            if (activity != null) {
4338                map.put("activity", activity);
4339            }
4340
4341            mHandler.sendMessage(msg);
4342        }
4343    }
4344
4345    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4346        if (!mLaunchWarningShown) {
4347            mLaunchWarningShown = true;
4348            mHandler.post(new Runnable() {
4349                @Override
4350                public void run() {
4351                    synchronized (ActivityManagerService.this) {
4352                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4353                        d.show();
4354                        mHandler.postDelayed(new Runnable() {
4355                            @Override
4356                            public void run() {
4357                                synchronized (ActivityManagerService.this) {
4358                                    d.dismiss();
4359                                    mLaunchWarningShown = false;
4360                                }
4361                            }
4362                        }, 4000);
4363                    }
4364                }
4365            });
4366        }
4367    }
4368
4369    @Override
4370    public boolean clearApplicationUserData(final String packageName,
4371            final IPackageDataObserver observer, int userId) {
4372        enforceNotIsolatedCaller("clearApplicationUserData");
4373        int uid = Binder.getCallingUid();
4374        int pid = Binder.getCallingPid();
4375        userId = handleIncomingUser(pid, uid,
4376                userId, false, true, "clearApplicationUserData", null);
4377        long callingId = Binder.clearCallingIdentity();
4378        try {
4379            IPackageManager pm = AppGlobals.getPackageManager();
4380            int pkgUid = -1;
4381            synchronized(this) {
4382                try {
4383                    pkgUid = pm.getPackageUid(packageName, userId);
4384                } catch (RemoteException e) {
4385                }
4386                if (pkgUid == -1) {
4387                    Slog.w(TAG, "Invalid packageName: " + packageName);
4388                    if (observer != null) {
4389                        try {
4390                            observer.onRemoveCompleted(packageName, false);
4391                        } catch (RemoteException e) {
4392                            Slog.i(TAG, "Observer no longer exists.");
4393                        }
4394                    }
4395                    return false;
4396                }
4397                if (uid == pkgUid || checkComponentPermission(
4398                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4399                        pid, uid, -1, true)
4400                        == PackageManager.PERMISSION_GRANTED) {
4401                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4402                } else {
4403                    throw new SecurityException("PID " + pid + " does not have permission "
4404                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4405                                    + " of package " + packageName);
4406                }
4407            }
4408
4409            try {
4410                // Clear application user data
4411                pm.clearApplicationUserData(packageName, observer, userId);
4412
4413                // Remove all permissions granted from/to this package
4414                removeUriPermissionsForPackageLocked(packageName, userId, true);
4415
4416                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4417                        Uri.fromParts("package", packageName, null));
4418                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4419                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4420                        null, null, 0, null, null, null, false, false, userId);
4421            } catch (RemoteException e) {
4422            }
4423        } finally {
4424            Binder.restoreCallingIdentity(callingId);
4425        }
4426        return true;
4427    }
4428
4429    @Override
4430    public void killBackgroundProcesses(final String packageName, int userId) {
4431        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4432                != PackageManager.PERMISSION_GRANTED &&
4433                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4434                        != PackageManager.PERMISSION_GRANTED) {
4435            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4436                    + Binder.getCallingPid()
4437                    + ", uid=" + Binder.getCallingUid()
4438                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4439            Slog.w(TAG, msg);
4440            throw new SecurityException(msg);
4441        }
4442
4443        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4444                userId, true, true, "killBackgroundProcesses", null);
4445        long callingId = Binder.clearCallingIdentity();
4446        try {
4447            IPackageManager pm = AppGlobals.getPackageManager();
4448            synchronized(this) {
4449                int appId = -1;
4450                try {
4451                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4452                } catch (RemoteException e) {
4453                }
4454                if (appId == -1) {
4455                    Slog.w(TAG, "Invalid packageName: " + packageName);
4456                    return;
4457                }
4458                killPackageProcessesLocked(packageName, appId, userId,
4459                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4460            }
4461        } finally {
4462            Binder.restoreCallingIdentity(callingId);
4463        }
4464    }
4465
4466    @Override
4467    public void killAllBackgroundProcesses() {
4468        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4469                != PackageManager.PERMISSION_GRANTED) {
4470            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4471                    + Binder.getCallingPid()
4472                    + ", uid=" + Binder.getCallingUid()
4473                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4474            Slog.w(TAG, msg);
4475            throw new SecurityException(msg);
4476        }
4477
4478        long callingId = Binder.clearCallingIdentity();
4479        try {
4480            synchronized(this) {
4481                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4482                final int NP = mProcessNames.getMap().size();
4483                for (int ip=0; ip<NP; ip++) {
4484                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4485                    final int NA = apps.size();
4486                    for (int ia=0; ia<NA; ia++) {
4487                        ProcessRecord app = apps.valueAt(ia);
4488                        if (app.persistent) {
4489                            // we don't kill persistent processes
4490                            continue;
4491                        }
4492                        if (app.removed) {
4493                            procs.add(app);
4494                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4495                            app.removed = true;
4496                            procs.add(app);
4497                        }
4498                    }
4499                }
4500
4501                int N = procs.size();
4502                for (int i=0; i<N; i++) {
4503                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4504                }
4505                mAllowLowerMemLevel = true;
4506                updateOomAdjLocked();
4507                doLowMemReportIfNeededLocked(null);
4508            }
4509        } finally {
4510            Binder.restoreCallingIdentity(callingId);
4511        }
4512    }
4513
4514    @Override
4515    public void forceStopPackage(final String packageName, int userId) {
4516        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4517                != PackageManager.PERMISSION_GRANTED) {
4518            String msg = "Permission Denial: forceStopPackage() from pid="
4519                    + Binder.getCallingPid()
4520                    + ", uid=" + Binder.getCallingUid()
4521                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4522            Slog.w(TAG, msg);
4523            throw new SecurityException(msg);
4524        }
4525        final int callingPid = Binder.getCallingPid();
4526        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4527                userId, true, true, "forceStopPackage", null);
4528        long callingId = Binder.clearCallingIdentity();
4529        try {
4530            IPackageManager pm = AppGlobals.getPackageManager();
4531            synchronized(this) {
4532                int[] users = userId == UserHandle.USER_ALL
4533                        ? getUsersLocked() : new int[] { userId };
4534                for (int user : users) {
4535                    int pkgUid = -1;
4536                    try {
4537                        pkgUid = pm.getPackageUid(packageName, user);
4538                    } catch (RemoteException e) {
4539                    }
4540                    if (pkgUid == -1) {
4541                        Slog.w(TAG, "Invalid packageName: " + packageName);
4542                        continue;
4543                    }
4544                    try {
4545                        pm.setPackageStoppedState(packageName, true, user);
4546                    } catch (RemoteException e) {
4547                    } catch (IllegalArgumentException e) {
4548                        Slog.w(TAG, "Failed trying to unstop package "
4549                                + packageName + ": " + e);
4550                    }
4551                    if (isUserRunningLocked(user, false)) {
4552                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4553                    }
4554                }
4555            }
4556        } finally {
4557            Binder.restoreCallingIdentity(callingId);
4558        }
4559    }
4560
4561    /*
4562     * The pkg name and app id have to be specified.
4563     */
4564    @Override
4565    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4566        if (pkg == null) {
4567            return;
4568        }
4569        // Make sure the uid is valid.
4570        if (appid < 0) {
4571            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4572            return;
4573        }
4574        int callerUid = Binder.getCallingUid();
4575        // Only the system server can kill an application
4576        if (callerUid == Process.SYSTEM_UID) {
4577            // Post an aysnc message to kill the application
4578            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4579            msg.arg1 = appid;
4580            msg.arg2 = 0;
4581            Bundle bundle = new Bundle();
4582            bundle.putString("pkg", pkg);
4583            bundle.putString("reason", reason);
4584            msg.obj = bundle;
4585            mHandler.sendMessage(msg);
4586        } else {
4587            throw new SecurityException(callerUid + " cannot kill pkg: " +
4588                    pkg);
4589        }
4590    }
4591
4592    @Override
4593    public void closeSystemDialogs(String reason) {
4594        enforceNotIsolatedCaller("closeSystemDialogs");
4595
4596        final int pid = Binder.getCallingPid();
4597        final int uid = Binder.getCallingUid();
4598        final long origId = Binder.clearCallingIdentity();
4599        try {
4600            synchronized (this) {
4601                // Only allow this from foreground processes, so that background
4602                // applications can't abuse it to prevent system UI from being shown.
4603                if (uid >= Process.FIRST_APPLICATION_UID) {
4604                    ProcessRecord proc;
4605                    synchronized (mPidsSelfLocked) {
4606                        proc = mPidsSelfLocked.get(pid);
4607                    }
4608                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4609                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4610                                + " from background process " + proc);
4611                        return;
4612                    }
4613                }
4614                closeSystemDialogsLocked(reason);
4615            }
4616        } finally {
4617            Binder.restoreCallingIdentity(origId);
4618        }
4619    }
4620
4621    void closeSystemDialogsLocked(String reason) {
4622        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4623        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4624                | Intent.FLAG_RECEIVER_FOREGROUND);
4625        if (reason != null) {
4626            intent.putExtra("reason", reason);
4627        }
4628        mWindowManager.closeSystemDialogs(reason);
4629
4630        mStackSupervisor.closeSystemDialogsLocked();
4631
4632        broadcastIntentLocked(null, null, intent, null,
4633                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4634                Process.SYSTEM_UID, UserHandle.USER_ALL);
4635    }
4636
4637    @Override
4638    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4639        enforceNotIsolatedCaller("getProcessMemoryInfo");
4640        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4641        for (int i=pids.length-1; i>=0; i--) {
4642            ProcessRecord proc;
4643            int oomAdj;
4644            synchronized (this) {
4645                synchronized (mPidsSelfLocked) {
4646                    proc = mPidsSelfLocked.get(pids[i]);
4647                    oomAdj = proc != null ? proc.setAdj : 0;
4648                }
4649            }
4650            infos[i] = new Debug.MemoryInfo();
4651            Debug.getMemoryInfo(pids[i], infos[i]);
4652            if (proc != null) {
4653                synchronized (this) {
4654                    if (proc.thread != null && proc.setAdj == oomAdj) {
4655                        // Record this for posterity if the process has been stable.
4656                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4657                                infos[i].getTotalUss(), false, proc.pkgList);
4658                    }
4659                }
4660            }
4661        }
4662        return infos;
4663    }
4664
4665    @Override
4666    public long[] getProcessPss(int[] pids) {
4667        enforceNotIsolatedCaller("getProcessPss");
4668        long[] pss = new long[pids.length];
4669        for (int i=pids.length-1; i>=0; i--) {
4670            ProcessRecord proc;
4671            int oomAdj;
4672            synchronized (this) {
4673                synchronized (mPidsSelfLocked) {
4674                    proc = mPidsSelfLocked.get(pids[i]);
4675                    oomAdj = proc != null ? proc.setAdj : 0;
4676                }
4677            }
4678            long[] tmpUss = new long[1];
4679            pss[i] = Debug.getPss(pids[i], tmpUss);
4680            if (proc != null) {
4681                synchronized (this) {
4682                    if (proc.thread != null && proc.setAdj == oomAdj) {
4683                        // Record this for posterity if the process has been stable.
4684                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4685                    }
4686                }
4687            }
4688        }
4689        return pss;
4690    }
4691
4692    @Override
4693    public void killApplicationProcess(String processName, int uid) {
4694        if (processName == null) {
4695            return;
4696        }
4697
4698        int callerUid = Binder.getCallingUid();
4699        // Only the system server can kill an application
4700        if (callerUid == Process.SYSTEM_UID) {
4701            synchronized (this) {
4702                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4703                if (app != null && app.thread != null) {
4704                    try {
4705                        app.thread.scheduleSuicide();
4706                    } catch (RemoteException e) {
4707                        // If the other end already died, then our work here is done.
4708                    }
4709                } else {
4710                    Slog.w(TAG, "Process/uid not found attempting kill of "
4711                            + processName + " / " + uid);
4712                }
4713            }
4714        } else {
4715            throw new SecurityException(callerUid + " cannot kill app process: " +
4716                    processName);
4717        }
4718    }
4719
4720    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4721        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4722                false, true, false, false, UserHandle.getUserId(uid), reason);
4723        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4724                Uri.fromParts("package", packageName, null));
4725        if (!mProcessesReady) {
4726            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4727                    | Intent.FLAG_RECEIVER_FOREGROUND);
4728        }
4729        intent.putExtra(Intent.EXTRA_UID, uid);
4730        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4731        broadcastIntentLocked(null, null, intent,
4732                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4733                false, false,
4734                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4735    }
4736
4737    private void forceStopUserLocked(int userId, String reason) {
4738        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4739        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4740        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4741                | Intent.FLAG_RECEIVER_FOREGROUND);
4742        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4743        broadcastIntentLocked(null, null, intent,
4744                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4745                false, false,
4746                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4747    }
4748
4749    private final boolean killPackageProcessesLocked(String packageName, int appId,
4750            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4751            boolean doit, boolean evenPersistent, String reason) {
4752        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4753
4754        // Remove all processes this package may have touched: all with the
4755        // same UID (except for the system or root user), and all whose name
4756        // matches the package name.
4757        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4758        final int NP = mProcessNames.getMap().size();
4759        for (int ip=0; ip<NP; ip++) {
4760            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4761            final int NA = apps.size();
4762            for (int ia=0; ia<NA; ia++) {
4763                ProcessRecord app = apps.valueAt(ia);
4764                if (app.persistent && !evenPersistent) {
4765                    // we don't kill persistent processes
4766                    continue;
4767                }
4768                if (app.removed) {
4769                    if (doit) {
4770                        procs.add(app);
4771                    }
4772                    continue;
4773                }
4774
4775                // Skip process if it doesn't meet our oom adj requirement.
4776                if (app.setAdj < minOomAdj) {
4777                    continue;
4778                }
4779
4780                // If no package is specified, we call all processes under the
4781                // give user id.
4782                if (packageName == null) {
4783                    if (app.userId != userId) {
4784                        continue;
4785                    }
4786                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4787                        continue;
4788                    }
4789                // Package has been specified, we want to hit all processes
4790                // that match it.  We need to qualify this by the processes
4791                // that are running under the specified app and user ID.
4792                } else {
4793                    if (UserHandle.getAppId(app.uid) != appId) {
4794                        continue;
4795                    }
4796                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4797                        continue;
4798                    }
4799                    if (!app.pkgList.containsKey(packageName)) {
4800                        continue;
4801                    }
4802                }
4803
4804                // Process has passed all conditions, kill it!
4805                if (!doit) {
4806                    return true;
4807                }
4808                app.removed = true;
4809                procs.add(app);
4810            }
4811        }
4812
4813        int N = procs.size();
4814        for (int i=0; i<N; i++) {
4815            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4816        }
4817        updateOomAdjLocked();
4818        return N > 0;
4819    }
4820
4821    private final boolean forceStopPackageLocked(String name, int appId,
4822            boolean callerWillRestart, boolean purgeCache, boolean doit,
4823            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4824        int i;
4825        int N;
4826
4827        if (userId == UserHandle.USER_ALL && name == null) {
4828            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4829        }
4830
4831        if (appId < 0 && name != null) {
4832            try {
4833                appId = UserHandle.getAppId(
4834                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4835            } catch (RemoteException e) {
4836            }
4837        }
4838
4839        if (doit) {
4840            if (name != null) {
4841                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4842                        + " user=" + userId + ": " + reason);
4843            } else {
4844                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4845            }
4846
4847            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4848            for (int ip=pmap.size()-1; ip>=0; ip--) {
4849                SparseArray<Long> ba = pmap.valueAt(ip);
4850                for (i=ba.size()-1; i>=0; i--) {
4851                    boolean remove = false;
4852                    final int entUid = ba.keyAt(i);
4853                    if (name != null) {
4854                        if (userId == UserHandle.USER_ALL) {
4855                            if (UserHandle.getAppId(entUid) == appId) {
4856                                remove = true;
4857                            }
4858                        } else {
4859                            if (entUid == UserHandle.getUid(userId, appId)) {
4860                                remove = true;
4861                            }
4862                        }
4863                    } else if (UserHandle.getUserId(entUid) == userId) {
4864                        remove = true;
4865                    }
4866                    if (remove) {
4867                        ba.removeAt(i);
4868                    }
4869                }
4870                if (ba.size() == 0) {
4871                    pmap.removeAt(ip);
4872                }
4873            }
4874        }
4875
4876        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4877                -100, callerWillRestart, true, doit, evenPersistent,
4878                name == null ? ("stop user " + userId) : ("stop " + name));
4879
4880        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4881            if (!doit) {
4882                return true;
4883            }
4884            didSomething = true;
4885        }
4886
4887        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4888            if (!doit) {
4889                return true;
4890            }
4891            didSomething = true;
4892        }
4893
4894        if (name == null) {
4895            // Remove all sticky broadcasts from this user.
4896            mStickyBroadcasts.remove(userId);
4897        }
4898
4899        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4900        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4901                userId, providers)) {
4902            if (!doit) {
4903                return true;
4904            }
4905            didSomething = true;
4906        }
4907        N = providers.size();
4908        for (i=0; i<N; i++) {
4909            removeDyingProviderLocked(null, providers.get(i), true);
4910        }
4911
4912        // Remove transient permissions granted from/to this package/user
4913        removeUriPermissionsForPackageLocked(name, userId, false);
4914
4915        if (name == null || uninstalling) {
4916            // Remove pending intents.  For now we only do this when force
4917            // stopping users, because we have some problems when doing this
4918            // for packages -- app widgets are not currently cleaned up for
4919            // such packages, so they can be left with bad pending intents.
4920            if (mIntentSenderRecords.size() > 0) {
4921                Iterator<WeakReference<PendingIntentRecord>> it
4922                        = mIntentSenderRecords.values().iterator();
4923                while (it.hasNext()) {
4924                    WeakReference<PendingIntentRecord> wpir = it.next();
4925                    if (wpir == null) {
4926                        it.remove();
4927                        continue;
4928                    }
4929                    PendingIntentRecord pir = wpir.get();
4930                    if (pir == null) {
4931                        it.remove();
4932                        continue;
4933                    }
4934                    if (name == null) {
4935                        // Stopping user, remove all objects for the user.
4936                        if (pir.key.userId != userId) {
4937                            // Not the same user, skip it.
4938                            continue;
4939                        }
4940                    } else {
4941                        if (UserHandle.getAppId(pir.uid) != appId) {
4942                            // Different app id, skip it.
4943                            continue;
4944                        }
4945                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4946                            // Different user, skip it.
4947                            continue;
4948                        }
4949                        if (!pir.key.packageName.equals(name)) {
4950                            // Different package, skip it.
4951                            continue;
4952                        }
4953                    }
4954                    if (!doit) {
4955                        return true;
4956                    }
4957                    didSomething = true;
4958                    it.remove();
4959                    pir.canceled = true;
4960                    if (pir.key.activity != null) {
4961                        pir.key.activity.pendingResults.remove(pir.ref);
4962                    }
4963                }
4964            }
4965        }
4966
4967        if (doit) {
4968            if (purgeCache && name != null) {
4969                AttributeCache ac = AttributeCache.instance();
4970                if (ac != null) {
4971                    ac.removePackage(name);
4972                }
4973            }
4974            if (mBooted) {
4975                mStackSupervisor.resumeTopActivitiesLocked();
4976                mStackSupervisor.scheduleIdleLocked();
4977            }
4978        }
4979
4980        return didSomething;
4981    }
4982
4983    private final boolean removeProcessLocked(ProcessRecord app,
4984            boolean callerWillRestart, boolean allowRestart, String reason) {
4985        final String name = app.processName;
4986        final int uid = app.uid;
4987        if (DEBUG_PROCESSES) Slog.d(
4988            TAG, "Force removing proc " + app.toShortString() + " (" + name
4989            + "/" + uid + ")");
4990
4991        mProcessNames.remove(name, uid);
4992        mIsolatedProcesses.remove(app.uid);
4993        if (mHeavyWeightProcess == app) {
4994            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4995                    mHeavyWeightProcess.userId, 0));
4996            mHeavyWeightProcess = null;
4997        }
4998        boolean needRestart = false;
4999        if (app.pid > 0 && app.pid != MY_PID) {
5000            int pid = app.pid;
5001            synchronized (mPidsSelfLocked) {
5002                mPidsSelfLocked.remove(pid);
5003                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5004            }
5005            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5006                    app.processName, app.info.uid);
5007            if (app.isolated) {
5008                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5009            }
5010            killUnneededProcessLocked(app, reason);
5011            handleAppDiedLocked(app, true, allowRestart);
5012            removeLruProcessLocked(app);
5013
5014            if (app.persistent && !app.isolated) {
5015                if (!callerWillRestart) {
5016                    addAppLocked(app.info, false);
5017                } else {
5018                    needRestart = true;
5019                }
5020            }
5021        } else {
5022            mRemovedProcesses.add(app);
5023        }
5024
5025        return needRestart;
5026    }
5027
5028    private final void processStartTimedOutLocked(ProcessRecord app) {
5029        final int pid = app.pid;
5030        boolean gone = false;
5031        synchronized (mPidsSelfLocked) {
5032            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5033            if (knownApp != null && knownApp.thread == null) {
5034                mPidsSelfLocked.remove(pid);
5035                gone = true;
5036            }
5037        }
5038
5039        if (gone) {
5040            Slog.w(TAG, "Process " + app + " failed to attach");
5041            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5042                    pid, app.uid, app.processName);
5043            mProcessNames.remove(app.processName, app.uid);
5044            mIsolatedProcesses.remove(app.uid);
5045            if (mHeavyWeightProcess == app) {
5046                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5047                        mHeavyWeightProcess.userId, 0));
5048                mHeavyWeightProcess = null;
5049            }
5050            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5051                    app.processName, app.info.uid);
5052            if (app.isolated) {
5053                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5054            }
5055            // Take care of any launching providers waiting for this process.
5056            checkAppInLaunchingProvidersLocked(app, true);
5057            // Take care of any services that are waiting for the process.
5058            mServices.processStartTimedOutLocked(app);
5059            killUnneededProcessLocked(app, "start timeout");
5060            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5061                Slog.w(TAG, "Unattached app died before backup, skipping");
5062                try {
5063                    IBackupManager bm = IBackupManager.Stub.asInterface(
5064                            ServiceManager.getService(Context.BACKUP_SERVICE));
5065                    bm.agentDisconnected(app.info.packageName);
5066                } catch (RemoteException e) {
5067                    // Can't happen; the backup manager is local
5068                }
5069            }
5070            if (isPendingBroadcastProcessLocked(pid)) {
5071                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5072                skipPendingBroadcastLocked(pid);
5073            }
5074        } else {
5075            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5076        }
5077    }
5078
5079    private final boolean attachApplicationLocked(IApplicationThread thread,
5080            int pid) {
5081
5082        // Find the application record that is being attached...  either via
5083        // the pid if we are running in multiple processes, or just pull the
5084        // next app record if we are emulating process with anonymous threads.
5085        ProcessRecord app;
5086        if (pid != MY_PID && pid >= 0) {
5087            synchronized (mPidsSelfLocked) {
5088                app = mPidsSelfLocked.get(pid);
5089            }
5090        } else {
5091            app = null;
5092        }
5093
5094        if (app == null) {
5095            Slog.w(TAG, "No pending application record for pid " + pid
5096                    + " (IApplicationThread " + thread + "); dropping process");
5097            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5098            if (pid > 0 && pid != MY_PID) {
5099                Process.killProcessQuiet(pid);
5100            } else {
5101                try {
5102                    thread.scheduleExit();
5103                } catch (Exception e) {
5104                    // Ignore exceptions.
5105                }
5106            }
5107            return false;
5108        }
5109
5110        // If this application record is still attached to a previous
5111        // process, clean it up now.
5112        if (app.thread != null) {
5113            handleAppDiedLocked(app, true, true);
5114        }
5115
5116        // Tell the process all about itself.
5117
5118        if (localLOGV) Slog.v(
5119                TAG, "Binding process pid " + pid + " to record " + app);
5120
5121        final String processName = app.processName;
5122        try {
5123            AppDeathRecipient adr = new AppDeathRecipient(
5124                    app, pid, thread);
5125            thread.asBinder().linkToDeath(adr, 0);
5126            app.deathRecipient = adr;
5127        } catch (RemoteException e) {
5128            app.resetPackageList(mProcessStats);
5129            startProcessLocked(app, "link fail", processName);
5130            return false;
5131        }
5132
5133        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5134
5135        app.makeActive(thread, mProcessStats);
5136        app.curAdj = app.setAdj = -100;
5137        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5138        app.forcingToForeground = null;
5139        updateProcessForegroundLocked(app, false, false);
5140        app.hasShownUi = false;
5141        app.debugging = false;
5142        app.cached = false;
5143
5144        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5145
5146        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5147        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5148
5149        if (!normalMode) {
5150            Slog.i(TAG, "Launching preboot mode app: " + app);
5151        }
5152
5153        if (localLOGV) Slog.v(
5154            TAG, "New app record " + app
5155            + " thread=" + thread.asBinder() + " pid=" + pid);
5156        try {
5157            int testMode = IApplicationThread.DEBUG_OFF;
5158            if (mDebugApp != null && mDebugApp.equals(processName)) {
5159                testMode = mWaitForDebugger
5160                    ? IApplicationThread.DEBUG_WAIT
5161                    : IApplicationThread.DEBUG_ON;
5162                app.debugging = true;
5163                if (mDebugTransient) {
5164                    mDebugApp = mOrigDebugApp;
5165                    mWaitForDebugger = mOrigWaitForDebugger;
5166                }
5167            }
5168            String profileFile = app.instrumentationProfileFile;
5169            ParcelFileDescriptor profileFd = null;
5170            boolean profileAutoStop = false;
5171            if (mProfileApp != null && mProfileApp.equals(processName)) {
5172                mProfileProc = app;
5173                profileFile = mProfileFile;
5174                profileFd = mProfileFd;
5175                profileAutoStop = mAutoStopProfiler;
5176            }
5177            boolean enableOpenGlTrace = false;
5178            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5179                enableOpenGlTrace = true;
5180                mOpenGlTraceApp = null;
5181            }
5182
5183            // If the app is being launched for restore or full backup, set it up specially
5184            boolean isRestrictedBackupMode = false;
5185            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5186                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5187                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5188                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5189            }
5190
5191            ensurePackageDexOpt(app.instrumentationInfo != null
5192                    ? app.instrumentationInfo.packageName
5193                    : app.info.packageName);
5194            if (app.instrumentationClass != null) {
5195                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5196            }
5197            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5198                    + processName + " with config " + mConfiguration);
5199            ApplicationInfo appInfo = app.instrumentationInfo != null
5200                    ? app.instrumentationInfo : app.info;
5201            app.compat = compatibilityInfoForPackageLocked(appInfo);
5202            if (profileFd != null) {
5203                profileFd = profileFd.dup();
5204            }
5205            thread.bindApplication(processName, appInfo, providers,
5206                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5207                    app.instrumentationArguments, app.instrumentationWatcher,
5208                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5209                    isRestrictedBackupMode || !normalMode, app.persistent,
5210                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5211                    mCoreSettingsObserver.getCoreSettingsLocked());
5212            updateLruProcessLocked(app, false, null);
5213            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5214        } catch (Exception e) {
5215            // todo: Yikes!  What should we do?  For now we will try to
5216            // start another process, but that could easily get us in
5217            // an infinite loop of restarting processes...
5218            Slog.w(TAG, "Exception thrown during bind!", e);
5219
5220            app.resetPackageList(mProcessStats);
5221            app.unlinkDeathRecipient();
5222            startProcessLocked(app, "bind fail", processName);
5223            return false;
5224        }
5225
5226        // Remove this record from the list of starting applications.
5227        mPersistentStartingProcesses.remove(app);
5228        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5229                "Attach application locked removing on hold: " + app);
5230        mProcessesOnHold.remove(app);
5231
5232        boolean badApp = false;
5233        boolean didSomething = false;
5234
5235        // See if the top visible activity is waiting to run in this process...
5236        if (normalMode) {
5237            try {
5238                if (mStackSupervisor.attachApplicationLocked(app)) {
5239                    didSomething = true;
5240                }
5241            } catch (Exception e) {
5242                badApp = true;
5243            }
5244        }
5245
5246        // Find any services that should be running in this process...
5247        if (!badApp) {
5248            try {
5249                didSomething |= mServices.attachApplicationLocked(app, processName);
5250            } catch (Exception e) {
5251                badApp = true;
5252            }
5253        }
5254
5255        // Check if a next-broadcast receiver is in this process...
5256        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5257            try {
5258                didSomething |= sendPendingBroadcastsLocked(app);
5259            } catch (Exception e) {
5260                // If the app died trying to launch the receiver we declare it 'bad'
5261                badApp = true;
5262            }
5263        }
5264
5265        // Check whether the next backup agent is in this process...
5266        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5267            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5268            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5269            try {
5270                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5271                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5272                        mBackupTarget.backupMode);
5273            } catch (Exception e) {
5274                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5275                e.printStackTrace();
5276            }
5277        }
5278
5279        if (badApp) {
5280            // todo: Also need to kill application to deal with all
5281            // kinds of exceptions.
5282            handleAppDiedLocked(app, false, true);
5283            return false;
5284        }
5285
5286        if (!didSomething) {
5287            updateOomAdjLocked();
5288        }
5289
5290        return true;
5291    }
5292
5293    @Override
5294    public final void attachApplication(IApplicationThread thread) {
5295        synchronized (this) {
5296            int callingPid = Binder.getCallingPid();
5297            final long origId = Binder.clearCallingIdentity();
5298            attachApplicationLocked(thread, callingPid);
5299            Binder.restoreCallingIdentity(origId);
5300        }
5301    }
5302
5303    @Override
5304    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5305        final long origId = Binder.clearCallingIdentity();
5306        synchronized (this) {
5307            ActivityStack stack = ActivityRecord.getStackLocked(token);
5308            if (stack != null) {
5309                ActivityRecord r =
5310                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5311                if (stopProfiling) {
5312                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5313                        try {
5314                            mProfileFd.close();
5315                        } catch (IOException e) {
5316                        }
5317                        clearProfilerLocked();
5318                    }
5319                }
5320            }
5321        }
5322        Binder.restoreCallingIdentity(origId);
5323    }
5324
5325    void enableScreenAfterBoot() {
5326        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5327                SystemClock.uptimeMillis());
5328        mWindowManager.enableScreenAfterBoot();
5329
5330        synchronized (this) {
5331            updateEventDispatchingLocked();
5332        }
5333    }
5334
5335    @Override
5336    public void showBootMessage(final CharSequence msg, final boolean always) {
5337        enforceNotIsolatedCaller("showBootMessage");
5338        mWindowManager.showBootMessage(msg, always);
5339    }
5340
5341    @Override
5342    public void dismissKeyguardOnNextActivity() {
5343        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5344        final long token = Binder.clearCallingIdentity();
5345        try {
5346            synchronized (this) {
5347                if (DEBUG_LOCKSCREEN) logLockScreen("");
5348                if (mLockScreenShown) {
5349                    mLockScreenShown = false;
5350                    comeOutOfSleepIfNeededLocked();
5351                }
5352                mStackSupervisor.setDismissKeyguard(true);
5353            }
5354        } finally {
5355            Binder.restoreCallingIdentity(token);
5356        }
5357    }
5358
5359    final void finishBooting() {
5360        // Register receivers to handle package update events
5361        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5362
5363        synchronized (this) {
5364            // Ensure that any processes we had put on hold are now started
5365            // up.
5366            final int NP = mProcessesOnHold.size();
5367            if (NP > 0) {
5368                ArrayList<ProcessRecord> procs =
5369                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5370                for (int ip=0; ip<NP; ip++) {
5371                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5372                            + procs.get(ip));
5373                    startProcessLocked(procs.get(ip), "on-hold", null);
5374                }
5375            }
5376
5377            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5378                // Start looking for apps that are abusing wake locks.
5379                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5380                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5381                // Tell anyone interested that we are done booting!
5382                SystemProperties.set("sys.boot_completed", "1");
5383                SystemProperties.set("dev.bootcomplete", "1");
5384                for (int i=0; i<mStartedUsers.size(); i++) {
5385                    UserStartedState uss = mStartedUsers.valueAt(i);
5386                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5387                        uss.mState = UserStartedState.STATE_RUNNING;
5388                        final int userId = mStartedUsers.keyAt(i);
5389                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5390                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5391                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5392                        broadcastIntentLocked(null, null, intent, null,
5393                                new IIntentReceiver.Stub() {
5394                                    @Override
5395                                    public void performReceive(Intent intent, int resultCode,
5396                                            String data, Bundle extras, boolean ordered,
5397                                            boolean sticky, int sendingUser) {
5398                                        synchronized (ActivityManagerService.this) {
5399                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5400                                                    true, false);
5401                                        }
5402                                    }
5403                                },
5404                                0, null, null,
5405                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5406                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5407                                userId);
5408                    }
5409                }
5410                scheduleStartProfilesLocked();
5411            }
5412        }
5413    }
5414
5415    final void ensureBootCompleted() {
5416        boolean booting;
5417        boolean enableScreen;
5418        synchronized (this) {
5419            booting = mBooting;
5420            mBooting = false;
5421            enableScreen = !mBooted;
5422            mBooted = true;
5423        }
5424
5425        if (booting) {
5426            finishBooting();
5427        }
5428
5429        if (enableScreen) {
5430            enableScreenAfterBoot();
5431        }
5432    }
5433
5434    @Override
5435    public final void activityResumed(IBinder token) {
5436        final long origId = Binder.clearCallingIdentity();
5437        synchronized(this) {
5438            ActivityStack stack = ActivityRecord.getStackLocked(token);
5439            if (stack != null) {
5440                ActivityRecord.activityResumedLocked(token);
5441            }
5442        }
5443        Binder.restoreCallingIdentity(origId);
5444    }
5445
5446    @Override
5447    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5448        final long origId = Binder.clearCallingIdentity();
5449        synchronized(this) {
5450            ActivityStack stack = ActivityRecord.getStackLocked(token);
5451            if (stack != null) {
5452                stack.activityPausedLocked(token, false, persistentState);
5453            }
5454        }
5455        Binder.restoreCallingIdentity(origId);
5456    }
5457
5458    @Override
5459    public final void activityStopped(IBinder token, Bundle icicle,
5460            PersistableBundle persistentState, CharSequence description) {
5461        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5462
5463        // Refuse possible leaked file descriptors
5464        if (icicle != null && icicle.hasFileDescriptors()) {
5465            throw new IllegalArgumentException("File descriptors passed in Bundle");
5466        }
5467
5468        final long origId = Binder.clearCallingIdentity();
5469
5470        synchronized (this) {
5471            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5472            if (r != null) {
5473                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5474            }
5475        }
5476
5477        trimApplications();
5478
5479        Binder.restoreCallingIdentity(origId);
5480    }
5481
5482    @Override
5483    public final void activityDestroyed(IBinder token) {
5484        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5485        synchronized (this) {
5486            ActivityStack stack = ActivityRecord.getStackLocked(token);
5487            if (stack != null) {
5488                stack.activityDestroyedLocked(token);
5489            }
5490        }
5491    }
5492
5493    @Override
5494    public String getCallingPackage(IBinder token) {
5495        synchronized (this) {
5496            ActivityRecord r = getCallingRecordLocked(token);
5497            return r != null ? r.info.packageName : null;
5498        }
5499    }
5500
5501    @Override
5502    public ComponentName getCallingActivity(IBinder token) {
5503        synchronized (this) {
5504            ActivityRecord r = getCallingRecordLocked(token);
5505            return r != null ? r.intent.getComponent() : null;
5506        }
5507    }
5508
5509    private ActivityRecord getCallingRecordLocked(IBinder token) {
5510        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5511        if (r == null) {
5512            return null;
5513        }
5514        return r.resultTo;
5515    }
5516
5517    @Override
5518    public ComponentName getActivityClassForToken(IBinder token) {
5519        synchronized(this) {
5520            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5521            if (r == null) {
5522                return null;
5523            }
5524            return r.intent.getComponent();
5525        }
5526    }
5527
5528    @Override
5529    public String getPackageForToken(IBinder token) {
5530        synchronized(this) {
5531            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5532            if (r == null) {
5533                return null;
5534            }
5535            return r.packageName;
5536        }
5537    }
5538
5539    @Override
5540    public IIntentSender getIntentSender(int type,
5541            String packageName, IBinder token, String resultWho,
5542            int requestCode, Intent[] intents, String[] resolvedTypes,
5543            int flags, Bundle options, int userId) {
5544        enforceNotIsolatedCaller("getIntentSender");
5545        // Refuse possible leaked file descriptors
5546        if (intents != null) {
5547            if (intents.length < 1) {
5548                throw new IllegalArgumentException("Intents array length must be >= 1");
5549            }
5550            for (int i=0; i<intents.length; i++) {
5551                Intent intent = intents[i];
5552                if (intent != null) {
5553                    if (intent.hasFileDescriptors()) {
5554                        throw new IllegalArgumentException("File descriptors passed in Intent");
5555                    }
5556                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5557                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5558                        throw new IllegalArgumentException(
5559                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5560                    }
5561                    intents[i] = new Intent(intent);
5562                }
5563            }
5564            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5565                throw new IllegalArgumentException(
5566                        "Intent array length does not match resolvedTypes length");
5567            }
5568        }
5569        if (options != null) {
5570            if (options.hasFileDescriptors()) {
5571                throw new IllegalArgumentException("File descriptors passed in options");
5572            }
5573        }
5574
5575        synchronized(this) {
5576            int callingUid = Binder.getCallingUid();
5577            int origUserId = userId;
5578            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5579                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5580                    "getIntentSender", null);
5581            if (origUserId == UserHandle.USER_CURRENT) {
5582                // We don't want to evaluate this until the pending intent is
5583                // actually executed.  However, we do want to always do the
5584                // security checking for it above.
5585                userId = UserHandle.USER_CURRENT;
5586            }
5587            try {
5588                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5589                    int uid = AppGlobals.getPackageManager()
5590                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5591                    if (!UserHandle.isSameApp(callingUid, uid)) {
5592                        String msg = "Permission Denial: getIntentSender() from pid="
5593                            + Binder.getCallingPid()
5594                            + ", uid=" + Binder.getCallingUid()
5595                            + ", (need uid=" + uid + ")"
5596                            + " is not allowed to send as package " + packageName;
5597                        Slog.w(TAG, msg);
5598                        throw new SecurityException(msg);
5599                    }
5600                }
5601
5602                return getIntentSenderLocked(type, packageName, callingUid, userId,
5603                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5604
5605            } catch (RemoteException e) {
5606                throw new SecurityException(e);
5607            }
5608        }
5609    }
5610
5611    IIntentSender getIntentSenderLocked(int type, String packageName,
5612            int callingUid, int userId, IBinder token, String resultWho,
5613            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5614            Bundle options) {
5615        if (DEBUG_MU)
5616            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5617        ActivityRecord activity = null;
5618        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5619            activity = ActivityRecord.isInStackLocked(token);
5620            if (activity == null) {
5621                return null;
5622            }
5623            if (activity.finishing) {
5624                return null;
5625            }
5626        }
5627
5628        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5629        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5630        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5631        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5632                |PendingIntent.FLAG_UPDATE_CURRENT);
5633
5634        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5635                type, packageName, activity, resultWho,
5636                requestCode, intents, resolvedTypes, flags, options, userId);
5637        WeakReference<PendingIntentRecord> ref;
5638        ref = mIntentSenderRecords.get(key);
5639        PendingIntentRecord rec = ref != null ? ref.get() : null;
5640        if (rec != null) {
5641            if (!cancelCurrent) {
5642                if (updateCurrent) {
5643                    if (rec.key.requestIntent != null) {
5644                        rec.key.requestIntent.replaceExtras(intents != null ?
5645                                intents[intents.length - 1] : null);
5646                    }
5647                    if (intents != null) {
5648                        intents[intents.length-1] = rec.key.requestIntent;
5649                        rec.key.allIntents = intents;
5650                        rec.key.allResolvedTypes = resolvedTypes;
5651                    } else {
5652                        rec.key.allIntents = null;
5653                        rec.key.allResolvedTypes = null;
5654                    }
5655                }
5656                return rec;
5657            }
5658            rec.canceled = true;
5659            mIntentSenderRecords.remove(key);
5660        }
5661        if (noCreate) {
5662            return rec;
5663        }
5664        rec = new PendingIntentRecord(this, key, callingUid);
5665        mIntentSenderRecords.put(key, rec.ref);
5666        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5667            if (activity.pendingResults == null) {
5668                activity.pendingResults
5669                        = new HashSet<WeakReference<PendingIntentRecord>>();
5670            }
5671            activity.pendingResults.add(rec.ref);
5672        }
5673        return rec;
5674    }
5675
5676    @Override
5677    public void cancelIntentSender(IIntentSender sender) {
5678        if (!(sender instanceof PendingIntentRecord)) {
5679            return;
5680        }
5681        synchronized(this) {
5682            PendingIntentRecord rec = (PendingIntentRecord)sender;
5683            try {
5684                int uid = AppGlobals.getPackageManager()
5685                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5686                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5687                    String msg = "Permission Denial: cancelIntentSender() from pid="
5688                        + Binder.getCallingPid()
5689                        + ", uid=" + Binder.getCallingUid()
5690                        + " is not allowed to cancel packges "
5691                        + rec.key.packageName;
5692                    Slog.w(TAG, msg);
5693                    throw new SecurityException(msg);
5694                }
5695            } catch (RemoteException e) {
5696                throw new SecurityException(e);
5697            }
5698            cancelIntentSenderLocked(rec, true);
5699        }
5700    }
5701
5702    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5703        rec.canceled = true;
5704        mIntentSenderRecords.remove(rec.key);
5705        if (cleanActivity && rec.key.activity != null) {
5706            rec.key.activity.pendingResults.remove(rec.ref);
5707        }
5708    }
5709
5710    @Override
5711    public String getPackageForIntentSender(IIntentSender pendingResult) {
5712        if (!(pendingResult instanceof PendingIntentRecord)) {
5713            return null;
5714        }
5715        try {
5716            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5717            return res.key.packageName;
5718        } catch (ClassCastException e) {
5719        }
5720        return null;
5721    }
5722
5723    @Override
5724    public int getUidForIntentSender(IIntentSender sender) {
5725        if (sender instanceof PendingIntentRecord) {
5726            try {
5727                PendingIntentRecord res = (PendingIntentRecord)sender;
5728                return res.uid;
5729            } catch (ClassCastException e) {
5730            }
5731        }
5732        return -1;
5733    }
5734
5735    @Override
5736    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5737        if (!(pendingResult instanceof PendingIntentRecord)) {
5738            return false;
5739        }
5740        try {
5741            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5742            if (res.key.allIntents == null) {
5743                return false;
5744            }
5745            for (int i=0; i<res.key.allIntents.length; i++) {
5746                Intent intent = res.key.allIntents[i];
5747                if (intent.getPackage() != null && intent.getComponent() != null) {
5748                    return false;
5749                }
5750            }
5751            return true;
5752        } catch (ClassCastException e) {
5753        }
5754        return false;
5755    }
5756
5757    @Override
5758    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5759        if (!(pendingResult instanceof PendingIntentRecord)) {
5760            return false;
5761        }
5762        try {
5763            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5764            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5765                return true;
5766            }
5767            return false;
5768        } catch (ClassCastException e) {
5769        }
5770        return false;
5771    }
5772
5773    @Override
5774    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5775        if (!(pendingResult instanceof PendingIntentRecord)) {
5776            return null;
5777        }
5778        try {
5779            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5780            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5781        } catch (ClassCastException e) {
5782        }
5783        return null;
5784    }
5785
5786    @Override
5787    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5788        if (!(pendingResult instanceof PendingIntentRecord)) {
5789            return null;
5790        }
5791        try {
5792            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5793            Intent intent = res.key.requestIntent;
5794            if (intent != null) {
5795                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5796                        || res.lastTagPrefix.equals(prefix))) {
5797                    return res.lastTag;
5798                }
5799                res.lastTagPrefix = prefix;
5800                StringBuilder sb = new StringBuilder(128);
5801                if (prefix != null) {
5802                    sb.append(prefix);
5803                }
5804                if (intent.getAction() != null) {
5805                    sb.append(intent.getAction());
5806                } else if (intent.getComponent() != null) {
5807                    intent.getComponent().appendShortString(sb);
5808                } else {
5809                    sb.append("?");
5810                }
5811                return res.lastTag = sb.toString();
5812            }
5813        } catch (ClassCastException e) {
5814        }
5815        return null;
5816    }
5817
5818    @Override
5819    public void setProcessLimit(int max) {
5820        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5821                "setProcessLimit()");
5822        synchronized (this) {
5823            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5824            mProcessLimitOverride = max;
5825        }
5826        trimApplications();
5827    }
5828
5829    @Override
5830    public int getProcessLimit() {
5831        synchronized (this) {
5832            return mProcessLimitOverride;
5833        }
5834    }
5835
5836    void foregroundTokenDied(ForegroundToken token) {
5837        synchronized (ActivityManagerService.this) {
5838            synchronized (mPidsSelfLocked) {
5839                ForegroundToken cur
5840                    = mForegroundProcesses.get(token.pid);
5841                if (cur != token) {
5842                    return;
5843                }
5844                mForegroundProcesses.remove(token.pid);
5845                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5846                if (pr == null) {
5847                    return;
5848                }
5849                pr.forcingToForeground = null;
5850                updateProcessForegroundLocked(pr, false, false);
5851            }
5852            updateOomAdjLocked();
5853        }
5854    }
5855
5856    @Override
5857    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5858        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5859                "setProcessForeground()");
5860        synchronized(this) {
5861            boolean changed = false;
5862
5863            synchronized (mPidsSelfLocked) {
5864                ProcessRecord pr = mPidsSelfLocked.get(pid);
5865                if (pr == null && isForeground) {
5866                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5867                    return;
5868                }
5869                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5870                if (oldToken != null) {
5871                    oldToken.token.unlinkToDeath(oldToken, 0);
5872                    mForegroundProcesses.remove(pid);
5873                    if (pr != null) {
5874                        pr.forcingToForeground = null;
5875                    }
5876                    changed = true;
5877                }
5878                if (isForeground && token != null) {
5879                    ForegroundToken newToken = new ForegroundToken() {
5880                        @Override
5881                        public void binderDied() {
5882                            foregroundTokenDied(this);
5883                        }
5884                    };
5885                    newToken.pid = pid;
5886                    newToken.token = token;
5887                    try {
5888                        token.linkToDeath(newToken, 0);
5889                        mForegroundProcesses.put(pid, newToken);
5890                        pr.forcingToForeground = token;
5891                        changed = true;
5892                    } catch (RemoteException e) {
5893                        // If the process died while doing this, we will later
5894                        // do the cleanup with the process death link.
5895                    }
5896                }
5897            }
5898
5899            if (changed) {
5900                updateOomAdjLocked();
5901            }
5902        }
5903    }
5904
5905    // =========================================================
5906    // PERMISSIONS
5907    // =========================================================
5908
5909    static class PermissionController extends IPermissionController.Stub {
5910        ActivityManagerService mActivityManagerService;
5911        PermissionController(ActivityManagerService activityManagerService) {
5912            mActivityManagerService = activityManagerService;
5913        }
5914
5915        @Override
5916        public boolean checkPermission(String permission, int pid, int uid) {
5917            return mActivityManagerService.checkPermission(permission, pid,
5918                    uid) == PackageManager.PERMISSION_GRANTED;
5919        }
5920    }
5921
5922    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5923        @Override
5924        public int checkComponentPermission(String permission, int pid, int uid,
5925                int owningUid, boolean exported) {
5926            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5927                    owningUid, exported);
5928        }
5929
5930        @Override
5931        public Object getAMSLock() {
5932            return ActivityManagerService.this;
5933        }
5934    }
5935
5936    /**
5937     * This can be called with or without the global lock held.
5938     */
5939    int checkComponentPermission(String permission, int pid, int uid,
5940            int owningUid, boolean exported) {
5941        // We might be performing an operation on behalf of an indirect binder
5942        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5943        // client identity accordingly before proceeding.
5944        Identity tlsIdentity = sCallerIdentity.get();
5945        if (tlsIdentity != null) {
5946            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5947                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5948            uid = tlsIdentity.uid;
5949            pid = tlsIdentity.pid;
5950        }
5951
5952        if (pid == MY_PID) {
5953            return PackageManager.PERMISSION_GRANTED;
5954        }
5955
5956        return ActivityManager.checkComponentPermission(permission, uid,
5957                owningUid, exported);
5958    }
5959
5960    /**
5961     * As the only public entry point for permissions checking, this method
5962     * can enforce the semantic that requesting a check on a null global
5963     * permission is automatically denied.  (Internally a null permission
5964     * string is used when calling {@link #checkComponentPermission} in cases
5965     * when only uid-based security is needed.)
5966     *
5967     * This can be called with or without the global lock held.
5968     */
5969    @Override
5970    public int checkPermission(String permission, int pid, int uid) {
5971        if (permission == null) {
5972            return PackageManager.PERMISSION_DENIED;
5973        }
5974        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5975    }
5976
5977    /**
5978     * Binder IPC calls go through the public entry point.
5979     * This can be called with or without the global lock held.
5980     */
5981    int checkCallingPermission(String permission) {
5982        return checkPermission(permission,
5983                Binder.getCallingPid(),
5984                UserHandle.getAppId(Binder.getCallingUid()));
5985    }
5986
5987    /**
5988     * This can be called with or without the global lock held.
5989     */
5990    void enforceCallingPermission(String permission, String func) {
5991        if (checkCallingPermission(permission)
5992                == PackageManager.PERMISSION_GRANTED) {
5993            return;
5994        }
5995
5996        String msg = "Permission Denial: " + func + " from pid="
5997                + Binder.getCallingPid()
5998                + ", uid=" + Binder.getCallingUid()
5999                + " requires " + permission;
6000        Slog.w(TAG, msg);
6001        throw new SecurityException(msg);
6002    }
6003
6004    /**
6005     * Determine if UID is holding permissions required to access {@link Uri} in
6006     * the given {@link ProviderInfo}. Final permission checking is always done
6007     * in {@link ContentProvider}.
6008     */
6009    private final boolean checkHoldingPermissionsLocked(
6010            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6011        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6012                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6013
6014        if (pi.applicationInfo.uid == uid) {
6015            return true;
6016        } else if (!pi.exported) {
6017            return false;
6018        }
6019
6020        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6021        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6022        try {
6023            // check if target holds top-level <provider> permissions
6024            if (!readMet && pi.readPermission != null
6025                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6026                readMet = true;
6027            }
6028            if (!writeMet && pi.writePermission != null
6029                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6030                writeMet = true;
6031            }
6032
6033            // track if unprotected read/write is allowed; any denied
6034            // <path-permission> below removes this ability
6035            boolean allowDefaultRead = pi.readPermission == null;
6036            boolean allowDefaultWrite = pi.writePermission == null;
6037
6038            // check if target holds any <path-permission> that match uri
6039            final PathPermission[] pps = pi.pathPermissions;
6040            if (pps != null) {
6041                final String path = grantUri.uri.getPath();
6042                int i = pps.length;
6043                while (i > 0 && (!readMet || !writeMet)) {
6044                    i--;
6045                    PathPermission pp = pps[i];
6046                    if (pp.match(path)) {
6047                        if (!readMet) {
6048                            final String pprperm = pp.getReadPermission();
6049                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6050                                    + pprperm + " for " + pp.getPath()
6051                                    + ": match=" + pp.match(path)
6052                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6053                            if (pprperm != null) {
6054                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6055                                    readMet = true;
6056                                } else {
6057                                    allowDefaultRead = false;
6058                                }
6059                            }
6060                        }
6061                        if (!writeMet) {
6062                            final String ppwperm = pp.getWritePermission();
6063                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6064                                    + ppwperm + " for " + pp.getPath()
6065                                    + ": match=" + pp.match(path)
6066                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6067                            if (ppwperm != null) {
6068                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6069                                    writeMet = true;
6070                                } else {
6071                                    allowDefaultWrite = false;
6072                                }
6073                            }
6074                        }
6075                    }
6076                }
6077            }
6078
6079            // grant unprotected <provider> read/write, if not blocked by
6080            // <path-permission> above
6081            if (allowDefaultRead) readMet = true;
6082            if (allowDefaultWrite) writeMet = true;
6083
6084        } catch (RemoteException e) {
6085            return false;
6086        }
6087
6088        return readMet && writeMet;
6089    }
6090
6091    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6092        ProviderInfo pi = null;
6093        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6094        if (cpr != null) {
6095            pi = cpr.info;
6096        } else {
6097            try {
6098                pi = AppGlobals.getPackageManager().resolveContentProvider(
6099                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6100            } catch (RemoteException ex) {
6101            }
6102        }
6103        return pi;
6104    }
6105
6106    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6107        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6108        if (targetUris != null) {
6109            return targetUris.get(grantUri);
6110        }
6111        return null;
6112    }
6113
6114    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6115            String targetPkg, int targetUid, GrantUri grantUri) {
6116        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6117        if (targetUris == null) {
6118            targetUris = Maps.newArrayMap();
6119            mGrantedUriPermissions.put(targetUid, targetUris);
6120        }
6121
6122        UriPermission perm = targetUris.get(grantUri);
6123        if (perm == null) {
6124            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6125            targetUris.put(grantUri, perm);
6126        }
6127
6128        return perm;
6129    }
6130
6131    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6132            final int modeFlags) {
6133        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6134        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6135                : UriPermission.STRENGTH_OWNED;
6136
6137        // Root gets to do everything.
6138        if (uid == 0) {
6139            return true;
6140        }
6141
6142        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6143        if (perms == null) return false;
6144
6145        // First look for exact match
6146        final UriPermission exactPerm = perms.get(grantUri);
6147        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6148            return true;
6149        }
6150
6151        // No exact match, look for prefixes
6152        final int N = perms.size();
6153        for (int i = 0; i < N; i++) {
6154            final UriPermission perm = perms.valueAt(i);
6155            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6156                    && perm.getStrength(modeFlags) >= minStrength) {
6157                return true;
6158            }
6159        }
6160
6161        return false;
6162    }
6163
6164    @Override
6165    public int checkUriPermission(Uri uri, int pid, int uid,
6166            final int modeFlags, int userId) {
6167        enforceNotIsolatedCaller("checkUriPermission");
6168
6169        // Another redirected-binder-call permissions check as in
6170        // {@link checkComponentPermission}.
6171        Identity tlsIdentity = sCallerIdentity.get();
6172        if (tlsIdentity != null) {
6173            uid = tlsIdentity.uid;
6174            pid = tlsIdentity.pid;
6175        }
6176
6177        // Our own process gets to do everything.
6178        if (pid == MY_PID) {
6179            return PackageManager.PERMISSION_GRANTED;
6180        }
6181        synchronized (this) {
6182            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6183                    ? PackageManager.PERMISSION_GRANTED
6184                    : PackageManager.PERMISSION_DENIED;
6185        }
6186    }
6187
6188    /**
6189     * Check if the targetPkg can be granted permission to access uri by
6190     * the callingUid using the given modeFlags.  Throws a security exception
6191     * if callingUid is not allowed to do this.  Returns the uid of the target
6192     * if the URI permission grant should be performed; returns -1 if it is not
6193     * needed (for example targetPkg already has permission to access the URI).
6194     * If you already know the uid of the target, you can supply it in
6195     * lastTargetUid else set that to -1.
6196     */
6197    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6198            final int modeFlags, int lastTargetUid) {
6199        if (!Intent.isAccessUriMode(modeFlags)) {
6200            return -1;
6201        }
6202
6203        if (targetPkg != null) {
6204            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6205                    "Checking grant " + targetPkg + " permission to " + grantUri);
6206        }
6207
6208        final IPackageManager pm = AppGlobals.getPackageManager();
6209
6210        // If this is not a content: uri, we can't do anything with it.
6211        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6212            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6213                    "Can't grant URI permission for non-content URI: " + grantUri);
6214            return -1;
6215        }
6216
6217        final String authority = grantUri.uri.getAuthority();
6218        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6219        if (pi == null) {
6220            Slog.w(TAG, "No content provider found for permission check: " +
6221                    grantUri.uri.toSafeString());
6222            return -1;
6223        }
6224
6225        int targetUid = lastTargetUid;
6226        if (targetUid < 0 && targetPkg != null) {
6227            try {
6228                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6229                if (targetUid < 0) {
6230                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6231                            "Can't grant URI permission no uid for: " + targetPkg);
6232                    return -1;
6233                }
6234            } catch (RemoteException ex) {
6235                return -1;
6236            }
6237        }
6238
6239        if (targetUid >= 0) {
6240            // First...  does the target actually need this permission?
6241            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6242                // No need to grant the target this permission.
6243                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6244                        "Target " + targetPkg + " already has full permission to " + grantUri);
6245                return -1;
6246            }
6247        } else {
6248            // First...  there is no target package, so can anyone access it?
6249            boolean allowed = pi.exported;
6250            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6251                if (pi.readPermission != null) {
6252                    allowed = false;
6253                }
6254            }
6255            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6256                if (pi.writePermission != null) {
6257                    allowed = false;
6258                }
6259            }
6260            if (allowed) {
6261                return -1;
6262            }
6263        }
6264
6265        // Second...  is the provider allowing granting of URI permissions?
6266        if (!pi.grantUriPermissions) {
6267            throw new SecurityException("Provider " + pi.packageName
6268                    + "/" + pi.name
6269                    + " does not allow granting of Uri permissions (uri "
6270                    + grantUri + ")");
6271        }
6272        if (pi.uriPermissionPatterns != null) {
6273            final int N = pi.uriPermissionPatterns.length;
6274            boolean allowed = false;
6275            for (int i=0; i<N; i++) {
6276                if (pi.uriPermissionPatterns[i] != null
6277                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6278                    allowed = true;
6279                    break;
6280                }
6281            }
6282            if (!allowed) {
6283                throw new SecurityException("Provider " + pi.packageName
6284                        + "/" + pi.name
6285                        + " does not allow granting of permission to path of Uri "
6286                        + grantUri);
6287            }
6288        }
6289
6290        // Third...  does the caller itself have permission to access
6291        // this uri?
6292        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6293            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6294                // Require they hold a strong enough Uri permission
6295                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6296                    throw new SecurityException("Uid " + callingUid
6297                            + " does not have permission to uri " + grantUri);
6298                }
6299            }
6300        }
6301        return targetUid;
6302    }
6303
6304    @Override
6305    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6306            final int modeFlags, int userId) {
6307        enforceNotIsolatedCaller("checkGrantUriPermission");
6308        synchronized(this) {
6309            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6310                    new GrantUri(userId, uri, false), modeFlags, -1);
6311        }
6312    }
6313
6314    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6315            final int modeFlags, UriPermissionOwner owner) {
6316        if (!Intent.isAccessUriMode(modeFlags)) {
6317            return;
6318        }
6319
6320        // So here we are: the caller has the assumed permission
6321        // to the uri, and the target doesn't.  Let's now give this to
6322        // the target.
6323
6324        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6325                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6326
6327        final String authority = grantUri.uri.getAuthority();
6328        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6329        if (pi == null) {
6330            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6331            return;
6332        }
6333
6334        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6335            grantUri.prefix = true;
6336        }
6337        final UriPermission perm = findOrCreateUriPermissionLocked(
6338                pi.packageName, targetPkg, targetUid, grantUri);
6339        perm.grantModes(modeFlags, owner);
6340    }
6341
6342    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6343            final int modeFlags, UriPermissionOwner owner) {
6344        if (targetPkg == null) {
6345            throw new NullPointerException("targetPkg");
6346        }
6347
6348        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6349                -1);
6350        if (targetUid < 0) {
6351            return;
6352        }
6353
6354        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6355                owner);
6356    }
6357
6358    static class NeededUriGrants extends ArrayList<GrantUri> {
6359        final String targetPkg;
6360        final int targetUid;
6361        final int flags;
6362
6363        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6364            this.targetPkg = targetPkg;
6365            this.targetUid = targetUid;
6366            this.flags = flags;
6367        }
6368    }
6369
6370    /**
6371     * Like checkGrantUriPermissionLocked, but takes an Intent.
6372     */
6373    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6374            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6375        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6376                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6377                + " clip=" + (intent != null ? intent.getClipData() : null)
6378                + " from " + intent + "; flags=0x"
6379                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6380
6381        if (targetPkg == null) {
6382            throw new NullPointerException("targetPkg");
6383        }
6384
6385        if (intent == null) {
6386            return null;
6387        }
6388        Uri data = intent.getData();
6389        ClipData clip = intent.getClipData();
6390        if (data == null && clip == null) {
6391            return null;
6392        }
6393
6394        if (data != null) {
6395            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6396            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6397                    needed != null ? needed.targetUid : -1);
6398            if (targetUid > 0) {
6399                if (needed == null) {
6400                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6401                }
6402                needed.add(grantUri);
6403            }
6404        }
6405        if (clip != null) {
6406            for (int i=0; i<clip.getItemCount(); i++) {
6407                Uri uri = clip.getItemAt(i).getUri();
6408                if (uri != null) {
6409                    int targetUid = -1;
6410                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6411                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6412                            needed != null ? needed.targetUid : -1);
6413                    if (targetUid > 0) {
6414                        if (needed == null) {
6415                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6416                        }
6417                        needed.add(grantUri);
6418                    }
6419                } else {
6420                    Intent clipIntent = clip.getItemAt(i).getIntent();
6421                    if (clipIntent != null) {
6422                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6423                                callingUid, targetPkg, clipIntent, mode, needed);
6424                        if (newNeeded != null) {
6425                            needed = newNeeded;
6426                        }
6427                    }
6428                }
6429            }
6430        }
6431
6432        return needed;
6433    }
6434
6435    /**
6436     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6437     */
6438    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6439            UriPermissionOwner owner) {
6440        if (needed != null) {
6441            for (int i=0; i<needed.size(); i++) {
6442                GrantUri grantUri = needed.get(i);
6443                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6444                        grantUri, needed.flags, owner);
6445            }
6446        }
6447    }
6448
6449    void grantUriPermissionFromIntentLocked(int callingUid,
6450            String targetPkg, Intent intent, UriPermissionOwner owner) {
6451        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6452                intent, intent != null ? intent.getFlags() : 0, null);
6453        if (needed == null) {
6454            return;
6455        }
6456
6457        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6458    }
6459
6460    @Override
6461    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6462            final int modeFlags, int userId) {
6463        enforceNotIsolatedCaller("grantUriPermission");
6464        GrantUri grantUri = new GrantUri(userId, uri, false);
6465        synchronized(this) {
6466            final ProcessRecord r = getRecordForAppLocked(caller);
6467            if (r == null) {
6468                throw new SecurityException("Unable to find app for caller "
6469                        + caller
6470                        + " when granting permission to uri " + grantUri);
6471            }
6472            if (targetPkg == null) {
6473                throw new IllegalArgumentException("null target");
6474            }
6475            if (grantUri == null) {
6476                throw new IllegalArgumentException("null uri");
6477            }
6478
6479            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6480                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6481                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6482                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6483
6484            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6485        }
6486    }
6487
6488    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6489        if (perm.modeFlags == 0) {
6490            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6491                    perm.targetUid);
6492            if (perms != null) {
6493                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6494                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6495
6496                perms.remove(perm.uri);
6497                if (perms.isEmpty()) {
6498                    mGrantedUriPermissions.remove(perm.targetUid);
6499                }
6500            }
6501        }
6502    }
6503
6504    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6505        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6506
6507        final IPackageManager pm = AppGlobals.getPackageManager();
6508        final String authority = grantUri.uri.getAuthority();
6509        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6510        if (pi == null) {
6511            Slog.w(TAG, "No content provider found for permission revoke: "
6512                    + grantUri.toSafeString());
6513            return;
6514        }
6515
6516        // Does the caller have this permission on the URI?
6517        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6518            // Right now, if you are not the original owner of the permission,
6519            // you are not allowed to revoke it.
6520            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6521                throw new SecurityException("Uid " + callingUid
6522                        + " does not have permission to uri " + grantUri);
6523            //}
6524        }
6525
6526        boolean persistChanged = false;
6527
6528        // Go through all of the permissions and remove any that match.
6529        int N = mGrantedUriPermissions.size();
6530        for (int i = 0; i < N; i++) {
6531            final int targetUid = mGrantedUriPermissions.keyAt(i);
6532            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6533
6534            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6535                final UriPermission perm = it.next();
6536                if (perm.uri.sourceUserId == grantUri.sourceUserId
6537                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6538                    if (DEBUG_URI_PERMISSION)
6539                        Slog.v(TAG,
6540                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6541                    persistChanged |= perm.revokeModes(
6542                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6543                    if (perm.modeFlags == 0) {
6544                        it.remove();
6545                    }
6546                }
6547            }
6548
6549            if (perms.isEmpty()) {
6550                mGrantedUriPermissions.remove(targetUid);
6551                N--;
6552                i--;
6553            }
6554        }
6555
6556        if (persistChanged) {
6557            schedulePersistUriGrants();
6558        }
6559    }
6560
6561    @Override
6562    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6563            int userId) {
6564        enforceNotIsolatedCaller("revokeUriPermission");
6565        synchronized(this) {
6566            final ProcessRecord r = getRecordForAppLocked(caller);
6567            if (r == null) {
6568                throw new SecurityException("Unable to find app for caller "
6569                        + caller
6570                        + " when revoking permission to uri " + uri);
6571            }
6572            if (uri == null) {
6573                Slog.w(TAG, "revokeUriPermission: null uri");
6574                return;
6575            }
6576
6577            if (!Intent.isAccessUriMode(modeFlags)) {
6578                return;
6579            }
6580
6581            final IPackageManager pm = AppGlobals.getPackageManager();
6582            final String authority = uri.getAuthority();
6583            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6584            if (pi == null) {
6585                Slog.w(TAG, "No content provider found for permission revoke: "
6586                        + uri.toSafeString());
6587                return;
6588            }
6589
6590            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6591        }
6592    }
6593
6594    /**
6595     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6596     * given package.
6597     *
6598     * @param packageName Package name to match, or {@code null} to apply to all
6599     *            packages.
6600     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6601     *            to all users.
6602     * @param persistable If persistable grants should be removed.
6603     */
6604    private void removeUriPermissionsForPackageLocked(
6605            String packageName, int userHandle, boolean persistable) {
6606        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6607            throw new IllegalArgumentException("Must narrow by either package or user");
6608        }
6609
6610        boolean persistChanged = false;
6611
6612        int N = mGrantedUriPermissions.size();
6613        for (int i = 0; i < N; i++) {
6614            final int targetUid = mGrantedUriPermissions.keyAt(i);
6615            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6616
6617            // Only inspect grants matching user
6618            if (userHandle == UserHandle.USER_ALL
6619                    || userHandle == UserHandle.getUserId(targetUid)) {
6620                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6621                    final UriPermission perm = it.next();
6622
6623                    // Only inspect grants matching package
6624                    if (packageName == null || perm.sourcePkg.equals(packageName)
6625                            || perm.targetPkg.equals(packageName)) {
6626                        persistChanged |= perm.revokeModes(
6627                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6628
6629                        // Only remove when no modes remain; any persisted grants
6630                        // will keep this alive.
6631                        if (perm.modeFlags == 0) {
6632                            it.remove();
6633                        }
6634                    }
6635                }
6636
6637                if (perms.isEmpty()) {
6638                    mGrantedUriPermissions.remove(targetUid);
6639                    N--;
6640                    i--;
6641                }
6642            }
6643        }
6644
6645        if (persistChanged) {
6646            schedulePersistUriGrants();
6647        }
6648    }
6649
6650    @Override
6651    public IBinder newUriPermissionOwner(String name) {
6652        enforceNotIsolatedCaller("newUriPermissionOwner");
6653        synchronized(this) {
6654            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6655            return owner.getExternalTokenLocked();
6656        }
6657    }
6658
6659    @Override
6660    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6661            final int modeFlags, int userId) {
6662        synchronized(this) {
6663            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6664            if (owner == null) {
6665                throw new IllegalArgumentException("Unknown owner: " + token);
6666            }
6667            if (fromUid != Binder.getCallingUid()) {
6668                if (Binder.getCallingUid() != Process.myUid()) {
6669                    // Only system code can grant URI permissions on behalf
6670                    // of other users.
6671                    throw new SecurityException("nice try");
6672                }
6673            }
6674            if (targetPkg == null) {
6675                throw new IllegalArgumentException("null target");
6676            }
6677            if (uri == null) {
6678                throw new IllegalArgumentException("null uri");
6679            }
6680
6681            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6682                    modeFlags, owner);
6683        }
6684    }
6685
6686    @Override
6687    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6688        synchronized(this) {
6689            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6690            if (owner == null) {
6691                throw new IllegalArgumentException("Unknown owner: " + token);
6692            }
6693
6694            if (uri == null) {
6695                owner.removeUriPermissionsLocked(mode);
6696            } else {
6697                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6698            }
6699        }
6700    }
6701
6702    private void schedulePersistUriGrants() {
6703        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6704            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6705                    10 * DateUtils.SECOND_IN_MILLIS);
6706        }
6707    }
6708
6709    private void writeGrantedUriPermissions() {
6710        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6711
6712        // Snapshot permissions so we can persist without lock
6713        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6714        synchronized (this) {
6715            final int size = mGrantedUriPermissions.size();
6716            for (int i = 0; i < size; i++) {
6717                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6718                for (UriPermission perm : perms.values()) {
6719                    if (perm.persistedModeFlags != 0) {
6720                        persist.add(perm.snapshot());
6721                    }
6722                }
6723            }
6724        }
6725
6726        FileOutputStream fos = null;
6727        try {
6728            fos = mGrantFile.startWrite();
6729
6730            XmlSerializer out = new FastXmlSerializer();
6731            out.setOutput(fos, "utf-8");
6732            out.startDocument(null, true);
6733            out.startTag(null, TAG_URI_GRANTS);
6734            for (UriPermission.Snapshot perm : persist) {
6735                out.startTag(null, TAG_URI_GRANT);
6736                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6737                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6738                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6739                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6740                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6741                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6742                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6743                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6744                out.endTag(null, TAG_URI_GRANT);
6745            }
6746            out.endTag(null, TAG_URI_GRANTS);
6747            out.endDocument();
6748
6749            mGrantFile.finishWrite(fos);
6750        } catch (IOException e) {
6751            if (fos != null) {
6752                mGrantFile.failWrite(fos);
6753            }
6754        }
6755    }
6756
6757    private void readGrantedUriPermissionsLocked() {
6758        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6759
6760        final long now = System.currentTimeMillis();
6761
6762        FileInputStream fis = null;
6763        try {
6764            fis = mGrantFile.openRead();
6765            final XmlPullParser in = Xml.newPullParser();
6766            in.setInput(fis, null);
6767
6768            int type;
6769            while ((type = in.next()) != END_DOCUMENT) {
6770                final String tag = in.getName();
6771                if (type == START_TAG) {
6772                    if (TAG_URI_GRANT.equals(tag)) {
6773                        final int sourceUserId;
6774                        final int targetUserId;
6775                        final int userHandle = readIntAttribute(in,
6776                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6777                        if (userHandle != UserHandle.USER_NULL) {
6778                            // For backwards compatibility.
6779                            sourceUserId = userHandle;
6780                            targetUserId = userHandle;
6781                        } else {
6782                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6783                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6784                        }
6785                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6786                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6787                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6788                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6789                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6790                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6791
6792                        // Sanity check that provider still belongs to source package
6793                        final ProviderInfo pi = getProviderInfoLocked(
6794                                uri.getAuthority(), sourceUserId);
6795                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6796                            int targetUid = -1;
6797                            try {
6798                                targetUid = AppGlobals.getPackageManager()
6799                                        .getPackageUid(targetPkg, targetUserId);
6800                            } catch (RemoteException e) {
6801                            }
6802                            if (targetUid != -1) {
6803                                final UriPermission perm = findOrCreateUriPermissionLocked(
6804                                        sourcePkg, targetPkg, targetUid,
6805                                        new GrantUri(sourceUserId, uri, prefix));
6806                                perm.initPersistedModes(modeFlags, createdTime);
6807                            }
6808                        } else {
6809                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6810                                    + " but instead found " + pi);
6811                        }
6812                    }
6813                }
6814            }
6815        } catch (FileNotFoundException e) {
6816            // Missing grants is okay
6817        } catch (IOException e) {
6818            Log.wtf(TAG, "Failed reading Uri grants", e);
6819        } catch (XmlPullParserException e) {
6820            Log.wtf(TAG, "Failed reading Uri grants", e);
6821        } finally {
6822            IoUtils.closeQuietly(fis);
6823        }
6824    }
6825
6826    @Override
6827    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6828        enforceNotIsolatedCaller("takePersistableUriPermission");
6829
6830        Preconditions.checkFlagsArgument(modeFlags,
6831                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6832
6833        synchronized (this) {
6834            final int callingUid = Binder.getCallingUid();
6835            boolean persistChanged = false;
6836            GrantUri grantUri = new GrantUri(userId, uri, false);
6837
6838            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6839                    new GrantUri(userId, uri, false));
6840            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6841                    new GrantUri(userId, uri, true));
6842
6843            final boolean exactValid = (exactPerm != null)
6844                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6845            final boolean prefixValid = (prefixPerm != null)
6846                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6847
6848            if (!(exactValid || prefixValid)) {
6849                throw new SecurityException("No persistable permission grants found for UID "
6850                        + callingUid + " and Uri " + grantUri.toSafeString());
6851            }
6852
6853            if (exactValid) {
6854                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6855            }
6856            if (prefixValid) {
6857                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6858            }
6859
6860            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6861
6862            if (persistChanged) {
6863                schedulePersistUriGrants();
6864            }
6865        }
6866    }
6867
6868    @Override
6869    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6870        enforceNotIsolatedCaller("releasePersistableUriPermission");
6871
6872        Preconditions.checkFlagsArgument(modeFlags,
6873                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6874
6875        synchronized (this) {
6876            final int callingUid = Binder.getCallingUid();
6877            boolean persistChanged = false;
6878
6879            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6880                    new GrantUri(userId, uri, false));
6881            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6882                    new GrantUri(userId, uri, true));
6883            if (exactPerm == null && prefixPerm == null) {
6884                throw new SecurityException("No permission grants found for UID " + callingUid
6885                        + " and Uri " + uri.toSafeString());
6886            }
6887
6888            if (exactPerm != null) {
6889                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6890                removeUriPermissionIfNeededLocked(exactPerm);
6891            }
6892            if (prefixPerm != null) {
6893                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6894                removeUriPermissionIfNeededLocked(prefixPerm);
6895            }
6896
6897            if (persistChanged) {
6898                schedulePersistUriGrants();
6899            }
6900        }
6901    }
6902
6903    /**
6904     * Prune any older {@link UriPermission} for the given UID until outstanding
6905     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6906     *
6907     * @return if any mutations occured that require persisting.
6908     */
6909    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6910        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6911        if (perms == null) return false;
6912        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6913
6914        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6915        for (UriPermission perm : perms.values()) {
6916            if (perm.persistedModeFlags != 0) {
6917                persisted.add(perm);
6918            }
6919        }
6920
6921        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6922        if (trimCount <= 0) return false;
6923
6924        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6925        for (int i = 0; i < trimCount; i++) {
6926            final UriPermission perm = persisted.get(i);
6927
6928            if (DEBUG_URI_PERMISSION) {
6929                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6930            }
6931
6932            perm.releasePersistableModes(~0);
6933            removeUriPermissionIfNeededLocked(perm);
6934        }
6935
6936        return true;
6937    }
6938
6939    @Override
6940    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6941            String packageName, boolean incoming) {
6942        enforceNotIsolatedCaller("getPersistedUriPermissions");
6943        Preconditions.checkNotNull(packageName, "packageName");
6944
6945        final int callingUid = Binder.getCallingUid();
6946        final IPackageManager pm = AppGlobals.getPackageManager();
6947        try {
6948            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6949            if (packageUid != callingUid) {
6950                throw new SecurityException(
6951                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6952            }
6953        } catch (RemoteException e) {
6954            throw new SecurityException("Failed to verify package name ownership");
6955        }
6956
6957        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6958        synchronized (this) {
6959            if (incoming) {
6960                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6961                        callingUid);
6962                if (perms == null) {
6963                    Slog.w(TAG, "No permission grants found for " + packageName);
6964                } else {
6965                    for (UriPermission perm : perms.values()) {
6966                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6967                            result.add(perm.buildPersistedPublicApiObject());
6968                        }
6969                    }
6970                }
6971            } else {
6972                final int size = mGrantedUriPermissions.size();
6973                for (int i = 0; i < size; i++) {
6974                    final ArrayMap<GrantUri, UriPermission> perms =
6975                            mGrantedUriPermissions.valueAt(i);
6976                    for (UriPermission perm : perms.values()) {
6977                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6978                            result.add(perm.buildPersistedPublicApiObject());
6979                        }
6980                    }
6981                }
6982            }
6983        }
6984        return new ParceledListSlice<android.content.UriPermission>(result);
6985    }
6986
6987    @Override
6988    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6989        synchronized (this) {
6990            ProcessRecord app =
6991                who != null ? getRecordForAppLocked(who) : null;
6992            if (app == null) return;
6993
6994            Message msg = Message.obtain();
6995            msg.what = WAIT_FOR_DEBUGGER_MSG;
6996            msg.obj = app;
6997            msg.arg1 = waiting ? 1 : 0;
6998            mHandler.sendMessage(msg);
6999        }
7000    }
7001
7002    @Override
7003    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7004        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7005        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7006        outInfo.availMem = Process.getFreeMemory();
7007        outInfo.totalMem = Process.getTotalMemory();
7008        outInfo.threshold = homeAppMem;
7009        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7010        outInfo.hiddenAppThreshold = cachedAppMem;
7011        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7012                ProcessList.SERVICE_ADJ);
7013        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7014                ProcessList.VISIBLE_APP_ADJ);
7015        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7016                ProcessList.FOREGROUND_APP_ADJ);
7017    }
7018
7019    // =========================================================
7020    // TASK MANAGEMENT
7021    // =========================================================
7022
7023    @Override
7024    public List<IAppTask> getAppTasks() {
7025        int callingUid = Binder.getCallingUid();
7026        long ident = Binder.clearCallingIdentity();
7027        synchronized(this) {
7028            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7029            try {
7030                if (localLOGV) Slog.v(TAG, "getAppTasks");
7031
7032                final int N = mRecentTasks.size();
7033                for (int i = 0; i < N; i++) {
7034                    TaskRecord tr = mRecentTasks.get(i);
7035                    // Skip tasks that are not created by the caller
7036                    if (tr.creatorUid == callingUid) {
7037                        ActivityManager.RecentTaskInfo taskInfo =
7038                                createRecentTaskInfoFromTaskRecord(tr);
7039                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7040                        list.add(taskImpl);
7041                    }
7042                }
7043            } finally {
7044                Binder.restoreCallingIdentity(ident);
7045            }
7046            return list;
7047        }
7048    }
7049
7050    @Override
7051    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7052        final int callingUid = Binder.getCallingUid();
7053        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7054
7055        synchronized(this) {
7056            if (localLOGV) Slog.v(
7057                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7058
7059            final boolean allowed = checkCallingPermission(
7060                    android.Manifest.permission.GET_TASKS)
7061                    == PackageManager.PERMISSION_GRANTED;
7062            if (!allowed) {
7063                Slog.w(TAG, "getTasks: caller " + callingUid
7064                        + " does not hold GET_TASKS; limiting output");
7065            }
7066
7067            // TODO: Improve with MRU list from all ActivityStacks.
7068            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7069        }
7070
7071        return list;
7072    }
7073
7074    TaskRecord getMostRecentTask() {
7075        return mRecentTasks.get(0);
7076    }
7077
7078    /**
7079     * Creates a new RecentTaskInfo from a TaskRecord.
7080     */
7081    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7082        ActivityManager.RecentTaskInfo rti
7083                = new ActivityManager.RecentTaskInfo();
7084        rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7085        rti.persistentId = tr.taskId;
7086        rti.baseIntent = new Intent(tr.getBaseIntent());
7087        rti.origActivity = tr.origActivity;
7088        rti.description = tr.lastDescription;
7089        rti.stackId = tr.stack.mStackId;
7090        rti.userId = tr.userId;
7091        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7092        return rti;
7093    }
7094
7095    @Override
7096    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7097            int flags, int userId) {
7098        final int callingUid = Binder.getCallingUid();
7099        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7100                false, true, "getRecentTasks", null);
7101
7102        synchronized (this) {
7103            final boolean allowed = checkCallingPermission(
7104                    android.Manifest.permission.GET_TASKS)
7105                    == PackageManager.PERMISSION_GRANTED;
7106            if (!allowed) {
7107                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7108                        + " does not hold GET_TASKS; limiting output");
7109            }
7110            final boolean detailed = checkCallingPermission(
7111                    android.Manifest.permission.GET_DETAILED_TASKS)
7112                    == PackageManager.PERMISSION_GRANTED;
7113
7114            IPackageManager pm = AppGlobals.getPackageManager();
7115
7116            final int N = mRecentTasks.size();
7117            ArrayList<ActivityManager.RecentTaskInfo> res
7118                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7119                            maxNum < N ? maxNum : N);
7120
7121            final Set<Integer> includedUsers;
7122            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7123                includedUsers = getProfileIdsLocked(userId);
7124            } else {
7125                includedUsers = new HashSet<Integer>();
7126            }
7127            includedUsers.add(Integer.valueOf(userId));
7128            for (int i=0; i<N && maxNum > 0; i++) {
7129                TaskRecord tr = mRecentTasks.get(i);
7130                // Only add calling user or related users recent tasks
7131                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7132
7133                // Return the entry if desired by the caller.  We always return
7134                // the first entry, because callers always expect this to be the
7135                // foreground app.  We may filter others if the caller has
7136                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7137                // we should exclude the entry.
7138
7139                if (i == 0
7140                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7141                        || (tr.intent == null)
7142                        || ((tr.intent.getFlags()
7143                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7144                    if (!allowed) {
7145                        // If the caller doesn't have the GET_TASKS permission, then only
7146                        // allow them to see a small subset of tasks -- their own and home.
7147                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7148                            continue;
7149                        }
7150                    }
7151
7152                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7153                    if (!detailed) {
7154                        rti.baseIntent.replaceExtras((Bundle)null);
7155                    }
7156
7157                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7158                        // Check whether this activity is currently available.
7159                        try {
7160                            if (rti.origActivity != null) {
7161                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7162                                        == null) {
7163                                    continue;
7164                                }
7165                            } else if (rti.baseIntent != null) {
7166                                if (pm.queryIntentActivities(rti.baseIntent,
7167                                        null, 0, userId) == null) {
7168                                    continue;
7169                                }
7170                            }
7171                        } catch (RemoteException e) {
7172                            // Will never happen.
7173                        }
7174                    }
7175
7176                    res.add(rti);
7177                    maxNum--;
7178                }
7179            }
7180            return res;
7181        }
7182    }
7183
7184    private TaskRecord recentTaskForIdLocked(int id) {
7185        final int N = mRecentTasks.size();
7186            for (int i=0; i<N; i++) {
7187                TaskRecord tr = mRecentTasks.get(i);
7188                if (tr.taskId == id) {
7189                    return tr;
7190                }
7191            }
7192            return null;
7193    }
7194
7195    @Override
7196    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7197        synchronized (this) {
7198            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7199                    "getTaskThumbnails()");
7200            TaskRecord tr = recentTaskForIdLocked(id);
7201            if (tr != null) {
7202                return tr.getTaskThumbnailsLocked();
7203            }
7204        }
7205        return null;
7206    }
7207
7208    @Override
7209    public Bitmap getTaskTopThumbnail(int id) {
7210        synchronized (this) {
7211            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7212                    "getTaskTopThumbnail()");
7213            TaskRecord tr = recentTaskForIdLocked(id);
7214            if (tr != null) {
7215                return tr.getTaskTopThumbnailLocked();
7216            }
7217        }
7218        return null;
7219    }
7220
7221    @Override
7222    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7223        synchronized (this) {
7224            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7225            if (r != null) {
7226                r.taskDescription = td;
7227                r.task.updateTaskDescription();
7228            }
7229        }
7230    }
7231
7232    @Override
7233    public boolean removeSubTask(int taskId, int subTaskIndex) {
7234        synchronized (this) {
7235            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7236                    "removeSubTask()");
7237            long ident = Binder.clearCallingIdentity();
7238            try {
7239                TaskRecord tr = recentTaskForIdLocked(taskId);
7240                if (tr != null) {
7241                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7242                }
7243                return false;
7244            } finally {
7245                Binder.restoreCallingIdentity(ident);
7246            }
7247        }
7248    }
7249
7250    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7251        if (!pr.killedByAm) {
7252            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7253            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7254                    pr.processName, pr.setAdj, reason);
7255            pr.killedByAm = true;
7256            Process.killProcessQuiet(pr.pid);
7257        }
7258    }
7259
7260    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7261        tr.disposeThumbnail();
7262        mRecentTasks.remove(tr);
7263        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7264        Intent baseIntent = new Intent(
7265                tr.intent != null ? tr.intent : tr.affinityIntent);
7266        ComponentName component = baseIntent.getComponent();
7267        if (component == null) {
7268            Slog.w(TAG, "Now component for base intent of task: " + tr);
7269            return;
7270        }
7271
7272        // Find any running services associated with this app.
7273        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7274
7275        if (killProcesses) {
7276            // Find any running processes associated with this app.
7277            final String pkg = component.getPackageName();
7278            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7279            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7280            for (int i=0; i<pmap.size(); i++) {
7281                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7282                for (int j=0; j<uids.size(); j++) {
7283                    ProcessRecord proc = uids.valueAt(j);
7284                    if (proc.userId != tr.userId) {
7285                        continue;
7286                    }
7287                    if (!proc.pkgList.containsKey(pkg)) {
7288                        continue;
7289                    }
7290                    procs.add(proc);
7291                }
7292            }
7293
7294            // Kill the running processes.
7295            for (int i=0; i<procs.size(); i++) {
7296                ProcessRecord pr = procs.get(i);
7297                if (pr == mHomeProcess) {
7298                    // Don't kill the home process along with tasks from the same package.
7299                    continue;
7300                }
7301                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7302                    killUnneededProcessLocked(pr, "remove task");
7303                } else {
7304                    pr.waitingToKill = "remove task";
7305                }
7306            }
7307        }
7308    }
7309
7310    /**
7311     * Removes the task with the specified task id.
7312     *
7313     * @param taskId Identifier of the task to be removed.
7314     * @param flags Additional operational flags.  May be 0 or
7315     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7316     * @return Returns true if the given task was found and removed.
7317     */
7318    private boolean removeTaskByIdLocked(int taskId, int flags) {
7319        TaskRecord tr = recentTaskForIdLocked(taskId);
7320        if (tr != null) {
7321            tr.removeTaskActivitiesLocked(-1, false);
7322            cleanUpRemovedTaskLocked(tr, flags);
7323            return true;
7324        }
7325        return false;
7326    }
7327
7328    @Override
7329    public boolean removeTask(int taskId, int flags) {
7330        synchronized (this) {
7331            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7332                    "removeTask()");
7333            long ident = Binder.clearCallingIdentity();
7334            try {
7335                return removeTaskByIdLocked(taskId, flags);
7336            } finally {
7337                Binder.restoreCallingIdentity(ident);
7338            }
7339        }
7340    }
7341
7342    /**
7343     * TODO: Add mController hook
7344     */
7345    @Override
7346    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7347        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7348                "moveTaskToFront()");
7349
7350        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7351        synchronized(this) {
7352            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7353                    Binder.getCallingUid(), "Task to front")) {
7354                ActivityOptions.abort(options);
7355                return;
7356            }
7357            final long origId = Binder.clearCallingIdentity();
7358            try {
7359                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7360                if (task == null) {
7361                    return;
7362                }
7363                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7364                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7365                    return;
7366                }
7367                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7368            } finally {
7369                Binder.restoreCallingIdentity(origId);
7370            }
7371            ActivityOptions.abort(options);
7372        }
7373    }
7374
7375    @Override
7376    public void moveTaskToBack(int taskId) {
7377        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7378                "moveTaskToBack()");
7379
7380        synchronized(this) {
7381            TaskRecord tr = recentTaskForIdLocked(taskId);
7382            if (tr != null) {
7383                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7384                ActivityStack stack = tr.stack;
7385                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7386                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7387                            Binder.getCallingUid(), "Task to back")) {
7388                        return;
7389                    }
7390                }
7391                final long origId = Binder.clearCallingIdentity();
7392                try {
7393                    stack.moveTaskToBackLocked(taskId, null);
7394                } finally {
7395                    Binder.restoreCallingIdentity(origId);
7396                }
7397            }
7398        }
7399    }
7400
7401    /**
7402     * Moves an activity, and all of the other activities within the same task, to the bottom
7403     * of the history stack.  The activity's order within the task is unchanged.
7404     *
7405     * @param token A reference to the activity we wish to move
7406     * @param nonRoot If false then this only works if the activity is the root
7407     *                of a task; if true it will work for any activity in a task.
7408     * @return Returns true if the move completed, false if not.
7409     */
7410    @Override
7411    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7412        enforceNotIsolatedCaller("moveActivityTaskToBack");
7413        synchronized(this) {
7414            final long origId = Binder.clearCallingIdentity();
7415            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7416            if (taskId >= 0) {
7417                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7418            }
7419            Binder.restoreCallingIdentity(origId);
7420        }
7421        return false;
7422    }
7423
7424    @Override
7425    public void moveTaskBackwards(int task) {
7426        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7427                "moveTaskBackwards()");
7428
7429        synchronized(this) {
7430            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7431                    Binder.getCallingUid(), "Task backwards")) {
7432                return;
7433            }
7434            final long origId = Binder.clearCallingIdentity();
7435            moveTaskBackwardsLocked(task);
7436            Binder.restoreCallingIdentity(origId);
7437        }
7438    }
7439
7440    private final void moveTaskBackwardsLocked(int task) {
7441        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7442    }
7443
7444    @Override
7445    public IBinder getHomeActivityToken() throws RemoteException {
7446        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7447                "getHomeActivityToken()");
7448        synchronized (this) {
7449            return mStackSupervisor.getHomeActivityToken();
7450        }
7451    }
7452
7453    @Override
7454    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7455            IActivityContainerCallback callback) throws RemoteException {
7456        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7457                "createActivityContainer()");
7458        synchronized (this) {
7459            if (parentActivityToken == null) {
7460                throw new IllegalArgumentException("parent token must not be null");
7461            }
7462            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7463            if (r == null) {
7464                return null;
7465            }
7466            if (callback == null) {
7467                throw new IllegalArgumentException("callback must not be null");
7468            }
7469            return mStackSupervisor.createActivityContainer(r, callback);
7470        }
7471    }
7472
7473    @Override
7474    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7475        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7476                "deleteActivityContainer()");
7477        synchronized (this) {
7478            mStackSupervisor.deleteActivityContainer(container);
7479        }
7480    }
7481
7482    @Override
7483    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7484            throws RemoteException {
7485        synchronized (this) {
7486            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7487            if (stack != null) {
7488                return stack.mActivityContainer;
7489            }
7490            return null;
7491        }
7492    }
7493
7494    @Override
7495    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7496        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7497                "moveTaskToStack()");
7498        if (stackId == HOME_STACK_ID) {
7499            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7500                    new RuntimeException("here").fillInStackTrace());
7501        }
7502        synchronized (this) {
7503            long ident = Binder.clearCallingIdentity();
7504            try {
7505                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7506                        + stackId + " toTop=" + toTop);
7507                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7508            } finally {
7509                Binder.restoreCallingIdentity(ident);
7510            }
7511        }
7512    }
7513
7514    @Override
7515    public void resizeStack(int stackBoxId, Rect bounds) {
7516        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7517                "resizeStackBox()");
7518        long ident = Binder.clearCallingIdentity();
7519        try {
7520            mWindowManager.resizeStack(stackBoxId, bounds);
7521        } finally {
7522            Binder.restoreCallingIdentity(ident);
7523        }
7524    }
7525
7526    @Override
7527    public List<StackInfo> getAllStackInfos() {
7528        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7529                "getAllStackInfos()");
7530        long ident = Binder.clearCallingIdentity();
7531        try {
7532            synchronized (this) {
7533                return mStackSupervisor.getAllStackInfosLocked();
7534            }
7535        } finally {
7536            Binder.restoreCallingIdentity(ident);
7537        }
7538    }
7539
7540    @Override
7541    public StackInfo getStackInfo(int stackId) {
7542        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7543                "getStackInfo()");
7544        long ident = Binder.clearCallingIdentity();
7545        try {
7546            synchronized (this) {
7547                return mStackSupervisor.getStackInfoLocked(stackId);
7548            }
7549        } finally {
7550            Binder.restoreCallingIdentity(ident);
7551        }
7552    }
7553
7554    @Override
7555    public boolean isInHomeStack(int taskId) {
7556        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7557                "getStackInfo()");
7558        long ident = Binder.clearCallingIdentity();
7559        try {
7560            synchronized (this) {
7561                TaskRecord tr = recentTaskForIdLocked(taskId);
7562                if (tr != null) {
7563                    return tr.stack.isHomeStack();
7564                }
7565            }
7566        } finally {
7567            Binder.restoreCallingIdentity(ident);
7568        }
7569        return false;
7570    }
7571
7572    @Override
7573    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7574        synchronized(this) {
7575            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7576        }
7577    }
7578
7579    private boolean isLockTaskAuthorized(ComponentName name) {
7580        final DevicePolicyManager dpm = (DevicePolicyManager)
7581                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7582        return dpm != null && dpm.isLockTaskPermitted(name);
7583    }
7584
7585    private void startLockTaskMode(TaskRecord task) {
7586        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7587            return;
7588        }
7589        long ident = Binder.clearCallingIdentity();
7590        try {
7591            synchronized (this) {
7592                // Since we lost lock on task, make sure it is still there.
7593                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7594                if (task != null) {
7595                    mStackSupervisor.setLockTaskModeLocked(task);
7596                }
7597            }
7598        } finally {
7599            Binder.restoreCallingIdentity(ident);
7600        }
7601    }
7602
7603    @Override
7604    public void startLockTaskMode(int taskId) {
7605        long ident = Binder.clearCallingIdentity();
7606        try {
7607            final TaskRecord task;
7608            synchronized (this) {
7609                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7610            }
7611            if (task != null) {
7612                startLockTaskMode(task);
7613            }
7614        } finally {
7615            Binder.restoreCallingIdentity(ident);
7616        }
7617    }
7618
7619    @Override
7620    public void startLockTaskMode(IBinder token) {
7621        long ident = Binder.clearCallingIdentity();
7622        try {
7623            final TaskRecord task;
7624            synchronized (this) {
7625                final ActivityRecord r = ActivityRecord.forToken(token);
7626                if (r == null) {
7627                    return;
7628                }
7629                task = r.task;
7630            }
7631            if (task != null) {
7632                startLockTaskMode(task);
7633            }
7634        } finally {
7635            Binder.restoreCallingIdentity(ident);
7636        }
7637    }
7638
7639    @Override
7640    public void stopLockTaskMode() {
7641        // Check if the calling task is eligible to use lock task
7642        final int uid = Binder.getCallingUid();
7643        try {
7644            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7645            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7646                return;
7647            }
7648        } catch (RemoteException e) {
7649            Log.d(TAG, "stopLockTaskMode " + e);
7650            return;
7651        }
7652        // Stop lock task
7653        synchronized (this) {
7654            mStackSupervisor.setLockTaskModeLocked(null);
7655        }
7656    }
7657
7658    @Override
7659    public boolean isInLockTaskMode() {
7660        synchronized (this) {
7661            return mStackSupervisor.isInLockTaskMode();
7662        }
7663    }
7664
7665    // =========================================================
7666    // CONTENT PROVIDERS
7667    // =========================================================
7668
7669    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7670        List<ProviderInfo> providers = null;
7671        try {
7672            providers = AppGlobals.getPackageManager().
7673                queryContentProviders(app.processName, app.uid,
7674                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7675        } catch (RemoteException ex) {
7676        }
7677        if (DEBUG_MU)
7678            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7679        int userId = app.userId;
7680        if (providers != null) {
7681            int N = providers.size();
7682            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7683            for (int i=0; i<N; i++) {
7684                ProviderInfo cpi =
7685                    (ProviderInfo)providers.get(i);
7686                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7687                        cpi.name, cpi.flags);
7688                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7689                    // This is a singleton provider, but a user besides the
7690                    // default user is asking to initialize a process it runs
7691                    // in...  well, no, it doesn't actually run in this process,
7692                    // it runs in the process of the default user.  Get rid of it.
7693                    providers.remove(i);
7694                    N--;
7695                    i--;
7696                    continue;
7697                }
7698
7699                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7700                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7701                if (cpr == null) {
7702                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7703                    mProviderMap.putProviderByClass(comp, cpr);
7704                }
7705                if (DEBUG_MU)
7706                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7707                app.pubProviders.put(cpi.name, cpr);
7708                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7709                    // Don't add this if it is a platform component that is marked
7710                    // to run in multiple processes, because this is actually
7711                    // part of the framework so doesn't make sense to track as a
7712                    // separate apk in the process.
7713                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7714                }
7715                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7716            }
7717        }
7718        return providers;
7719    }
7720
7721    /**
7722     * Check if {@link ProcessRecord} has a possible chance at accessing the
7723     * given {@link ProviderInfo}. Final permission checking is always done
7724     * in {@link ContentProvider}.
7725     */
7726    private final String checkContentProviderPermissionLocked(
7727            ProviderInfo cpi, ProcessRecord r, int userId) {
7728        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7729        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7730        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7731        // Looking for cross-user grants before to enforce the typical cross-users permissions
7732        if (userId != UserHandle.getUserId(callingUid)) {
7733            if (perms != null) {
7734                for (GrantUri grantUri : perms.keySet()) {
7735                    if (grantUri.sourceUserId == userId) {
7736                        String authority = grantUri.uri.getAuthority();
7737                        if (authority.equals(cpi.authority)) {
7738                            return null;
7739                        }
7740                    }
7741                }
7742            }
7743        }
7744        userId = handleIncomingUser(callingPid, callingUid, userId,
7745                false, true, "checkContentProviderPermissionLocked", null);
7746        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7747                cpi.applicationInfo.uid, cpi.exported)
7748                == PackageManager.PERMISSION_GRANTED) {
7749            return null;
7750        }
7751        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7752                cpi.applicationInfo.uid, cpi.exported)
7753                == PackageManager.PERMISSION_GRANTED) {
7754            return null;
7755        }
7756
7757        PathPermission[] pps = cpi.pathPermissions;
7758        if (pps != null) {
7759            int i = pps.length;
7760            while (i > 0) {
7761                i--;
7762                PathPermission pp = pps[i];
7763                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7764                        cpi.applicationInfo.uid, cpi.exported)
7765                        == PackageManager.PERMISSION_GRANTED) {
7766                    return null;
7767                }
7768                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7769                        cpi.applicationInfo.uid, cpi.exported)
7770                        == PackageManager.PERMISSION_GRANTED) {
7771                    return null;
7772                }
7773            }
7774        }
7775
7776        if (perms != null) {
7777            for (GrantUri grantUri : perms.keySet()) {
7778                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7779                    return null;
7780                }
7781            }
7782        }
7783
7784        String msg;
7785        if (!cpi.exported) {
7786            msg = "Permission Denial: opening provider " + cpi.name
7787                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7788                    + ", uid=" + callingUid + ") that is not exported from uid "
7789                    + cpi.applicationInfo.uid;
7790        } else {
7791            msg = "Permission Denial: opening provider " + cpi.name
7792                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7793                    + ", uid=" + callingUid + ") requires "
7794                    + cpi.readPermission + " or " + cpi.writePermission;
7795        }
7796        Slog.w(TAG, msg);
7797        return msg;
7798    }
7799
7800    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7801            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7802        if (r != null) {
7803            for (int i=0; i<r.conProviders.size(); i++) {
7804                ContentProviderConnection conn = r.conProviders.get(i);
7805                if (conn.provider == cpr) {
7806                    if (DEBUG_PROVIDER) Slog.v(TAG,
7807                            "Adding provider requested by "
7808                            + r.processName + " from process "
7809                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7810                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7811                    if (stable) {
7812                        conn.stableCount++;
7813                        conn.numStableIncs++;
7814                    } else {
7815                        conn.unstableCount++;
7816                        conn.numUnstableIncs++;
7817                    }
7818                    return conn;
7819                }
7820            }
7821            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7822            if (stable) {
7823                conn.stableCount = 1;
7824                conn.numStableIncs = 1;
7825            } else {
7826                conn.unstableCount = 1;
7827                conn.numUnstableIncs = 1;
7828            }
7829            cpr.connections.add(conn);
7830            r.conProviders.add(conn);
7831            return conn;
7832        }
7833        cpr.addExternalProcessHandleLocked(externalProcessToken);
7834        return null;
7835    }
7836
7837    boolean decProviderCountLocked(ContentProviderConnection conn,
7838            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7839        if (conn != null) {
7840            cpr = conn.provider;
7841            if (DEBUG_PROVIDER) Slog.v(TAG,
7842                    "Removing provider requested by "
7843                    + conn.client.processName + " from process "
7844                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7845                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7846            if (stable) {
7847                conn.stableCount--;
7848            } else {
7849                conn.unstableCount--;
7850            }
7851            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7852                cpr.connections.remove(conn);
7853                conn.client.conProviders.remove(conn);
7854                return true;
7855            }
7856            return false;
7857        }
7858        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7859        return false;
7860    }
7861
7862    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7863            String name, IBinder token, boolean stable, int userId) {
7864        ContentProviderRecord cpr;
7865        ContentProviderConnection conn = null;
7866        ProviderInfo cpi = null;
7867
7868        synchronized(this) {
7869            ProcessRecord r = null;
7870            if (caller != null) {
7871                r = getRecordForAppLocked(caller);
7872                if (r == null) {
7873                    throw new SecurityException(
7874                            "Unable to find app for caller " + caller
7875                          + " (pid=" + Binder.getCallingPid()
7876                          + ") when getting content provider " + name);
7877                }
7878            }
7879
7880            // First check if this content provider has been published...
7881            cpr = mProviderMap.getProviderByName(name, userId);
7882            boolean providerRunning = cpr != null;
7883            if (providerRunning) {
7884                cpi = cpr.info;
7885                String msg;
7886                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7887                    throw new SecurityException(msg);
7888                }
7889
7890                if (r != null && cpr.canRunHere(r)) {
7891                    // This provider has been published or is in the process
7892                    // of being published...  but it is also allowed to run
7893                    // in the caller's process, so don't make a connection
7894                    // and just let the caller instantiate its own instance.
7895                    ContentProviderHolder holder = cpr.newHolder(null);
7896                    // don't give caller the provider object, it needs
7897                    // to make its own.
7898                    holder.provider = null;
7899                    return holder;
7900                }
7901
7902                final long origId = Binder.clearCallingIdentity();
7903
7904                // In this case the provider instance already exists, so we can
7905                // return it right away.
7906                conn = incProviderCountLocked(r, cpr, token, stable);
7907                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7908                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7909                        // If this is a perceptible app accessing the provider,
7910                        // make sure to count it as being accessed and thus
7911                        // back up on the LRU list.  This is good because
7912                        // content providers are often expensive to start.
7913                        updateLruProcessLocked(cpr.proc, false, null);
7914                    }
7915                }
7916
7917                if (cpr.proc != null) {
7918                    if (false) {
7919                        if (cpr.name.flattenToShortString().equals(
7920                                "com.android.providers.calendar/.CalendarProvider2")) {
7921                            Slog.v(TAG, "****************** KILLING "
7922                                + cpr.name.flattenToShortString());
7923                            Process.killProcess(cpr.proc.pid);
7924                        }
7925                    }
7926                    boolean success = updateOomAdjLocked(cpr.proc);
7927                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7928                    // NOTE: there is still a race here where a signal could be
7929                    // pending on the process even though we managed to update its
7930                    // adj level.  Not sure what to do about this, but at least
7931                    // the race is now smaller.
7932                    if (!success) {
7933                        // Uh oh...  it looks like the provider's process
7934                        // has been killed on us.  We need to wait for a new
7935                        // process to be started, and make sure its death
7936                        // doesn't kill our process.
7937                        Slog.i(TAG,
7938                                "Existing provider " + cpr.name.flattenToShortString()
7939                                + " is crashing; detaching " + r);
7940                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7941                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7942                        if (!lastRef) {
7943                            // This wasn't the last ref our process had on
7944                            // the provider...  we have now been killed, bail.
7945                            return null;
7946                        }
7947                        providerRunning = false;
7948                        conn = null;
7949                    }
7950                }
7951
7952                Binder.restoreCallingIdentity(origId);
7953            }
7954
7955            boolean singleton;
7956            if (!providerRunning) {
7957                try {
7958                    cpi = AppGlobals.getPackageManager().
7959                        resolveContentProvider(name,
7960                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7961                } catch (RemoteException ex) {
7962                }
7963                if (cpi == null) {
7964                    return null;
7965                }
7966                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7967                        cpi.name, cpi.flags);
7968                if (singleton) {
7969                    userId = 0;
7970                }
7971                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7972
7973                String msg;
7974                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7975                    throw new SecurityException(msg);
7976                }
7977
7978                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7979                        && !cpi.processName.equals("system")) {
7980                    // If this content provider does not run in the system
7981                    // process, and the system is not yet ready to run other
7982                    // processes, then fail fast instead of hanging.
7983                    throw new IllegalArgumentException(
7984                            "Attempt to launch content provider before system ready");
7985                }
7986
7987                // Make sure that the user who owns this provider is started.  If not,
7988                // we don't want to allow it to run.
7989                if (mStartedUsers.get(userId) == null) {
7990                    Slog.w(TAG, "Unable to launch app "
7991                            + cpi.applicationInfo.packageName + "/"
7992                            + cpi.applicationInfo.uid + " for provider "
7993                            + name + ": user " + userId + " is stopped");
7994                    return null;
7995                }
7996
7997                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7998                cpr = mProviderMap.getProviderByClass(comp, userId);
7999                final boolean firstClass = cpr == null;
8000                if (firstClass) {
8001                    try {
8002                        ApplicationInfo ai =
8003                            AppGlobals.getPackageManager().
8004                                getApplicationInfo(
8005                                        cpi.applicationInfo.packageName,
8006                                        STOCK_PM_FLAGS, userId);
8007                        if (ai == null) {
8008                            Slog.w(TAG, "No package info for content provider "
8009                                    + cpi.name);
8010                            return null;
8011                        }
8012                        ai = getAppInfoForUser(ai, userId);
8013                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8014                    } catch (RemoteException ex) {
8015                        // pm is in same process, this will never happen.
8016                    }
8017                }
8018
8019                if (r != null && cpr.canRunHere(r)) {
8020                    // If this is a multiprocess provider, then just return its
8021                    // info and allow the caller to instantiate it.  Only do
8022                    // this if the provider is the same user as the caller's
8023                    // process, or can run as root (so can be in any process).
8024                    return cpr.newHolder(null);
8025                }
8026
8027                if (DEBUG_PROVIDER) {
8028                    RuntimeException e = new RuntimeException("here");
8029                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8030                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8031                }
8032
8033                // This is single process, and our app is now connecting to it.
8034                // See if we are already in the process of launching this
8035                // provider.
8036                final int N = mLaunchingProviders.size();
8037                int i;
8038                for (i=0; i<N; i++) {
8039                    if (mLaunchingProviders.get(i) == cpr) {
8040                        break;
8041                    }
8042                }
8043
8044                // If the provider is not already being launched, then get it
8045                // started.
8046                if (i >= N) {
8047                    final long origId = Binder.clearCallingIdentity();
8048
8049                    try {
8050                        // Content provider is now in use, its package can't be stopped.
8051                        try {
8052                            AppGlobals.getPackageManager().setPackageStoppedState(
8053                                    cpr.appInfo.packageName, false, userId);
8054                        } catch (RemoteException e) {
8055                        } catch (IllegalArgumentException e) {
8056                            Slog.w(TAG, "Failed trying to unstop package "
8057                                    + cpr.appInfo.packageName + ": " + e);
8058                        }
8059
8060                        // Use existing process if already started
8061                        ProcessRecord proc = getProcessRecordLocked(
8062                                cpi.processName, cpr.appInfo.uid, false);
8063                        if (proc != null && proc.thread != null) {
8064                            if (DEBUG_PROVIDER) {
8065                                Slog.d(TAG, "Installing in existing process " + proc);
8066                            }
8067                            proc.pubProviders.put(cpi.name, cpr);
8068                            try {
8069                                proc.thread.scheduleInstallProvider(cpi);
8070                            } catch (RemoteException e) {
8071                            }
8072                        } else {
8073                            proc = startProcessLocked(cpi.processName,
8074                                    cpr.appInfo, false, 0, "content provider",
8075                                    new ComponentName(cpi.applicationInfo.packageName,
8076                                            cpi.name), false, false, false);
8077                            if (proc == null) {
8078                                Slog.w(TAG, "Unable to launch app "
8079                                        + cpi.applicationInfo.packageName + "/"
8080                                        + cpi.applicationInfo.uid + " for provider "
8081                                        + name + ": process is bad");
8082                                return null;
8083                            }
8084                        }
8085                        cpr.launchingApp = proc;
8086                        mLaunchingProviders.add(cpr);
8087                    } finally {
8088                        Binder.restoreCallingIdentity(origId);
8089                    }
8090                }
8091
8092                // Make sure the provider is published (the same provider class
8093                // may be published under multiple names).
8094                if (firstClass) {
8095                    mProviderMap.putProviderByClass(comp, cpr);
8096                }
8097
8098                mProviderMap.putProviderByName(name, cpr);
8099                conn = incProviderCountLocked(r, cpr, token, stable);
8100                if (conn != null) {
8101                    conn.waiting = true;
8102                }
8103            }
8104        }
8105
8106        // Wait for the provider to be published...
8107        synchronized (cpr) {
8108            while (cpr.provider == null) {
8109                if (cpr.launchingApp == null) {
8110                    Slog.w(TAG, "Unable to launch app "
8111                            + cpi.applicationInfo.packageName + "/"
8112                            + cpi.applicationInfo.uid + " for provider "
8113                            + name + ": launching app became null");
8114                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8115                            UserHandle.getUserId(cpi.applicationInfo.uid),
8116                            cpi.applicationInfo.packageName,
8117                            cpi.applicationInfo.uid, name);
8118                    return null;
8119                }
8120                try {
8121                    if (DEBUG_MU) {
8122                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8123                                + cpr.launchingApp);
8124                    }
8125                    if (conn != null) {
8126                        conn.waiting = true;
8127                    }
8128                    cpr.wait();
8129                } catch (InterruptedException ex) {
8130                } finally {
8131                    if (conn != null) {
8132                        conn.waiting = false;
8133                    }
8134                }
8135            }
8136        }
8137        return cpr != null ? cpr.newHolder(conn) : null;
8138    }
8139
8140    @Override
8141    public final ContentProviderHolder getContentProvider(
8142            IApplicationThread caller, String name, int userId, boolean stable) {
8143        enforceNotIsolatedCaller("getContentProvider");
8144        if (caller == null) {
8145            String msg = "null IApplicationThread when getting content provider "
8146                    + name;
8147            Slog.w(TAG, msg);
8148            throw new SecurityException(msg);
8149        }
8150        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8151        // with cross-user grant.
8152        return getContentProviderImpl(caller, name, null, stable, userId);
8153    }
8154
8155    public ContentProviderHolder getContentProviderExternal(
8156            String name, int userId, IBinder token) {
8157        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8158            "Do not have permission in call getContentProviderExternal()");
8159        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8160                false, true, "getContentProvider", null);
8161        return getContentProviderExternalUnchecked(name, token, userId);
8162    }
8163
8164    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8165            IBinder token, int userId) {
8166        return getContentProviderImpl(null, name, token, true, userId);
8167    }
8168
8169    /**
8170     * Drop a content provider from a ProcessRecord's bookkeeping
8171     */
8172    public void removeContentProvider(IBinder connection, boolean stable) {
8173        enforceNotIsolatedCaller("removeContentProvider");
8174        long ident = Binder.clearCallingIdentity();
8175        try {
8176            synchronized (this) {
8177                ContentProviderConnection conn;
8178                try {
8179                    conn = (ContentProviderConnection)connection;
8180                } catch (ClassCastException e) {
8181                    String msg ="removeContentProvider: " + connection
8182                            + " not a ContentProviderConnection";
8183                    Slog.w(TAG, msg);
8184                    throw new IllegalArgumentException(msg);
8185                }
8186                if (conn == null) {
8187                    throw new NullPointerException("connection is null");
8188                }
8189                if (decProviderCountLocked(conn, null, null, stable)) {
8190                    updateOomAdjLocked();
8191                }
8192            }
8193        } finally {
8194            Binder.restoreCallingIdentity(ident);
8195        }
8196    }
8197
8198    public void removeContentProviderExternal(String name, IBinder token) {
8199        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8200            "Do not have permission in call removeContentProviderExternal()");
8201        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8202    }
8203
8204    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8205        synchronized (this) {
8206            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8207            if(cpr == null) {
8208                //remove from mProvidersByClass
8209                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8210                return;
8211            }
8212
8213            //update content provider record entry info
8214            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8215            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8216            if (localCpr.hasExternalProcessHandles()) {
8217                if (localCpr.removeExternalProcessHandleLocked(token)) {
8218                    updateOomAdjLocked();
8219                } else {
8220                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8221                            + " with no external reference for token: "
8222                            + token + ".");
8223                }
8224            } else {
8225                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8226                        + " with no external references.");
8227            }
8228        }
8229    }
8230
8231    public final void publishContentProviders(IApplicationThread caller,
8232            List<ContentProviderHolder> providers) {
8233        if (providers == null) {
8234            return;
8235        }
8236
8237        enforceNotIsolatedCaller("publishContentProviders");
8238        synchronized (this) {
8239            final ProcessRecord r = getRecordForAppLocked(caller);
8240            if (DEBUG_MU)
8241                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8242            if (r == null) {
8243                throw new SecurityException(
8244                        "Unable to find app for caller " + caller
8245                      + " (pid=" + Binder.getCallingPid()
8246                      + ") when publishing content providers");
8247            }
8248
8249            final long origId = Binder.clearCallingIdentity();
8250
8251            final int N = providers.size();
8252            for (int i=0; i<N; i++) {
8253                ContentProviderHolder src = providers.get(i);
8254                if (src == null || src.info == null || src.provider == null) {
8255                    continue;
8256                }
8257                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8258                if (DEBUG_MU)
8259                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8260                if (dst != null) {
8261                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8262                    mProviderMap.putProviderByClass(comp, dst);
8263                    String names[] = dst.info.authority.split(";");
8264                    for (int j = 0; j < names.length; j++) {
8265                        mProviderMap.putProviderByName(names[j], dst);
8266                    }
8267
8268                    int NL = mLaunchingProviders.size();
8269                    int j;
8270                    for (j=0; j<NL; j++) {
8271                        if (mLaunchingProviders.get(j) == dst) {
8272                            mLaunchingProviders.remove(j);
8273                            j--;
8274                            NL--;
8275                        }
8276                    }
8277                    synchronized (dst) {
8278                        dst.provider = src.provider;
8279                        dst.proc = r;
8280                        dst.notifyAll();
8281                    }
8282                    updateOomAdjLocked(r);
8283                }
8284            }
8285
8286            Binder.restoreCallingIdentity(origId);
8287        }
8288    }
8289
8290    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8291        ContentProviderConnection conn;
8292        try {
8293            conn = (ContentProviderConnection)connection;
8294        } catch (ClassCastException e) {
8295            String msg ="refContentProvider: " + connection
8296                    + " not a ContentProviderConnection";
8297            Slog.w(TAG, msg);
8298            throw new IllegalArgumentException(msg);
8299        }
8300        if (conn == null) {
8301            throw new NullPointerException("connection is null");
8302        }
8303
8304        synchronized (this) {
8305            if (stable > 0) {
8306                conn.numStableIncs += stable;
8307            }
8308            stable = conn.stableCount + stable;
8309            if (stable < 0) {
8310                throw new IllegalStateException("stableCount < 0: " + stable);
8311            }
8312
8313            if (unstable > 0) {
8314                conn.numUnstableIncs += unstable;
8315            }
8316            unstable = conn.unstableCount + unstable;
8317            if (unstable < 0) {
8318                throw new IllegalStateException("unstableCount < 0: " + unstable);
8319            }
8320
8321            if ((stable+unstable) <= 0) {
8322                throw new IllegalStateException("ref counts can't go to zero here: stable="
8323                        + stable + " unstable=" + unstable);
8324            }
8325            conn.stableCount = stable;
8326            conn.unstableCount = unstable;
8327            return !conn.dead;
8328        }
8329    }
8330
8331    public void unstableProviderDied(IBinder connection) {
8332        ContentProviderConnection conn;
8333        try {
8334            conn = (ContentProviderConnection)connection;
8335        } catch (ClassCastException e) {
8336            String msg ="refContentProvider: " + connection
8337                    + " not a ContentProviderConnection";
8338            Slog.w(TAG, msg);
8339            throw new IllegalArgumentException(msg);
8340        }
8341        if (conn == null) {
8342            throw new NullPointerException("connection is null");
8343        }
8344
8345        // Safely retrieve the content provider associated with the connection.
8346        IContentProvider provider;
8347        synchronized (this) {
8348            provider = conn.provider.provider;
8349        }
8350
8351        if (provider == null) {
8352            // Um, yeah, we're way ahead of you.
8353            return;
8354        }
8355
8356        // Make sure the caller is being honest with us.
8357        if (provider.asBinder().pingBinder()) {
8358            // Er, no, still looks good to us.
8359            synchronized (this) {
8360                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8361                        + " says " + conn + " died, but we don't agree");
8362                return;
8363            }
8364        }
8365
8366        // Well look at that!  It's dead!
8367        synchronized (this) {
8368            if (conn.provider.provider != provider) {
8369                // But something changed...  good enough.
8370                return;
8371            }
8372
8373            ProcessRecord proc = conn.provider.proc;
8374            if (proc == null || proc.thread == null) {
8375                // Seems like the process is already cleaned up.
8376                return;
8377            }
8378
8379            // As far as we're concerned, this is just like receiving a
8380            // death notification...  just a bit prematurely.
8381            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8382                    + ") early provider death");
8383            final long ident = Binder.clearCallingIdentity();
8384            try {
8385                appDiedLocked(proc, proc.pid, proc.thread);
8386            } finally {
8387                Binder.restoreCallingIdentity(ident);
8388            }
8389        }
8390    }
8391
8392    @Override
8393    public void appNotRespondingViaProvider(IBinder connection) {
8394        enforceCallingPermission(
8395                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8396
8397        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8398        if (conn == null) {
8399            Slog.w(TAG, "ContentProviderConnection is null");
8400            return;
8401        }
8402
8403        final ProcessRecord host = conn.provider.proc;
8404        if (host == null) {
8405            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8406            return;
8407        }
8408
8409        final long token = Binder.clearCallingIdentity();
8410        try {
8411            appNotResponding(host, null, null, false, "ContentProvider not responding");
8412        } finally {
8413            Binder.restoreCallingIdentity(token);
8414        }
8415    }
8416
8417    public final void installSystemProviders() {
8418        List<ProviderInfo> providers;
8419        synchronized (this) {
8420            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8421            providers = generateApplicationProvidersLocked(app);
8422            if (providers != null) {
8423                for (int i=providers.size()-1; i>=0; i--) {
8424                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8425                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8426                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8427                                + ": not system .apk");
8428                        providers.remove(i);
8429                    }
8430                }
8431            }
8432        }
8433        if (providers != null) {
8434            mSystemThread.installSystemProviders(providers);
8435        }
8436
8437        mCoreSettingsObserver = new CoreSettingsObserver(this);
8438
8439        mUsageStatsService.monitorPackages();
8440    }
8441
8442    /**
8443     * Allows app to retrieve the MIME type of a URI without having permission
8444     * to access its content provider.
8445     *
8446     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8447     *
8448     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8449     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8450     */
8451    public String getProviderMimeType(Uri uri, int userId) {
8452        enforceNotIsolatedCaller("getProviderMimeType");
8453        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8454                userId, false, true, "getProviderMimeType", null);
8455        final String name = uri.getAuthority();
8456        final long ident = Binder.clearCallingIdentity();
8457        ContentProviderHolder holder = null;
8458
8459        try {
8460            holder = getContentProviderExternalUnchecked(name, null, userId);
8461            if (holder != null) {
8462                return holder.provider.getType(uri);
8463            }
8464        } catch (RemoteException e) {
8465            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8466            return null;
8467        } finally {
8468            if (holder != null) {
8469                removeContentProviderExternalUnchecked(name, null, userId);
8470            }
8471            Binder.restoreCallingIdentity(ident);
8472        }
8473
8474        return null;
8475    }
8476
8477    // =========================================================
8478    // GLOBAL MANAGEMENT
8479    // =========================================================
8480
8481    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8482            boolean isolated) {
8483        String proc = customProcess != null ? customProcess : info.processName;
8484        BatteryStatsImpl.Uid.Proc ps = null;
8485        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8486        int uid = info.uid;
8487        if (isolated) {
8488            int userId = UserHandle.getUserId(uid);
8489            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8490            while (true) {
8491                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8492                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8493                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8494                }
8495                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8496                mNextIsolatedProcessUid++;
8497                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8498                    // No process for this uid, use it.
8499                    break;
8500                }
8501                stepsLeft--;
8502                if (stepsLeft <= 0) {
8503                    return null;
8504                }
8505            }
8506        }
8507        return new ProcessRecord(stats, info, proc, uid);
8508    }
8509
8510    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8511        ProcessRecord app;
8512        if (!isolated) {
8513            app = getProcessRecordLocked(info.processName, info.uid, true);
8514        } else {
8515            app = null;
8516        }
8517
8518        if (app == null) {
8519            app = newProcessRecordLocked(info, null, isolated);
8520            mProcessNames.put(info.processName, app.uid, app);
8521            if (isolated) {
8522                mIsolatedProcesses.put(app.uid, app);
8523            }
8524            updateLruProcessLocked(app, false, null);
8525            updateOomAdjLocked();
8526        }
8527
8528        // This package really, really can not be stopped.
8529        try {
8530            AppGlobals.getPackageManager().setPackageStoppedState(
8531                    info.packageName, false, UserHandle.getUserId(app.uid));
8532        } catch (RemoteException e) {
8533        } catch (IllegalArgumentException e) {
8534            Slog.w(TAG, "Failed trying to unstop package "
8535                    + info.packageName + ": " + e);
8536        }
8537
8538        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8539                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8540            app.persistent = true;
8541            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8542        }
8543        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8544            mPersistentStartingProcesses.add(app);
8545            startProcessLocked(app, "added application", app.processName);
8546        }
8547
8548        return app;
8549    }
8550
8551    public void unhandledBack() {
8552        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8553                "unhandledBack()");
8554
8555        synchronized(this) {
8556            final long origId = Binder.clearCallingIdentity();
8557            try {
8558                getFocusedStack().unhandledBackLocked();
8559            } finally {
8560                Binder.restoreCallingIdentity(origId);
8561            }
8562        }
8563    }
8564
8565    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8566        enforceNotIsolatedCaller("openContentUri");
8567        final int userId = UserHandle.getCallingUserId();
8568        String name = uri.getAuthority();
8569        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8570        ParcelFileDescriptor pfd = null;
8571        if (cph != null) {
8572            // We record the binder invoker's uid in thread-local storage before
8573            // going to the content provider to open the file.  Later, in the code
8574            // that handles all permissions checks, we look for this uid and use
8575            // that rather than the Activity Manager's own uid.  The effect is that
8576            // we do the check against the caller's permissions even though it looks
8577            // to the content provider like the Activity Manager itself is making
8578            // the request.
8579            sCallerIdentity.set(new Identity(
8580                    Binder.getCallingPid(), Binder.getCallingUid()));
8581            try {
8582                pfd = cph.provider.openFile(null, uri, "r", null);
8583            } catch (FileNotFoundException e) {
8584                // do nothing; pfd will be returned null
8585            } finally {
8586                // Ensure that whatever happens, we clean up the identity state
8587                sCallerIdentity.remove();
8588            }
8589
8590            // We've got the fd now, so we're done with the provider.
8591            removeContentProviderExternalUnchecked(name, null, userId);
8592        } else {
8593            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8594        }
8595        return pfd;
8596    }
8597
8598    // Actually is sleeping or shutting down or whatever else in the future
8599    // is an inactive state.
8600    public boolean isSleepingOrShuttingDown() {
8601        return mSleeping || mShuttingDown;
8602    }
8603
8604    public boolean isSleeping() {
8605        return mSleeping;
8606    }
8607
8608    void goingToSleep() {
8609        synchronized(this) {
8610            mWentToSleep = true;
8611            updateEventDispatchingLocked();
8612            goToSleepIfNeededLocked();
8613        }
8614    }
8615
8616    void finishRunningVoiceLocked() {
8617        if (mRunningVoice) {
8618            mRunningVoice = false;
8619            goToSleepIfNeededLocked();
8620        }
8621    }
8622
8623    void goToSleepIfNeededLocked() {
8624        if (mWentToSleep && !mRunningVoice) {
8625            if (!mSleeping) {
8626                mSleeping = true;
8627                mStackSupervisor.goingToSleepLocked();
8628
8629                // Initialize the wake times of all processes.
8630                checkExcessivePowerUsageLocked(false);
8631                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8632                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8633                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8634            }
8635        }
8636    }
8637
8638    @Override
8639    public boolean shutdown(int timeout) {
8640        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8641                != PackageManager.PERMISSION_GRANTED) {
8642            throw new SecurityException("Requires permission "
8643                    + android.Manifest.permission.SHUTDOWN);
8644        }
8645
8646        boolean timedout = false;
8647
8648        synchronized(this) {
8649            mShuttingDown = true;
8650            updateEventDispatchingLocked();
8651            timedout = mStackSupervisor.shutdownLocked(timeout);
8652        }
8653
8654        mAppOpsService.shutdown();
8655        mUsageStatsService.shutdown();
8656        mBatteryStatsService.shutdown();
8657        synchronized (this) {
8658            mProcessStats.shutdownLocked();
8659        }
8660
8661        return timedout;
8662    }
8663
8664    public final void activitySlept(IBinder token) {
8665        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8666
8667        final long origId = Binder.clearCallingIdentity();
8668
8669        synchronized (this) {
8670            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8671            if (r != null) {
8672                mStackSupervisor.activitySleptLocked(r);
8673            }
8674        }
8675
8676        Binder.restoreCallingIdentity(origId);
8677    }
8678
8679    void logLockScreen(String msg) {
8680        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8681                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8682                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8683                mStackSupervisor.mDismissKeyguardOnNextActivity);
8684    }
8685
8686    private void comeOutOfSleepIfNeededLocked() {
8687        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8688            if (mSleeping) {
8689                mSleeping = false;
8690                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8691            }
8692        }
8693    }
8694
8695    void wakingUp() {
8696        synchronized(this) {
8697            mWentToSleep = false;
8698            updateEventDispatchingLocked();
8699            comeOutOfSleepIfNeededLocked();
8700        }
8701    }
8702
8703    void startRunningVoiceLocked() {
8704        if (!mRunningVoice) {
8705            mRunningVoice = true;
8706            comeOutOfSleepIfNeededLocked();
8707        }
8708    }
8709
8710    private void updateEventDispatchingLocked() {
8711        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8712    }
8713
8714    public void setLockScreenShown(boolean shown) {
8715        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8716                != PackageManager.PERMISSION_GRANTED) {
8717            throw new SecurityException("Requires permission "
8718                    + android.Manifest.permission.DEVICE_POWER);
8719        }
8720
8721        synchronized(this) {
8722            long ident = Binder.clearCallingIdentity();
8723            try {
8724                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8725                mLockScreenShown = shown;
8726                comeOutOfSleepIfNeededLocked();
8727            } finally {
8728                Binder.restoreCallingIdentity(ident);
8729            }
8730        }
8731    }
8732
8733    public void stopAppSwitches() {
8734        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8735                != PackageManager.PERMISSION_GRANTED) {
8736            throw new SecurityException("Requires permission "
8737                    + android.Manifest.permission.STOP_APP_SWITCHES);
8738        }
8739
8740        synchronized(this) {
8741            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8742                    + APP_SWITCH_DELAY_TIME;
8743            mDidAppSwitch = false;
8744            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8745            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8746            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8747        }
8748    }
8749
8750    public void resumeAppSwitches() {
8751        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8752                != PackageManager.PERMISSION_GRANTED) {
8753            throw new SecurityException("Requires permission "
8754                    + android.Manifest.permission.STOP_APP_SWITCHES);
8755        }
8756
8757        synchronized(this) {
8758            // Note that we don't execute any pending app switches... we will
8759            // let those wait until either the timeout, or the next start
8760            // activity request.
8761            mAppSwitchesAllowedTime = 0;
8762        }
8763    }
8764
8765    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8766            String name) {
8767        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8768            return true;
8769        }
8770
8771        final int perm = checkComponentPermission(
8772                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8773                callingUid, -1, true);
8774        if (perm == PackageManager.PERMISSION_GRANTED) {
8775            return true;
8776        }
8777
8778        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8779        return false;
8780    }
8781
8782    public void setDebugApp(String packageName, boolean waitForDebugger,
8783            boolean persistent) {
8784        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8785                "setDebugApp()");
8786
8787        long ident = Binder.clearCallingIdentity();
8788        try {
8789            // Note that this is not really thread safe if there are multiple
8790            // callers into it at the same time, but that's not a situation we
8791            // care about.
8792            if (persistent) {
8793                final ContentResolver resolver = mContext.getContentResolver();
8794                Settings.Global.putString(
8795                    resolver, Settings.Global.DEBUG_APP,
8796                    packageName);
8797                Settings.Global.putInt(
8798                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8799                    waitForDebugger ? 1 : 0);
8800            }
8801
8802            synchronized (this) {
8803                if (!persistent) {
8804                    mOrigDebugApp = mDebugApp;
8805                    mOrigWaitForDebugger = mWaitForDebugger;
8806                }
8807                mDebugApp = packageName;
8808                mWaitForDebugger = waitForDebugger;
8809                mDebugTransient = !persistent;
8810                if (packageName != null) {
8811                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8812                            false, UserHandle.USER_ALL, "set debug app");
8813                }
8814            }
8815        } finally {
8816            Binder.restoreCallingIdentity(ident);
8817        }
8818    }
8819
8820    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8821        synchronized (this) {
8822            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8823            if (!isDebuggable) {
8824                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8825                    throw new SecurityException("Process not debuggable: " + app.packageName);
8826                }
8827            }
8828
8829            mOpenGlTraceApp = processName;
8830        }
8831    }
8832
8833    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8834            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8835        synchronized (this) {
8836            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8837            if (!isDebuggable) {
8838                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8839                    throw new SecurityException("Process not debuggable: " + app.packageName);
8840                }
8841            }
8842            mProfileApp = processName;
8843            mProfileFile = profileFile;
8844            if (mProfileFd != null) {
8845                try {
8846                    mProfileFd.close();
8847                } catch (IOException e) {
8848                }
8849                mProfileFd = null;
8850            }
8851            mProfileFd = profileFd;
8852            mProfileType = 0;
8853            mAutoStopProfiler = autoStopProfiler;
8854        }
8855    }
8856
8857    @Override
8858    public void setAlwaysFinish(boolean enabled) {
8859        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8860                "setAlwaysFinish()");
8861
8862        Settings.Global.putInt(
8863                mContext.getContentResolver(),
8864                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8865
8866        synchronized (this) {
8867            mAlwaysFinishActivities = enabled;
8868        }
8869    }
8870
8871    @Override
8872    public void setActivityController(IActivityController controller) {
8873        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8874                "setActivityController()");
8875        synchronized (this) {
8876            mController = controller;
8877            Watchdog.getInstance().setActivityController(controller);
8878        }
8879    }
8880
8881    @Override
8882    public void setUserIsMonkey(boolean userIsMonkey) {
8883        synchronized (this) {
8884            synchronized (mPidsSelfLocked) {
8885                final int callingPid = Binder.getCallingPid();
8886                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8887                if (precessRecord == null) {
8888                    throw new SecurityException("Unknown process: " + callingPid);
8889                }
8890                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8891                    throw new SecurityException("Only an instrumentation process "
8892                            + "with a UiAutomation can call setUserIsMonkey");
8893                }
8894            }
8895            mUserIsMonkey = userIsMonkey;
8896        }
8897    }
8898
8899    @Override
8900    public boolean isUserAMonkey() {
8901        synchronized (this) {
8902            // If there is a controller also implies the user is a monkey.
8903            return (mUserIsMonkey || mController != null);
8904        }
8905    }
8906
8907    public void requestBugReport() {
8908        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8909        SystemProperties.set("ctl.start", "bugreport");
8910    }
8911
8912    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8913        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8914    }
8915
8916    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8917        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8918            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8919        }
8920        return KEY_DISPATCHING_TIMEOUT;
8921    }
8922
8923    @Override
8924    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8925        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8926                != PackageManager.PERMISSION_GRANTED) {
8927            throw new SecurityException("Requires permission "
8928                    + android.Manifest.permission.FILTER_EVENTS);
8929        }
8930        ProcessRecord proc;
8931        long timeout;
8932        synchronized (this) {
8933            synchronized (mPidsSelfLocked) {
8934                proc = mPidsSelfLocked.get(pid);
8935            }
8936            timeout = getInputDispatchingTimeoutLocked(proc);
8937        }
8938
8939        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8940            return -1;
8941        }
8942
8943        return timeout;
8944    }
8945
8946    /**
8947     * Handle input dispatching timeouts.
8948     * Returns whether input dispatching should be aborted or not.
8949     */
8950    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8951            final ActivityRecord activity, final ActivityRecord parent,
8952            final boolean aboveSystem, String reason) {
8953        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8954                != PackageManager.PERMISSION_GRANTED) {
8955            throw new SecurityException("Requires permission "
8956                    + android.Manifest.permission.FILTER_EVENTS);
8957        }
8958
8959        final String annotation;
8960        if (reason == null) {
8961            annotation = "Input dispatching timed out";
8962        } else {
8963            annotation = "Input dispatching timed out (" + reason + ")";
8964        }
8965
8966        if (proc != null) {
8967            synchronized (this) {
8968                if (proc.debugging) {
8969                    return false;
8970                }
8971
8972                if (mDidDexOpt) {
8973                    // Give more time since we were dexopting.
8974                    mDidDexOpt = false;
8975                    return false;
8976                }
8977
8978                if (proc.instrumentationClass != null) {
8979                    Bundle info = new Bundle();
8980                    info.putString("shortMsg", "keyDispatchingTimedOut");
8981                    info.putString("longMsg", annotation);
8982                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8983                    return true;
8984                }
8985            }
8986            mHandler.post(new Runnable() {
8987                @Override
8988                public void run() {
8989                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8990                }
8991            });
8992        }
8993
8994        return true;
8995    }
8996
8997    public Bundle getAssistContextExtras(int requestType) {
8998        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8999                "getAssistContextExtras()");
9000        PendingAssistExtras pae;
9001        Bundle extras = new Bundle();
9002        synchronized (this) {
9003            ActivityRecord activity = getFocusedStack().mResumedActivity;
9004            if (activity == null) {
9005                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9006                return null;
9007            }
9008            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9009            if (activity.app == null || activity.app.thread == null) {
9010                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9011                return extras;
9012            }
9013            if (activity.app.pid == Binder.getCallingPid()) {
9014                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9015                return extras;
9016            }
9017            pae = new PendingAssistExtras(activity);
9018            try {
9019                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9020                        requestType);
9021                mPendingAssistExtras.add(pae);
9022                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9023            } catch (RemoteException e) {
9024                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9025                return extras;
9026            }
9027        }
9028        synchronized (pae) {
9029            while (!pae.haveResult) {
9030                try {
9031                    pae.wait();
9032                } catch (InterruptedException e) {
9033                }
9034            }
9035            if (pae.result != null) {
9036                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9037            }
9038        }
9039        synchronized (this) {
9040            mPendingAssistExtras.remove(pae);
9041            mHandler.removeCallbacks(pae);
9042        }
9043        return extras;
9044    }
9045
9046    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9047        PendingAssistExtras pae = (PendingAssistExtras)token;
9048        synchronized (pae) {
9049            pae.result = extras;
9050            pae.haveResult = true;
9051            pae.notifyAll();
9052        }
9053    }
9054
9055    public void registerProcessObserver(IProcessObserver observer) {
9056        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9057                "registerProcessObserver()");
9058        synchronized (this) {
9059            mProcessObservers.register(observer);
9060        }
9061    }
9062
9063    @Override
9064    public void unregisterProcessObserver(IProcessObserver observer) {
9065        synchronized (this) {
9066            mProcessObservers.unregister(observer);
9067        }
9068    }
9069
9070    @Override
9071    public boolean convertFromTranslucent(IBinder token) {
9072        final long origId = Binder.clearCallingIdentity();
9073        try {
9074            synchronized (this) {
9075                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9076                if (r == null) {
9077                    return false;
9078                }
9079                if (r.changeWindowTranslucency(true)) {
9080                    mWindowManager.setAppFullscreen(token, true);
9081                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9082                    return true;
9083                }
9084                return false;
9085            }
9086        } finally {
9087            Binder.restoreCallingIdentity(origId);
9088        }
9089    }
9090
9091    @Override
9092    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9093        final long origId = Binder.clearCallingIdentity();
9094        try {
9095            synchronized (this) {
9096                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9097                if (r == null) {
9098                    return false;
9099                }
9100                if (r.changeWindowTranslucency(false)) {
9101                    r.task.stack.convertToTranslucent(r, options);
9102                    mWindowManager.setAppFullscreen(token, false);
9103                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9104                    return true;
9105                }
9106                return false;
9107            }
9108        } finally {
9109            Binder.restoreCallingIdentity(origId);
9110        }
9111    }
9112
9113    @Override
9114    public ActivityOptions getActivityOptions(IBinder token) {
9115        final long origId = Binder.clearCallingIdentity();
9116        try {
9117            synchronized (this) {
9118                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9119                if (r != null) {
9120                    final ActivityOptions activityOptions = r.pendingOptions;
9121                    r.pendingOptions = null;
9122                    return activityOptions;
9123                }
9124                return null;
9125            }
9126        } finally {
9127            Binder.restoreCallingIdentity(origId);
9128        }
9129    }
9130
9131    @Override
9132    public void setImmersive(IBinder token, boolean immersive) {
9133        synchronized(this) {
9134            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9135            if (r == null) {
9136                throw new IllegalArgumentException();
9137            }
9138            r.immersive = immersive;
9139
9140            // update associated state if we're frontmost
9141            if (r == mFocusedActivity) {
9142                if (DEBUG_IMMERSIVE) {
9143                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9144                }
9145                applyUpdateLockStateLocked(r);
9146            }
9147        }
9148    }
9149
9150    @Override
9151    public boolean isImmersive(IBinder token) {
9152        synchronized (this) {
9153            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9154            if (r == null) {
9155                throw new IllegalArgumentException();
9156            }
9157            return r.immersive;
9158        }
9159    }
9160
9161    public boolean isTopActivityImmersive() {
9162        enforceNotIsolatedCaller("startActivity");
9163        synchronized (this) {
9164            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9165            return (r != null) ? r.immersive : false;
9166        }
9167    }
9168
9169    public final void enterSafeMode() {
9170        synchronized(this) {
9171            // It only makes sense to do this before the system is ready
9172            // and started launching other packages.
9173            if (!mSystemReady) {
9174                try {
9175                    AppGlobals.getPackageManager().enterSafeMode();
9176                } catch (RemoteException e) {
9177                }
9178            }
9179
9180            mSafeMode = true;
9181        }
9182    }
9183
9184    public final void showSafeModeOverlay() {
9185        View v = LayoutInflater.from(mContext).inflate(
9186                com.android.internal.R.layout.safe_mode, null);
9187        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9188        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9189        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9190        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9191        lp.gravity = Gravity.BOTTOM | Gravity.START;
9192        lp.format = v.getBackground().getOpacity();
9193        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9194                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9195        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9196        ((WindowManager)mContext.getSystemService(
9197                Context.WINDOW_SERVICE)).addView(v, lp);
9198    }
9199
9200    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9201        if (!(sender instanceof PendingIntentRecord)) {
9202            return;
9203        }
9204        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9205        synchronized (stats) {
9206            if (mBatteryStatsService.isOnBattery()) {
9207                mBatteryStatsService.enforceCallingPermission();
9208                PendingIntentRecord rec = (PendingIntentRecord)sender;
9209                int MY_UID = Binder.getCallingUid();
9210                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9211                BatteryStatsImpl.Uid.Pkg pkg =
9212                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9213                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9214                pkg.incWakeupsLocked();
9215            }
9216        }
9217    }
9218
9219    public boolean killPids(int[] pids, String pReason, boolean secure) {
9220        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9221            throw new SecurityException("killPids only available to the system");
9222        }
9223        String reason = (pReason == null) ? "Unknown" : pReason;
9224        // XXX Note: don't acquire main activity lock here, because the window
9225        // manager calls in with its locks held.
9226
9227        boolean killed = false;
9228        synchronized (mPidsSelfLocked) {
9229            int[] types = new int[pids.length];
9230            int worstType = 0;
9231            for (int i=0; i<pids.length; i++) {
9232                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9233                if (proc != null) {
9234                    int type = proc.setAdj;
9235                    types[i] = type;
9236                    if (type > worstType) {
9237                        worstType = type;
9238                    }
9239                }
9240            }
9241
9242            // If the worst oom_adj is somewhere in the cached proc LRU range,
9243            // then constrain it so we will kill all cached procs.
9244            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9245                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9246                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9247            }
9248
9249            // If this is not a secure call, don't let it kill processes that
9250            // are important.
9251            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9252                worstType = ProcessList.SERVICE_ADJ;
9253            }
9254
9255            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9256            for (int i=0; i<pids.length; i++) {
9257                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9258                if (proc == null) {
9259                    continue;
9260                }
9261                int adj = proc.setAdj;
9262                if (adj >= worstType && !proc.killedByAm) {
9263                    killUnneededProcessLocked(proc, reason);
9264                    killed = true;
9265                }
9266            }
9267        }
9268        return killed;
9269    }
9270
9271    @Override
9272    public void killUid(int uid, String reason) {
9273        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9274            throw new SecurityException("killUid only available to the system");
9275        }
9276        synchronized (this) {
9277            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9278                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9279                    reason != null ? reason : "kill uid");
9280        }
9281    }
9282
9283    @Override
9284    public boolean killProcessesBelowForeground(String reason) {
9285        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9286            throw new SecurityException("killProcessesBelowForeground() only available to system");
9287        }
9288
9289        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9290    }
9291
9292    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9293        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9294            throw new SecurityException("killProcessesBelowAdj() only available to system");
9295        }
9296
9297        boolean killed = false;
9298        synchronized (mPidsSelfLocked) {
9299            final int size = mPidsSelfLocked.size();
9300            for (int i = 0; i < size; i++) {
9301                final int pid = mPidsSelfLocked.keyAt(i);
9302                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9303                if (proc == null) continue;
9304
9305                final int adj = proc.setAdj;
9306                if (adj > belowAdj && !proc.killedByAm) {
9307                    killUnneededProcessLocked(proc, reason);
9308                    killed = true;
9309                }
9310            }
9311        }
9312        return killed;
9313    }
9314
9315    @Override
9316    public void hang(final IBinder who, boolean allowRestart) {
9317        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9318                != PackageManager.PERMISSION_GRANTED) {
9319            throw new SecurityException("Requires permission "
9320                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9321        }
9322
9323        final IBinder.DeathRecipient death = new DeathRecipient() {
9324            @Override
9325            public void binderDied() {
9326                synchronized (this) {
9327                    notifyAll();
9328                }
9329            }
9330        };
9331
9332        try {
9333            who.linkToDeath(death, 0);
9334        } catch (RemoteException e) {
9335            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9336            return;
9337        }
9338
9339        synchronized (this) {
9340            Watchdog.getInstance().setAllowRestart(allowRestart);
9341            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9342            synchronized (death) {
9343                while (who.isBinderAlive()) {
9344                    try {
9345                        death.wait();
9346                    } catch (InterruptedException e) {
9347                    }
9348                }
9349            }
9350            Watchdog.getInstance().setAllowRestart(true);
9351        }
9352    }
9353
9354    @Override
9355    public void restart() {
9356        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9357                != PackageManager.PERMISSION_GRANTED) {
9358            throw new SecurityException("Requires permission "
9359                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9360        }
9361
9362        Log.i(TAG, "Sending shutdown broadcast...");
9363
9364        BroadcastReceiver br = new BroadcastReceiver() {
9365            @Override public void onReceive(Context context, Intent intent) {
9366                // Now the broadcast is done, finish up the low-level shutdown.
9367                Log.i(TAG, "Shutting down activity manager...");
9368                shutdown(10000);
9369                Log.i(TAG, "Shutdown complete, restarting!");
9370                Process.killProcess(Process.myPid());
9371                System.exit(10);
9372            }
9373        };
9374
9375        // First send the high-level shut down broadcast.
9376        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9377        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9378        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9379        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9380        mContext.sendOrderedBroadcastAsUser(intent,
9381                UserHandle.ALL, null, br, mHandler, 0, null, null);
9382        */
9383        br.onReceive(mContext, intent);
9384    }
9385
9386    private long getLowRamTimeSinceIdle(long now) {
9387        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9388    }
9389
9390    @Override
9391    public void performIdleMaintenance() {
9392        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9393                != PackageManager.PERMISSION_GRANTED) {
9394            throw new SecurityException("Requires permission "
9395                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9396        }
9397
9398        synchronized (this) {
9399            final long now = SystemClock.uptimeMillis();
9400            final long timeSinceLastIdle = now - mLastIdleTime;
9401            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9402            mLastIdleTime = now;
9403            mLowRamTimeSinceLastIdle = 0;
9404            if (mLowRamStartTime != 0) {
9405                mLowRamStartTime = now;
9406            }
9407
9408            StringBuilder sb = new StringBuilder(128);
9409            sb.append("Idle maintenance over ");
9410            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9411            sb.append(" low RAM for ");
9412            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9413            Slog.i(TAG, sb.toString());
9414
9415            // If at least 1/3 of our time since the last idle period has been spent
9416            // with RAM low, then we want to kill processes.
9417            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9418
9419            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9420                ProcessRecord proc = mLruProcesses.get(i);
9421                if (proc.notCachedSinceIdle) {
9422                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9423                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9424                        if (doKilling && proc.initialIdlePss != 0
9425                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9426                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9427                                    + " from " + proc.initialIdlePss + ")");
9428                        }
9429                    }
9430                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9431                    proc.notCachedSinceIdle = true;
9432                    proc.initialIdlePss = 0;
9433                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9434                            isSleeping(), now);
9435                }
9436            }
9437
9438            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9439            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9440        }
9441    }
9442
9443    private void retrieveSettings() {
9444        final ContentResolver resolver = mContext.getContentResolver();
9445        String debugApp = Settings.Global.getString(
9446            resolver, Settings.Global.DEBUG_APP);
9447        boolean waitForDebugger = Settings.Global.getInt(
9448            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9449        boolean alwaysFinishActivities = Settings.Global.getInt(
9450            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9451        boolean forceRtl = Settings.Global.getInt(
9452                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9453        // Transfer any global setting for forcing RTL layout, into a System Property
9454        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9455
9456        Configuration configuration = new Configuration();
9457        Settings.System.getConfiguration(resolver, configuration);
9458        if (forceRtl) {
9459            // This will take care of setting the correct layout direction flags
9460            configuration.setLayoutDirection(configuration.locale);
9461        }
9462
9463        synchronized (this) {
9464            mDebugApp = mOrigDebugApp = debugApp;
9465            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9466            mAlwaysFinishActivities = alwaysFinishActivities;
9467            // This happens before any activities are started, so we can
9468            // change mConfiguration in-place.
9469            updateConfigurationLocked(configuration, null, false, true);
9470            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9471        }
9472    }
9473
9474    public boolean testIsSystemReady() {
9475        // no need to synchronize(this) just to read & return the value
9476        return mSystemReady;
9477    }
9478
9479    private static File getCalledPreBootReceiversFile() {
9480        File dataDir = Environment.getDataDirectory();
9481        File systemDir = new File(dataDir, "system");
9482        File fname = new File(systemDir, "called_pre_boots.dat");
9483        return fname;
9484    }
9485
9486    static final int LAST_DONE_VERSION = 10000;
9487
9488    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9489        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9490        File file = getCalledPreBootReceiversFile();
9491        FileInputStream fis = null;
9492        try {
9493            fis = new FileInputStream(file);
9494            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9495            int fvers = dis.readInt();
9496            if (fvers == LAST_DONE_VERSION) {
9497                String vers = dis.readUTF();
9498                String codename = dis.readUTF();
9499                String build = dis.readUTF();
9500                if (android.os.Build.VERSION.RELEASE.equals(vers)
9501                        && android.os.Build.VERSION.CODENAME.equals(codename)
9502                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9503                    int num = dis.readInt();
9504                    while (num > 0) {
9505                        num--;
9506                        String pkg = dis.readUTF();
9507                        String cls = dis.readUTF();
9508                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9509                    }
9510                }
9511            }
9512        } catch (FileNotFoundException e) {
9513        } catch (IOException e) {
9514            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9515        } finally {
9516            if (fis != null) {
9517                try {
9518                    fis.close();
9519                } catch (IOException e) {
9520                }
9521            }
9522        }
9523        return lastDoneReceivers;
9524    }
9525
9526    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9527        File file = getCalledPreBootReceiversFile();
9528        FileOutputStream fos = null;
9529        DataOutputStream dos = null;
9530        try {
9531            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9532            fos = new FileOutputStream(file);
9533            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9534            dos.writeInt(LAST_DONE_VERSION);
9535            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9536            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9537            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9538            dos.writeInt(list.size());
9539            for (int i=0; i<list.size(); i++) {
9540                dos.writeUTF(list.get(i).getPackageName());
9541                dos.writeUTF(list.get(i).getClassName());
9542            }
9543        } catch (IOException e) {
9544            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9545            file.delete();
9546        } finally {
9547            FileUtils.sync(fos);
9548            if (dos != null) {
9549                try {
9550                    dos.close();
9551                } catch (IOException e) {
9552                    // TODO Auto-generated catch block
9553                    e.printStackTrace();
9554                }
9555            }
9556        }
9557    }
9558
9559    public void systemReady(final Runnable goingCallback) {
9560        synchronized(this) {
9561            if (mSystemReady) {
9562                if (goingCallback != null) goingCallback.run();
9563                return;
9564            }
9565
9566            // Check to see if there are any update receivers to run.
9567            if (!mDidUpdate) {
9568                if (mWaitingUpdate) {
9569                    return;
9570                }
9571                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9572                List<ResolveInfo> ris = null;
9573                try {
9574                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9575                            intent, null, 0, 0);
9576                } catch (RemoteException e) {
9577                }
9578                if (ris != null) {
9579                    for (int i=ris.size()-1; i>=0; i--) {
9580                        if ((ris.get(i).activityInfo.applicationInfo.flags
9581                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9582                            ris.remove(i);
9583                        }
9584                    }
9585                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9586
9587                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9588
9589                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9590                    for (int i=0; i<ris.size(); i++) {
9591                        ActivityInfo ai = ris.get(i).activityInfo;
9592                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9593                        if (lastDoneReceivers.contains(comp)) {
9594                            // We already did the pre boot receiver for this app with the current
9595                            // platform version, so don't do it again...
9596                            ris.remove(i);
9597                            i--;
9598                            // ...however, do keep it as one that has been done, so we don't
9599                            // forget about it when rewriting the file of last done receivers.
9600                            doneReceivers.add(comp);
9601                        }
9602                    }
9603
9604                    final int[] users = getUsersLocked();
9605                    for (int i=0; i<ris.size(); i++) {
9606                        ActivityInfo ai = ris.get(i).activityInfo;
9607                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9608                        doneReceivers.add(comp);
9609                        intent.setComponent(comp);
9610                        for (int j=0; j<users.length; j++) {
9611                            IIntentReceiver finisher = null;
9612                            if (i == ris.size()-1 && j == users.length-1) {
9613                                finisher = new IIntentReceiver.Stub() {
9614                                    public void performReceive(Intent intent, int resultCode,
9615                                            String data, Bundle extras, boolean ordered,
9616                                            boolean sticky, int sendingUser) {
9617                                        // The raw IIntentReceiver interface is called
9618                                        // with the AM lock held, so redispatch to
9619                                        // execute our code without the lock.
9620                                        mHandler.post(new Runnable() {
9621                                            public void run() {
9622                                                synchronized (ActivityManagerService.this) {
9623                                                    mDidUpdate = true;
9624                                                }
9625                                                writeLastDonePreBootReceivers(doneReceivers);
9626                                                showBootMessage(mContext.getText(
9627                                                        R.string.android_upgrading_complete),
9628                                                        false);
9629                                                systemReady(goingCallback);
9630                                            }
9631                                        });
9632                                    }
9633                                };
9634                            }
9635                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9636                                    + " for user " + users[j]);
9637                            broadcastIntentLocked(null, null, intent, null, finisher,
9638                                    0, null, null, null, AppOpsManager.OP_NONE,
9639                                    true, false, MY_PID, Process.SYSTEM_UID,
9640                                    users[j]);
9641                            if (finisher != null) {
9642                                mWaitingUpdate = true;
9643                            }
9644                        }
9645                    }
9646                }
9647                if (mWaitingUpdate) {
9648                    return;
9649                }
9650                mDidUpdate = true;
9651            }
9652
9653            mAppOpsService.systemReady();
9654            mUsageStatsService.systemReady();
9655            mSystemReady = true;
9656        }
9657
9658        ArrayList<ProcessRecord> procsToKill = null;
9659        synchronized(mPidsSelfLocked) {
9660            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9661                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9662                if (!isAllowedWhileBooting(proc.info)){
9663                    if (procsToKill == null) {
9664                        procsToKill = new ArrayList<ProcessRecord>();
9665                    }
9666                    procsToKill.add(proc);
9667                }
9668            }
9669        }
9670
9671        synchronized(this) {
9672            if (procsToKill != null) {
9673                for (int i=procsToKill.size()-1; i>=0; i--) {
9674                    ProcessRecord proc = procsToKill.get(i);
9675                    Slog.i(TAG, "Removing system update proc: " + proc);
9676                    removeProcessLocked(proc, true, false, "system update done");
9677                }
9678            }
9679
9680            // Now that we have cleaned up any update processes, we
9681            // are ready to start launching real processes and know that
9682            // we won't trample on them any more.
9683            mProcessesReady = true;
9684        }
9685
9686        Slog.i(TAG, "System now ready");
9687        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9688            SystemClock.uptimeMillis());
9689
9690        synchronized(this) {
9691            // Make sure we have no pre-ready processes sitting around.
9692
9693            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9694                ResolveInfo ri = mContext.getPackageManager()
9695                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9696                                STOCK_PM_FLAGS);
9697                CharSequence errorMsg = null;
9698                if (ri != null) {
9699                    ActivityInfo ai = ri.activityInfo;
9700                    ApplicationInfo app = ai.applicationInfo;
9701                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9702                        mTopAction = Intent.ACTION_FACTORY_TEST;
9703                        mTopData = null;
9704                        mTopComponent = new ComponentName(app.packageName,
9705                                ai.name);
9706                    } else {
9707                        errorMsg = mContext.getResources().getText(
9708                                com.android.internal.R.string.factorytest_not_system);
9709                    }
9710                } else {
9711                    errorMsg = mContext.getResources().getText(
9712                            com.android.internal.R.string.factorytest_no_action);
9713                }
9714                if (errorMsg != null) {
9715                    mTopAction = null;
9716                    mTopData = null;
9717                    mTopComponent = null;
9718                    Message msg = Message.obtain();
9719                    msg.what = SHOW_FACTORY_ERROR_MSG;
9720                    msg.getData().putCharSequence("msg", errorMsg);
9721                    mHandler.sendMessage(msg);
9722                }
9723            }
9724        }
9725
9726        retrieveSettings();
9727
9728        synchronized (this) {
9729            readGrantedUriPermissionsLocked();
9730        }
9731
9732        if (goingCallback != null) goingCallback.run();
9733
9734        mSystemServiceManager.startUser(mCurrentUserId);
9735
9736        synchronized (this) {
9737            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9738                try {
9739                    List apps = AppGlobals.getPackageManager().
9740                        getPersistentApplications(STOCK_PM_FLAGS);
9741                    if (apps != null) {
9742                        int N = apps.size();
9743                        int i;
9744                        for (i=0; i<N; i++) {
9745                            ApplicationInfo info
9746                                = (ApplicationInfo)apps.get(i);
9747                            if (info != null &&
9748                                    !info.packageName.equals("android")) {
9749                                addAppLocked(info, false);
9750                            }
9751                        }
9752                    }
9753                } catch (RemoteException ex) {
9754                    // pm is in same process, this will never happen.
9755                }
9756            }
9757
9758            // Start up initial activity.
9759            mBooting = true;
9760
9761            try {
9762                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9763                    Message msg = Message.obtain();
9764                    msg.what = SHOW_UID_ERROR_MSG;
9765                    mHandler.sendMessage(msg);
9766                }
9767            } catch (RemoteException e) {
9768            }
9769
9770            long ident = Binder.clearCallingIdentity();
9771            try {
9772                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9773                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9774                        | Intent.FLAG_RECEIVER_FOREGROUND);
9775                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9776                broadcastIntentLocked(null, null, intent,
9777                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9778                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9779                intent = new Intent(Intent.ACTION_USER_STARTING);
9780                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9781                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9782                broadcastIntentLocked(null, null, intent,
9783                        null, new IIntentReceiver.Stub() {
9784                            @Override
9785                            public void performReceive(Intent intent, int resultCode, String data,
9786                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9787                                    throws RemoteException {
9788                            }
9789                        }, 0, null, null,
9790                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9791                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9792            } catch (Throwable t) {
9793                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9794            } finally {
9795                Binder.restoreCallingIdentity(ident);
9796            }
9797            mStackSupervisor.resumeTopActivitiesLocked();
9798            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9799        }
9800    }
9801
9802    private boolean makeAppCrashingLocked(ProcessRecord app,
9803            String shortMsg, String longMsg, String stackTrace) {
9804        app.crashing = true;
9805        app.crashingReport = generateProcessError(app,
9806                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9807        startAppProblemLocked(app);
9808        app.stopFreezingAllLocked();
9809        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9810    }
9811
9812    private void makeAppNotRespondingLocked(ProcessRecord app,
9813            String activity, String shortMsg, String longMsg) {
9814        app.notResponding = true;
9815        app.notRespondingReport = generateProcessError(app,
9816                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9817                activity, shortMsg, longMsg, null);
9818        startAppProblemLocked(app);
9819        app.stopFreezingAllLocked();
9820    }
9821
9822    /**
9823     * Generate a process error record, suitable for attachment to a ProcessRecord.
9824     *
9825     * @param app The ProcessRecord in which the error occurred.
9826     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9827     *                      ActivityManager.AppErrorStateInfo
9828     * @param activity The activity associated with the crash, if known.
9829     * @param shortMsg Short message describing the crash.
9830     * @param longMsg Long message describing the crash.
9831     * @param stackTrace Full crash stack trace, may be null.
9832     *
9833     * @return Returns a fully-formed AppErrorStateInfo record.
9834     */
9835    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9836            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9837        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9838
9839        report.condition = condition;
9840        report.processName = app.processName;
9841        report.pid = app.pid;
9842        report.uid = app.info.uid;
9843        report.tag = activity;
9844        report.shortMsg = shortMsg;
9845        report.longMsg = longMsg;
9846        report.stackTrace = stackTrace;
9847
9848        return report;
9849    }
9850
9851    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9852        synchronized (this) {
9853            app.crashing = false;
9854            app.crashingReport = null;
9855            app.notResponding = false;
9856            app.notRespondingReport = null;
9857            if (app.anrDialog == fromDialog) {
9858                app.anrDialog = null;
9859            }
9860            if (app.waitDialog == fromDialog) {
9861                app.waitDialog = null;
9862            }
9863            if (app.pid > 0 && app.pid != MY_PID) {
9864                handleAppCrashLocked(app, null, null, null);
9865                killUnneededProcessLocked(app, "user request after error");
9866            }
9867        }
9868    }
9869
9870    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9871            String stackTrace) {
9872        long now = SystemClock.uptimeMillis();
9873
9874        Long crashTime;
9875        if (!app.isolated) {
9876            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9877        } else {
9878            crashTime = null;
9879        }
9880        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9881            // This process loses!
9882            Slog.w(TAG, "Process " + app.info.processName
9883                    + " has crashed too many times: killing!");
9884            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9885                    app.userId, app.info.processName, app.uid);
9886            mStackSupervisor.handleAppCrashLocked(app);
9887            if (!app.persistent) {
9888                // We don't want to start this process again until the user
9889                // explicitly does so...  but for persistent process, we really
9890                // need to keep it running.  If a persistent process is actually
9891                // repeatedly crashing, then badness for everyone.
9892                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9893                        app.info.processName);
9894                if (!app.isolated) {
9895                    // XXX We don't have a way to mark isolated processes
9896                    // as bad, since they don't have a peristent identity.
9897                    mBadProcesses.put(app.info.processName, app.uid,
9898                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9899                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9900                }
9901                app.bad = true;
9902                app.removed = true;
9903                // Don't let services in this process be restarted and potentially
9904                // annoy the user repeatedly.  Unless it is persistent, since those
9905                // processes run critical code.
9906                removeProcessLocked(app, false, false, "crash");
9907                mStackSupervisor.resumeTopActivitiesLocked();
9908                return false;
9909            }
9910            mStackSupervisor.resumeTopActivitiesLocked();
9911        } else {
9912            mStackSupervisor.finishTopRunningActivityLocked(app);
9913        }
9914
9915        // Bump up the crash count of any services currently running in the proc.
9916        for (int i=app.services.size()-1; i>=0; i--) {
9917            // Any services running in the application need to be placed
9918            // back in the pending list.
9919            ServiceRecord sr = app.services.valueAt(i);
9920            sr.crashCount++;
9921        }
9922
9923        // If the crashing process is what we consider to be the "home process" and it has been
9924        // replaced by a third-party app, clear the package preferred activities from packages
9925        // with a home activity running in the process to prevent a repeatedly crashing app
9926        // from blocking the user to manually clear the list.
9927        final ArrayList<ActivityRecord> activities = app.activities;
9928        if (app == mHomeProcess && activities.size() > 0
9929                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9930            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9931                final ActivityRecord r = activities.get(activityNdx);
9932                if (r.isHomeActivity()) {
9933                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9934                    try {
9935                        ActivityThread.getPackageManager()
9936                                .clearPackagePreferredActivities(r.packageName);
9937                    } catch (RemoteException c) {
9938                        // pm is in same process, this will never happen.
9939                    }
9940                }
9941            }
9942        }
9943
9944        if (!app.isolated) {
9945            // XXX Can't keep track of crash times for isolated processes,
9946            // because they don't have a perisistent identity.
9947            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9948        }
9949
9950        return true;
9951    }
9952
9953    void startAppProblemLocked(ProcessRecord app) {
9954        if (app.userId == mCurrentUserId) {
9955            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9956                    mContext, app.info.packageName, app.info.flags);
9957        } else {
9958            // If this app is not running under the current user, then we
9959            // can't give it a report button because that would require
9960            // launching the report UI under a different user.
9961            app.errorReportReceiver = null;
9962        }
9963        skipCurrentReceiverLocked(app);
9964    }
9965
9966    void skipCurrentReceiverLocked(ProcessRecord app) {
9967        for (BroadcastQueue queue : mBroadcastQueues) {
9968            queue.skipCurrentReceiverLocked(app);
9969        }
9970    }
9971
9972    /**
9973     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9974     * The application process will exit immediately after this call returns.
9975     * @param app object of the crashing app, null for the system server
9976     * @param crashInfo describing the exception
9977     */
9978    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9979        ProcessRecord r = findAppProcess(app, "Crash");
9980        final String processName = app == null ? "system_server"
9981                : (r == null ? "unknown" : r.processName);
9982
9983        handleApplicationCrashInner("crash", r, processName, crashInfo);
9984    }
9985
9986    /* Native crash reporting uses this inner version because it needs to be somewhat
9987     * decoupled from the AM-managed cleanup lifecycle
9988     */
9989    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9990            ApplicationErrorReport.CrashInfo crashInfo) {
9991        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9992                UserHandle.getUserId(Binder.getCallingUid()), processName,
9993                r == null ? -1 : r.info.flags,
9994                crashInfo.exceptionClassName,
9995                crashInfo.exceptionMessage,
9996                crashInfo.throwFileName,
9997                crashInfo.throwLineNumber);
9998
9999        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10000
10001        crashApplication(r, crashInfo);
10002    }
10003
10004    public void handleApplicationStrictModeViolation(
10005            IBinder app,
10006            int violationMask,
10007            StrictMode.ViolationInfo info) {
10008        ProcessRecord r = findAppProcess(app, "StrictMode");
10009        if (r == null) {
10010            return;
10011        }
10012
10013        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10014            Integer stackFingerprint = info.hashCode();
10015            boolean logIt = true;
10016            synchronized (mAlreadyLoggedViolatedStacks) {
10017                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10018                    logIt = false;
10019                    // TODO: sub-sample into EventLog for these, with
10020                    // the info.durationMillis?  Then we'd get
10021                    // the relative pain numbers, without logging all
10022                    // the stack traces repeatedly.  We'd want to do
10023                    // likewise in the client code, which also does
10024                    // dup suppression, before the Binder call.
10025                } else {
10026                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10027                        mAlreadyLoggedViolatedStacks.clear();
10028                    }
10029                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10030                }
10031            }
10032            if (logIt) {
10033                logStrictModeViolationToDropBox(r, info);
10034            }
10035        }
10036
10037        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10038            AppErrorResult result = new AppErrorResult();
10039            synchronized (this) {
10040                final long origId = Binder.clearCallingIdentity();
10041
10042                Message msg = Message.obtain();
10043                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10044                HashMap<String, Object> data = new HashMap<String, Object>();
10045                data.put("result", result);
10046                data.put("app", r);
10047                data.put("violationMask", violationMask);
10048                data.put("info", info);
10049                msg.obj = data;
10050                mHandler.sendMessage(msg);
10051
10052                Binder.restoreCallingIdentity(origId);
10053            }
10054            int res = result.get();
10055            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10056        }
10057    }
10058
10059    // Depending on the policy in effect, there could be a bunch of
10060    // these in quick succession so we try to batch these together to
10061    // minimize disk writes, number of dropbox entries, and maximize
10062    // compression, by having more fewer, larger records.
10063    private void logStrictModeViolationToDropBox(
10064            ProcessRecord process,
10065            StrictMode.ViolationInfo info) {
10066        if (info == null) {
10067            return;
10068        }
10069        final boolean isSystemApp = process == null ||
10070                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10071                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10072        final String processName = process == null ? "unknown" : process.processName;
10073        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10074        final DropBoxManager dbox = (DropBoxManager)
10075                mContext.getSystemService(Context.DROPBOX_SERVICE);
10076
10077        // Exit early if the dropbox isn't configured to accept this report type.
10078        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10079
10080        boolean bufferWasEmpty;
10081        boolean needsFlush;
10082        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10083        synchronized (sb) {
10084            bufferWasEmpty = sb.length() == 0;
10085            appendDropBoxProcessHeaders(process, processName, sb);
10086            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10087            sb.append("System-App: ").append(isSystemApp).append("\n");
10088            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10089            if (info.violationNumThisLoop != 0) {
10090                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10091            }
10092            if (info.numAnimationsRunning != 0) {
10093                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10094            }
10095            if (info.broadcastIntentAction != null) {
10096                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10097            }
10098            if (info.durationMillis != -1) {
10099                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10100            }
10101            if (info.numInstances != -1) {
10102                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10103            }
10104            if (info.tags != null) {
10105                for (String tag : info.tags) {
10106                    sb.append("Span-Tag: ").append(tag).append("\n");
10107                }
10108            }
10109            sb.append("\n");
10110            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10111                sb.append(info.crashInfo.stackTrace);
10112            }
10113            sb.append("\n");
10114
10115            // Only buffer up to ~64k.  Various logging bits truncate
10116            // things at 128k.
10117            needsFlush = (sb.length() > 64 * 1024);
10118        }
10119
10120        // Flush immediately if the buffer's grown too large, or this
10121        // is a non-system app.  Non-system apps are isolated with a
10122        // different tag & policy and not batched.
10123        //
10124        // Batching is useful during internal testing with
10125        // StrictMode settings turned up high.  Without batching,
10126        // thousands of separate files could be created on boot.
10127        if (!isSystemApp || needsFlush) {
10128            new Thread("Error dump: " + dropboxTag) {
10129                @Override
10130                public void run() {
10131                    String report;
10132                    synchronized (sb) {
10133                        report = sb.toString();
10134                        sb.delete(0, sb.length());
10135                        sb.trimToSize();
10136                    }
10137                    if (report.length() != 0) {
10138                        dbox.addText(dropboxTag, report);
10139                    }
10140                }
10141            }.start();
10142            return;
10143        }
10144
10145        // System app batching:
10146        if (!bufferWasEmpty) {
10147            // An existing dropbox-writing thread is outstanding, so
10148            // we don't need to start it up.  The existing thread will
10149            // catch the buffer appends we just did.
10150            return;
10151        }
10152
10153        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10154        // (After this point, we shouldn't access AMS internal data structures.)
10155        new Thread("Error dump: " + dropboxTag) {
10156            @Override
10157            public void run() {
10158                // 5 second sleep to let stacks arrive and be batched together
10159                try {
10160                    Thread.sleep(5000);  // 5 seconds
10161                } catch (InterruptedException e) {}
10162
10163                String errorReport;
10164                synchronized (mStrictModeBuffer) {
10165                    errorReport = mStrictModeBuffer.toString();
10166                    if (errorReport.length() == 0) {
10167                        return;
10168                    }
10169                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10170                    mStrictModeBuffer.trimToSize();
10171                }
10172                dbox.addText(dropboxTag, errorReport);
10173            }
10174        }.start();
10175    }
10176
10177    /**
10178     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10179     * @param app object of the crashing app, null for the system server
10180     * @param tag reported by the caller
10181     * @param crashInfo describing the context of the error
10182     * @return true if the process should exit immediately (WTF is fatal)
10183     */
10184    public boolean handleApplicationWtf(IBinder app, String tag,
10185            ApplicationErrorReport.CrashInfo crashInfo) {
10186        ProcessRecord r = findAppProcess(app, "WTF");
10187        final String processName = app == null ? "system_server"
10188                : (r == null ? "unknown" : r.processName);
10189
10190        EventLog.writeEvent(EventLogTags.AM_WTF,
10191                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10192                processName,
10193                r == null ? -1 : r.info.flags,
10194                tag, crashInfo.exceptionMessage);
10195
10196        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10197
10198        if (r != null && r.pid != Process.myPid() &&
10199                Settings.Global.getInt(mContext.getContentResolver(),
10200                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10201            crashApplication(r, crashInfo);
10202            return true;
10203        } else {
10204            return false;
10205        }
10206    }
10207
10208    /**
10209     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10210     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10211     */
10212    private ProcessRecord findAppProcess(IBinder app, String reason) {
10213        if (app == null) {
10214            return null;
10215        }
10216
10217        synchronized (this) {
10218            final int NP = mProcessNames.getMap().size();
10219            for (int ip=0; ip<NP; ip++) {
10220                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10221                final int NA = apps.size();
10222                for (int ia=0; ia<NA; ia++) {
10223                    ProcessRecord p = apps.valueAt(ia);
10224                    if (p.thread != null && p.thread.asBinder() == app) {
10225                        return p;
10226                    }
10227                }
10228            }
10229
10230            Slog.w(TAG, "Can't find mystery application for " + reason
10231                    + " from pid=" + Binder.getCallingPid()
10232                    + " uid=" + Binder.getCallingUid() + ": " + app);
10233            return null;
10234        }
10235    }
10236
10237    /**
10238     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10239     * to append various headers to the dropbox log text.
10240     */
10241    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10242            StringBuilder sb) {
10243        // Watchdog thread ends up invoking this function (with
10244        // a null ProcessRecord) to add the stack file to dropbox.
10245        // Do not acquire a lock on this (am) in such cases, as it
10246        // could cause a potential deadlock, if and when watchdog
10247        // is invoked due to unavailability of lock on am and it
10248        // would prevent watchdog from killing system_server.
10249        if (process == null) {
10250            sb.append("Process: ").append(processName).append("\n");
10251            return;
10252        }
10253        // Note: ProcessRecord 'process' is guarded by the service
10254        // instance.  (notably process.pkgList, which could otherwise change
10255        // concurrently during execution of this method)
10256        synchronized (this) {
10257            sb.append("Process: ").append(processName).append("\n");
10258            int flags = process.info.flags;
10259            IPackageManager pm = AppGlobals.getPackageManager();
10260            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10261            for (int ip=0; ip<process.pkgList.size(); ip++) {
10262                String pkg = process.pkgList.keyAt(ip);
10263                sb.append("Package: ").append(pkg);
10264                try {
10265                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10266                    if (pi != null) {
10267                        sb.append(" v").append(pi.versionCode);
10268                        if (pi.versionName != null) {
10269                            sb.append(" (").append(pi.versionName).append(")");
10270                        }
10271                    }
10272                } catch (RemoteException e) {
10273                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10274                }
10275                sb.append("\n");
10276            }
10277        }
10278    }
10279
10280    private static String processClass(ProcessRecord process) {
10281        if (process == null || process.pid == MY_PID) {
10282            return "system_server";
10283        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10284            return "system_app";
10285        } else {
10286            return "data_app";
10287        }
10288    }
10289
10290    /**
10291     * Write a description of an error (crash, WTF, ANR) to the drop box.
10292     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10293     * @param process which caused the error, null means the system server
10294     * @param activity which triggered the error, null if unknown
10295     * @param parent activity related to the error, null if unknown
10296     * @param subject line related to the error, null if absent
10297     * @param report in long form describing the error, null if absent
10298     * @param logFile to include in the report, null if none
10299     * @param crashInfo giving an application stack trace, null if absent
10300     */
10301    public void addErrorToDropBox(String eventType,
10302            ProcessRecord process, String processName, ActivityRecord activity,
10303            ActivityRecord parent, String subject,
10304            final String report, final File logFile,
10305            final ApplicationErrorReport.CrashInfo crashInfo) {
10306        // NOTE -- this must never acquire the ActivityManagerService lock,
10307        // otherwise the watchdog may be prevented from resetting the system.
10308
10309        final String dropboxTag = processClass(process) + "_" + eventType;
10310        final DropBoxManager dbox = (DropBoxManager)
10311                mContext.getSystemService(Context.DROPBOX_SERVICE);
10312
10313        // Exit early if the dropbox isn't configured to accept this report type.
10314        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10315
10316        final StringBuilder sb = new StringBuilder(1024);
10317        appendDropBoxProcessHeaders(process, processName, sb);
10318        if (activity != null) {
10319            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10320        }
10321        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10322            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10323        }
10324        if (parent != null && parent != activity) {
10325            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10326        }
10327        if (subject != null) {
10328            sb.append("Subject: ").append(subject).append("\n");
10329        }
10330        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10331        if (Debug.isDebuggerConnected()) {
10332            sb.append("Debugger: Connected\n");
10333        }
10334        sb.append("\n");
10335
10336        // Do the rest in a worker thread to avoid blocking the caller on I/O
10337        // (After this point, we shouldn't access AMS internal data structures.)
10338        Thread worker = new Thread("Error dump: " + dropboxTag) {
10339            @Override
10340            public void run() {
10341                if (report != null) {
10342                    sb.append(report);
10343                }
10344                if (logFile != null) {
10345                    try {
10346                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10347                                    "\n\n[[TRUNCATED]]"));
10348                    } catch (IOException e) {
10349                        Slog.e(TAG, "Error reading " + logFile, e);
10350                    }
10351                }
10352                if (crashInfo != null && crashInfo.stackTrace != null) {
10353                    sb.append(crashInfo.stackTrace);
10354                }
10355
10356                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10357                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10358                if (lines > 0) {
10359                    sb.append("\n");
10360
10361                    // Merge several logcat streams, and take the last N lines
10362                    InputStreamReader input = null;
10363                    try {
10364                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10365                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10366                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10367
10368                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10369                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10370                        input = new InputStreamReader(logcat.getInputStream());
10371
10372                        int num;
10373                        char[] buf = new char[8192];
10374                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10375                    } catch (IOException e) {
10376                        Slog.e(TAG, "Error running logcat", e);
10377                    } finally {
10378                        if (input != null) try { input.close(); } catch (IOException e) {}
10379                    }
10380                }
10381
10382                dbox.addText(dropboxTag, sb.toString());
10383            }
10384        };
10385
10386        if (process == null) {
10387            // If process is null, we are being called from some internal code
10388            // and may be about to die -- run this synchronously.
10389            worker.run();
10390        } else {
10391            worker.start();
10392        }
10393    }
10394
10395    /**
10396     * Bring up the "unexpected error" dialog box for a crashing app.
10397     * Deal with edge cases (intercepts from instrumented applications,
10398     * ActivityController, error intent receivers, that sort of thing).
10399     * @param r the application crashing
10400     * @param crashInfo describing the failure
10401     */
10402    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10403        long timeMillis = System.currentTimeMillis();
10404        String shortMsg = crashInfo.exceptionClassName;
10405        String longMsg = crashInfo.exceptionMessage;
10406        String stackTrace = crashInfo.stackTrace;
10407        if (shortMsg != null && longMsg != null) {
10408            longMsg = shortMsg + ": " + longMsg;
10409        } else if (shortMsg != null) {
10410            longMsg = shortMsg;
10411        }
10412
10413        AppErrorResult result = new AppErrorResult();
10414        synchronized (this) {
10415            if (mController != null) {
10416                try {
10417                    String name = r != null ? r.processName : null;
10418                    int pid = r != null ? r.pid : Binder.getCallingPid();
10419                    if (!mController.appCrashed(name, pid,
10420                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10421                        Slog.w(TAG, "Force-killing crashed app " + name
10422                                + " at watcher's request");
10423                        Process.killProcess(pid);
10424                        return;
10425                    }
10426                } catch (RemoteException e) {
10427                    mController = null;
10428                    Watchdog.getInstance().setActivityController(null);
10429                }
10430            }
10431
10432            final long origId = Binder.clearCallingIdentity();
10433
10434            // If this process is running instrumentation, finish it.
10435            if (r != null && r.instrumentationClass != null) {
10436                Slog.w(TAG, "Error in app " + r.processName
10437                      + " running instrumentation " + r.instrumentationClass + ":");
10438                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10439                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10440                Bundle info = new Bundle();
10441                info.putString("shortMsg", shortMsg);
10442                info.putString("longMsg", longMsg);
10443                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10444                Binder.restoreCallingIdentity(origId);
10445                return;
10446            }
10447
10448            // If we can't identify the process or it's already exceeded its crash quota,
10449            // quit right away without showing a crash dialog.
10450            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10451                Binder.restoreCallingIdentity(origId);
10452                return;
10453            }
10454
10455            Message msg = Message.obtain();
10456            msg.what = SHOW_ERROR_MSG;
10457            HashMap data = new HashMap();
10458            data.put("result", result);
10459            data.put("app", r);
10460            msg.obj = data;
10461            mHandler.sendMessage(msg);
10462
10463            Binder.restoreCallingIdentity(origId);
10464        }
10465
10466        int res = result.get();
10467
10468        Intent appErrorIntent = null;
10469        synchronized (this) {
10470            if (r != null && !r.isolated) {
10471                // XXX Can't keep track of crash time for isolated processes,
10472                // since they don't have a persistent identity.
10473                mProcessCrashTimes.put(r.info.processName, r.uid,
10474                        SystemClock.uptimeMillis());
10475            }
10476            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10477                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10478            }
10479        }
10480
10481        if (appErrorIntent != null) {
10482            try {
10483                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10484            } catch (ActivityNotFoundException e) {
10485                Slog.w(TAG, "bug report receiver dissappeared", e);
10486            }
10487        }
10488    }
10489
10490    Intent createAppErrorIntentLocked(ProcessRecord r,
10491            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10492        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10493        if (report == null) {
10494            return null;
10495        }
10496        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10497        result.setComponent(r.errorReportReceiver);
10498        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10499        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10500        return result;
10501    }
10502
10503    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10504            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10505        if (r.errorReportReceiver == null) {
10506            return null;
10507        }
10508
10509        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10510            return null;
10511        }
10512
10513        ApplicationErrorReport report = new ApplicationErrorReport();
10514        report.packageName = r.info.packageName;
10515        report.installerPackageName = r.errorReportReceiver.getPackageName();
10516        report.processName = r.processName;
10517        report.time = timeMillis;
10518        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10519
10520        if (r.crashing || r.forceCrashReport) {
10521            report.type = ApplicationErrorReport.TYPE_CRASH;
10522            report.crashInfo = crashInfo;
10523        } else if (r.notResponding) {
10524            report.type = ApplicationErrorReport.TYPE_ANR;
10525            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10526
10527            report.anrInfo.activity = r.notRespondingReport.tag;
10528            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10529            report.anrInfo.info = r.notRespondingReport.longMsg;
10530        }
10531
10532        return report;
10533    }
10534
10535    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10536        enforceNotIsolatedCaller("getProcessesInErrorState");
10537        // assume our apps are happy - lazy create the list
10538        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10539
10540        final boolean allUsers = ActivityManager.checkUidPermission(
10541                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10542                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10543        int userId = UserHandle.getUserId(Binder.getCallingUid());
10544
10545        synchronized (this) {
10546
10547            // iterate across all processes
10548            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10549                ProcessRecord app = mLruProcesses.get(i);
10550                if (!allUsers && app.userId != userId) {
10551                    continue;
10552                }
10553                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10554                    // This one's in trouble, so we'll generate a report for it
10555                    // crashes are higher priority (in case there's a crash *and* an anr)
10556                    ActivityManager.ProcessErrorStateInfo report = null;
10557                    if (app.crashing) {
10558                        report = app.crashingReport;
10559                    } else if (app.notResponding) {
10560                        report = app.notRespondingReport;
10561                    }
10562
10563                    if (report != null) {
10564                        if (errList == null) {
10565                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10566                        }
10567                        errList.add(report);
10568                    } else {
10569                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10570                                " crashing = " + app.crashing +
10571                                " notResponding = " + app.notResponding);
10572                    }
10573                }
10574            }
10575        }
10576
10577        return errList;
10578    }
10579
10580    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10581        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10582            if (currApp != null) {
10583                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10584            }
10585            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10586        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10587            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10588        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10589            if (currApp != null) {
10590                currApp.lru = 0;
10591            }
10592            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10593        } else if (adj >= ProcessList.SERVICE_ADJ) {
10594            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10595        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10596            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10597        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10598            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10599        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10600            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10601        } else {
10602            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10603        }
10604    }
10605
10606    private void fillInProcMemInfo(ProcessRecord app,
10607            ActivityManager.RunningAppProcessInfo outInfo) {
10608        outInfo.pid = app.pid;
10609        outInfo.uid = app.info.uid;
10610        if (mHeavyWeightProcess == app) {
10611            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10612        }
10613        if (app.persistent) {
10614            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10615        }
10616        if (app.activities.size() > 0) {
10617            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10618        }
10619        outInfo.lastTrimLevel = app.trimMemoryLevel;
10620        int adj = app.curAdj;
10621        outInfo.importance = oomAdjToImportance(adj, outInfo);
10622        outInfo.importanceReasonCode = app.adjTypeCode;
10623        outInfo.processState = app.curProcState;
10624    }
10625
10626    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10627        enforceNotIsolatedCaller("getRunningAppProcesses");
10628        // Lazy instantiation of list
10629        List<ActivityManager.RunningAppProcessInfo> runList = null;
10630        final boolean allUsers = ActivityManager.checkUidPermission(
10631                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10632                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10633        int userId = UserHandle.getUserId(Binder.getCallingUid());
10634        synchronized (this) {
10635            // Iterate across all processes
10636            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10637                ProcessRecord app = mLruProcesses.get(i);
10638                if (!allUsers && app.userId != userId) {
10639                    continue;
10640                }
10641                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10642                    // Generate process state info for running application
10643                    ActivityManager.RunningAppProcessInfo currApp =
10644                        new ActivityManager.RunningAppProcessInfo(app.processName,
10645                                app.pid, app.getPackageList());
10646                    fillInProcMemInfo(app, currApp);
10647                    if (app.adjSource instanceof ProcessRecord) {
10648                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10649                        currApp.importanceReasonImportance = oomAdjToImportance(
10650                                app.adjSourceOom, null);
10651                    } else if (app.adjSource instanceof ActivityRecord) {
10652                        ActivityRecord r = (ActivityRecord)app.adjSource;
10653                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10654                    }
10655                    if (app.adjTarget instanceof ComponentName) {
10656                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10657                    }
10658                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10659                    //        + " lru=" + currApp.lru);
10660                    if (runList == null) {
10661                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10662                    }
10663                    runList.add(currApp);
10664                }
10665            }
10666        }
10667        return runList;
10668    }
10669
10670    public List<ApplicationInfo> getRunningExternalApplications() {
10671        enforceNotIsolatedCaller("getRunningExternalApplications");
10672        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10673        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10674        if (runningApps != null && runningApps.size() > 0) {
10675            Set<String> extList = new HashSet<String>();
10676            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10677                if (app.pkgList != null) {
10678                    for (String pkg : app.pkgList) {
10679                        extList.add(pkg);
10680                    }
10681                }
10682            }
10683            IPackageManager pm = AppGlobals.getPackageManager();
10684            for (String pkg : extList) {
10685                try {
10686                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10687                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10688                        retList.add(info);
10689                    }
10690                } catch (RemoteException e) {
10691                }
10692            }
10693        }
10694        return retList;
10695    }
10696
10697    @Override
10698    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10699        enforceNotIsolatedCaller("getMyMemoryState");
10700        synchronized (this) {
10701            ProcessRecord proc;
10702            synchronized (mPidsSelfLocked) {
10703                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10704            }
10705            fillInProcMemInfo(proc, outInfo);
10706        }
10707    }
10708
10709    @Override
10710    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10711        if (checkCallingPermission(android.Manifest.permission.DUMP)
10712                != PackageManager.PERMISSION_GRANTED) {
10713            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10714                    + Binder.getCallingPid()
10715                    + ", uid=" + Binder.getCallingUid()
10716                    + " without permission "
10717                    + android.Manifest.permission.DUMP);
10718            return;
10719        }
10720
10721        boolean dumpAll = false;
10722        boolean dumpClient = false;
10723        String dumpPackage = null;
10724
10725        int opti = 0;
10726        while (opti < args.length) {
10727            String opt = args[opti];
10728            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10729                break;
10730            }
10731            opti++;
10732            if ("-a".equals(opt)) {
10733                dumpAll = true;
10734            } else if ("-c".equals(opt)) {
10735                dumpClient = true;
10736            } else if ("-h".equals(opt)) {
10737                pw.println("Activity manager dump options:");
10738                pw.println("  [-a] [-c] [-h] [cmd] ...");
10739                pw.println("  cmd may be one of:");
10740                pw.println("    a[ctivities]: activity stack state");
10741                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10742                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10743                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10744                pw.println("    o[om]: out of memory management");
10745                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10746                pw.println("    provider [COMP_SPEC]: provider client-side state");
10747                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10748                pw.println("    service [COMP_SPEC]: service client-side state");
10749                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10750                pw.println("    all: dump all activities");
10751                pw.println("    top: dump the top activity");
10752                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10753                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10754                pw.println("    a partial substring in a component name, a");
10755                pw.println("    hex object identifier.");
10756                pw.println("  -a: include all available server state.");
10757                pw.println("  -c: include client state.");
10758                return;
10759            } else {
10760                pw.println("Unknown argument: " + opt + "; use -h for help");
10761            }
10762        }
10763
10764        long origId = Binder.clearCallingIdentity();
10765        boolean more = false;
10766        // Is the caller requesting to dump a particular piece of data?
10767        if (opti < args.length) {
10768            String cmd = args[opti];
10769            opti++;
10770            if ("activities".equals(cmd) || "a".equals(cmd)) {
10771                synchronized (this) {
10772                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10773                }
10774            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10775                String[] newArgs;
10776                String name;
10777                if (opti >= args.length) {
10778                    name = null;
10779                    newArgs = EMPTY_STRING_ARRAY;
10780                } else {
10781                    name = args[opti];
10782                    opti++;
10783                    newArgs = new String[args.length - opti];
10784                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10785                            args.length - opti);
10786                }
10787                synchronized (this) {
10788                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10789                }
10790            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10791                String[] newArgs;
10792                String name;
10793                if (opti >= args.length) {
10794                    name = null;
10795                    newArgs = EMPTY_STRING_ARRAY;
10796                } else {
10797                    name = args[opti];
10798                    opti++;
10799                    newArgs = new String[args.length - opti];
10800                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10801                            args.length - opti);
10802                }
10803                synchronized (this) {
10804                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10805                }
10806            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10807                String[] newArgs;
10808                String name;
10809                if (opti >= args.length) {
10810                    name = null;
10811                    newArgs = EMPTY_STRING_ARRAY;
10812                } else {
10813                    name = args[opti];
10814                    opti++;
10815                    newArgs = new String[args.length - opti];
10816                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10817                            args.length - opti);
10818                }
10819                synchronized (this) {
10820                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10821                }
10822            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10823                synchronized (this) {
10824                    dumpOomLocked(fd, pw, args, opti, true);
10825                }
10826            } else if ("provider".equals(cmd)) {
10827                String[] newArgs;
10828                String name;
10829                if (opti >= args.length) {
10830                    name = null;
10831                    newArgs = EMPTY_STRING_ARRAY;
10832                } else {
10833                    name = args[opti];
10834                    opti++;
10835                    newArgs = new String[args.length - opti];
10836                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10837                }
10838                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10839                    pw.println("No providers match: " + name);
10840                    pw.println("Use -h for help.");
10841                }
10842            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10843                synchronized (this) {
10844                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10845                }
10846            } else if ("service".equals(cmd)) {
10847                String[] newArgs;
10848                String name;
10849                if (opti >= args.length) {
10850                    name = null;
10851                    newArgs = EMPTY_STRING_ARRAY;
10852                } else {
10853                    name = args[opti];
10854                    opti++;
10855                    newArgs = new String[args.length - opti];
10856                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10857                            args.length - opti);
10858                }
10859                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10860                    pw.println("No services match: " + name);
10861                    pw.println("Use -h for help.");
10862                }
10863            } else if ("package".equals(cmd)) {
10864                String[] newArgs;
10865                if (opti >= args.length) {
10866                    pw.println("package: no package name specified");
10867                    pw.println("Use -h for help.");
10868                } else {
10869                    dumpPackage = args[opti];
10870                    opti++;
10871                    newArgs = new String[args.length - opti];
10872                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10873                            args.length - opti);
10874                    args = newArgs;
10875                    opti = 0;
10876                    more = true;
10877                }
10878            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10879                synchronized (this) {
10880                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10881                }
10882            } else {
10883                // Dumping a single activity?
10884                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10885                    pw.println("Bad activity command, or no activities match: " + cmd);
10886                    pw.println("Use -h for help.");
10887                }
10888            }
10889            if (!more) {
10890                Binder.restoreCallingIdentity(origId);
10891                return;
10892            }
10893        }
10894
10895        // No piece of data specified, dump everything.
10896        synchronized (this) {
10897            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10898            pw.println();
10899            if (dumpAll) {
10900                pw.println("-------------------------------------------------------------------------------");
10901            }
10902            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10903            pw.println();
10904            if (dumpAll) {
10905                pw.println("-------------------------------------------------------------------------------");
10906            }
10907            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10908            pw.println();
10909            if (dumpAll) {
10910                pw.println("-------------------------------------------------------------------------------");
10911            }
10912            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10913            pw.println();
10914            if (dumpAll) {
10915                pw.println("-------------------------------------------------------------------------------");
10916            }
10917            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10918            pw.println();
10919            if (dumpAll) {
10920                pw.println("-------------------------------------------------------------------------------");
10921            }
10922            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10923        }
10924        Binder.restoreCallingIdentity(origId);
10925    }
10926
10927    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10928            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10929        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10930
10931        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10932                dumpPackage);
10933        boolean needSep = printedAnything;
10934
10935        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10936                dumpPackage, needSep, "  mFocusedActivity: ");
10937        if (printed) {
10938            printedAnything = true;
10939            needSep = false;
10940        }
10941
10942        if (dumpPackage == null) {
10943            if (needSep) {
10944                pw.println();
10945            }
10946            needSep = true;
10947            printedAnything = true;
10948            mStackSupervisor.dump(pw, "  ");
10949        }
10950
10951        if (mRecentTasks.size() > 0) {
10952            boolean printedHeader = false;
10953
10954            final int N = mRecentTasks.size();
10955            for (int i=0; i<N; i++) {
10956                TaskRecord tr = mRecentTasks.get(i);
10957                if (dumpPackage != null) {
10958                    if (tr.realActivity == null ||
10959                            !dumpPackage.equals(tr.realActivity)) {
10960                        continue;
10961                    }
10962                }
10963                if (!printedHeader) {
10964                    if (needSep) {
10965                        pw.println();
10966                    }
10967                    pw.println("  Recent tasks:");
10968                    printedHeader = true;
10969                    printedAnything = true;
10970                }
10971                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10972                        pw.println(tr);
10973                if (dumpAll) {
10974                    mRecentTasks.get(i).dump(pw, "    ");
10975                }
10976            }
10977        }
10978
10979        if (!printedAnything) {
10980            pw.println("  (nothing)");
10981        }
10982    }
10983
10984    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10985            int opti, boolean dumpAll, String dumpPackage) {
10986        boolean needSep = false;
10987        boolean printedAnything = false;
10988        int numPers = 0;
10989
10990        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10991
10992        if (dumpAll) {
10993            final int NP = mProcessNames.getMap().size();
10994            for (int ip=0; ip<NP; ip++) {
10995                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10996                final int NA = procs.size();
10997                for (int ia=0; ia<NA; ia++) {
10998                    ProcessRecord r = procs.valueAt(ia);
10999                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11000                        continue;
11001                    }
11002                    if (!needSep) {
11003                        pw.println("  All known processes:");
11004                        needSep = true;
11005                        printedAnything = true;
11006                    }
11007                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11008                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11009                        pw.print(" "); pw.println(r);
11010                    r.dump(pw, "    ");
11011                    if (r.persistent) {
11012                        numPers++;
11013                    }
11014                }
11015            }
11016        }
11017
11018        if (mIsolatedProcesses.size() > 0) {
11019            boolean printed = false;
11020            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11021                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11022                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11023                    continue;
11024                }
11025                if (!printed) {
11026                    if (needSep) {
11027                        pw.println();
11028                    }
11029                    pw.println("  Isolated process list (sorted by uid):");
11030                    printedAnything = true;
11031                    printed = true;
11032                    needSep = true;
11033                }
11034                pw.println(String.format("%sIsolated #%2d: %s",
11035                        "    ", i, r.toString()));
11036            }
11037        }
11038
11039        if (mLruProcesses.size() > 0) {
11040            if (needSep) {
11041                pw.println();
11042            }
11043            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11044                    pw.print(" total, non-act at ");
11045                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11046                    pw.print(", non-svc at ");
11047                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11048                    pw.println("):");
11049            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11050            needSep = true;
11051            printedAnything = true;
11052        }
11053
11054        if (dumpAll || dumpPackage != null) {
11055            synchronized (mPidsSelfLocked) {
11056                boolean printed = false;
11057                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11058                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11059                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11060                        continue;
11061                    }
11062                    if (!printed) {
11063                        if (needSep) pw.println();
11064                        needSep = true;
11065                        pw.println("  PID mappings:");
11066                        printed = true;
11067                        printedAnything = true;
11068                    }
11069                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11070                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11071                }
11072            }
11073        }
11074
11075        if (mForegroundProcesses.size() > 0) {
11076            synchronized (mPidsSelfLocked) {
11077                boolean printed = false;
11078                for (int i=0; i<mForegroundProcesses.size(); i++) {
11079                    ProcessRecord r = mPidsSelfLocked.get(
11080                            mForegroundProcesses.valueAt(i).pid);
11081                    if (dumpPackage != null && (r == null
11082                            || !r.pkgList.containsKey(dumpPackage))) {
11083                        continue;
11084                    }
11085                    if (!printed) {
11086                        if (needSep) pw.println();
11087                        needSep = true;
11088                        pw.println("  Foreground Processes:");
11089                        printed = true;
11090                        printedAnything = true;
11091                    }
11092                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11093                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11094                }
11095            }
11096        }
11097
11098        if (mPersistentStartingProcesses.size() > 0) {
11099            if (needSep) pw.println();
11100            needSep = true;
11101            printedAnything = true;
11102            pw.println("  Persisent processes that are starting:");
11103            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11104                    "Starting Norm", "Restarting PERS", dumpPackage);
11105        }
11106
11107        if (mRemovedProcesses.size() > 0) {
11108            if (needSep) pw.println();
11109            needSep = true;
11110            printedAnything = true;
11111            pw.println("  Processes that are being removed:");
11112            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11113                    "Removed Norm", "Removed PERS", dumpPackage);
11114        }
11115
11116        if (mProcessesOnHold.size() > 0) {
11117            if (needSep) pw.println();
11118            needSep = true;
11119            printedAnything = true;
11120            pw.println("  Processes that are on old until the system is ready:");
11121            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11122                    "OnHold Norm", "OnHold PERS", dumpPackage);
11123        }
11124
11125        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11126
11127        if (mProcessCrashTimes.getMap().size() > 0) {
11128            boolean printed = false;
11129            long now = SystemClock.uptimeMillis();
11130            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11131            final int NP = pmap.size();
11132            for (int ip=0; ip<NP; ip++) {
11133                String pname = pmap.keyAt(ip);
11134                SparseArray<Long> uids = pmap.valueAt(ip);
11135                final int N = uids.size();
11136                for (int i=0; i<N; i++) {
11137                    int puid = uids.keyAt(i);
11138                    ProcessRecord r = mProcessNames.get(pname, puid);
11139                    if (dumpPackage != null && (r == null
11140                            || !r.pkgList.containsKey(dumpPackage))) {
11141                        continue;
11142                    }
11143                    if (!printed) {
11144                        if (needSep) pw.println();
11145                        needSep = true;
11146                        pw.println("  Time since processes crashed:");
11147                        printed = true;
11148                        printedAnything = true;
11149                    }
11150                    pw.print("    Process "); pw.print(pname);
11151                            pw.print(" uid "); pw.print(puid);
11152                            pw.print(": last crashed ");
11153                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11154                            pw.println(" ago");
11155                }
11156            }
11157        }
11158
11159        if (mBadProcesses.getMap().size() > 0) {
11160            boolean printed = false;
11161            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11162            final int NP = pmap.size();
11163            for (int ip=0; ip<NP; ip++) {
11164                String pname = pmap.keyAt(ip);
11165                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11166                final int N = uids.size();
11167                for (int i=0; i<N; i++) {
11168                    int puid = uids.keyAt(i);
11169                    ProcessRecord r = mProcessNames.get(pname, puid);
11170                    if (dumpPackage != null && (r == null
11171                            || !r.pkgList.containsKey(dumpPackage))) {
11172                        continue;
11173                    }
11174                    if (!printed) {
11175                        if (needSep) pw.println();
11176                        needSep = true;
11177                        pw.println("  Bad processes:");
11178                        printedAnything = true;
11179                    }
11180                    BadProcessInfo info = uids.valueAt(i);
11181                    pw.print("    Bad process "); pw.print(pname);
11182                            pw.print(" uid "); pw.print(puid);
11183                            pw.print(": crashed at time "); pw.println(info.time);
11184                    if (info.shortMsg != null) {
11185                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11186                    }
11187                    if (info.longMsg != null) {
11188                        pw.print("      Long msg: "); pw.println(info.longMsg);
11189                    }
11190                    if (info.stack != null) {
11191                        pw.println("      Stack:");
11192                        int lastPos = 0;
11193                        for (int pos=0; pos<info.stack.length(); pos++) {
11194                            if (info.stack.charAt(pos) == '\n') {
11195                                pw.print("        ");
11196                                pw.write(info.stack, lastPos, pos-lastPos);
11197                                pw.println();
11198                                lastPos = pos+1;
11199                            }
11200                        }
11201                        if (lastPos < info.stack.length()) {
11202                            pw.print("        ");
11203                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11204                            pw.println();
11205                        }
11206                    }
11207                }
11208            }
11209        }
11210
11211        if (dumpPackage == null) {
11212            pw.println();
11213            needSep = false;
11214            pw.println("  mStartedUsers:");
11215            for (int i=0; i<mStartedUsers.size(); i++) {
11216                UserStartedState uss = mStartedUsers.valueAt(i);
11217                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11218                        pw.print(": "); uss.dump("", pw);
11219            }
11220            pw.print("  mStartedUserArray: [");
11221            for (int i=0; i<mStartedUserArray.length; i++) {
11222                if (i > 0) pw.print(", ");
11223                pw.print(mStartedUserArray[i]);
11224            }
11225            pw.println("]");
11226            pw.print("  mUserLru: [");
11227            for (int i=0; i<mUserLru.size(); i++) {
11228                if (i > 0) pw.print(", ");
11229                pw.print(mUserLru.get(i));
11230            }
11231            pw.println("]");
11232            if (dumpAll) {
11233                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11234            }
11235        }
11236        if (mHomeProcess != null && (dumpPackage == null
11237                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11238            if (needSep) {
11239                pw.println();
11240                needSep = false;
11241            }
11242            pw.println("  mHomeProcess: " + mHomeProcess);
11243        }
11244        if (mPreviousProcess != null && (dumpPackage == null
11245                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11246            if (needSep) {
11247                pw.println();
11248                needSep = false;
11249            }
11250            pw.println("  mPreviousProcess: " + mPreviousProcess);
11251        }
11252        if (dumpAll) {
11253            StringBuilder sb = new StringBuilder(128);
11254            sb.append("  mPreviousProcessVisibleTime: ");
11255            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11256            pw.println(sb);
11257        }
11258        if (mHeavyWeightProcess != null && (dumpPackage == null
11259                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11260            if (needSep) {
11261                pw.println();
11262                needSep = false;
11263            }
11264            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11265        }
11266        if (dumpPackage == null) {
11267            pw.println("  mConfiguration: " + mConfiguration);
11268        }
11269        if (dumpAll) {
11270            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11271            if (mCompatModePackages.getPackages().size() > 0) {
11272                boolean printed = false;
11273                for (Map.Entry<String, Integer> entry
11274                        : mCompatModePackages.getPackages().entrySet()) {
11275                    String pkg = entry.getKey();
11276                    int mode = entry.getValue();
11277                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11278                        continue;
11279                    }
11280                    if (!printed) {
11281                        pw.println("  mScreenCompatPackages:");
11282                        printed = true;
11283                    }
11284                    pw.print("    "); pw.print(pkg); pw.print(": ");
11285                            pw.print(mode); pw.println();
11286                }
11287            }
11288        }
11289        if (dumpPackage == null) {
11290            if (mSleeping || mWentToSleep || mLockScreenShown) {
11291                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11292                        + " mLockScreenShown " + mLockScreenShown);
11293            }
11294            if (mShuttingDown || mRunningVoice) {
11295                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11296            }
11297        }
11298        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11299                || mOrigWaitForDebugger) {
11300            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11301                    || dumpPackage.equals(mOrigDebugApp)) {
11302                if (needSep) {
11303                    pw.println();
11304                    needSep = false;
11305                }
11306                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11307                        + " mDebugTransient=" + mDebugTransient
11308                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11309            }
11310        }
11311        if (mOpenGlTraceApp != null) {
11312            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11313                if (needSep) {
11314                    pw.println();
11315                    needSep = false;
11316                }
11317                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11318            }
11319        }
11320        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11321                || mProfileFd != null) {
11322            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11323                if (needSep) {
11324                    pw.println();
11325                    needSep = false;
11326                }
11327                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11328                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11329                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11330                        + mAutoStopProfiler);
11331            }
11332        }
11333        if (dumpPackage == null) {
11334            if (mAlwaysFinishActivities || mController != null) {
11335                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11336                        + " mController=" + mController);
11337            }
11338            if (dumpAll) {
11339                pw.println("  Total persistent processes: " + numPers);
11340                pw.println("  mProcessesReady=" + mProcessesReady
11341                        + " mSystemReady=" + mSystemReady);
11342                pw.println("  mBooting=" + mBooting
11343                        + " mBooted=" + mBooted
11344                        + " mFactoryTest=" + mFactoryTest);
11345                pw.print("  mLastPowerCheckRealtime=");
11346                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11347                        pw.println("");
11348                pw.print("  mLastPowerCheckUptime=");
11349                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11350                        pw.println("");
11351                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11352                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11353                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11354                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11355                        + " (" + mLruProcesses.size() + " total)"
11356                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11357                        + " mNumServiceProcs=" + mNumServiceProcs
11358                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11359                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11360                        + " mLastMemoryLevel" + mLastMemoryLevel
11361                        + " mLastNumProcesses" + mLastNumProcesses);
11362                long now = SystemClock.uptimeMillis();
11363                pw.print("  mLastIdleTime=");
11364                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11365                        pw.print(" mLowRamSinceLastIdle=");
11366                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11367                        pw.println();
11368            }
11369        }
11370
11371        if (!printedAnything) {
11372            pw.println("  (nothing)");
11373        }
11374    }
11375
11376    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11377            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11378        if (mProcessesToGc.size() > 0) {
11379            boolean printed = false;
11380            long now = SystemClock.uptimeMillis();
11381            for (int i=0; i<mProcessesToGc.size(); i++) {
11382                ProcessRecord proc = mProcessesToGc.get(i);
11383                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11384                    continue;
11385                }
11386                if (!printed) {
11387                    if (needSep) pw.println();
11388                    needSep = true;
11389                    pw.println("  Processes that are waiting to GC:");
11390                    printed = true;
11391                }
11392                pw.print("    Process "); pw.println(proc);
11393                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11394                        pw.print(", last gced=");
11395                        pw.print(now-proc.lastRequestedGc);
11396                        pw.print(" ms ago, last lowMem=");
11397                        pw.print(now-proc.lastLowMemory);
11398                        pw.println(" ms ago");
11399
11400            }
11401        }
11402        return needSep;
11403    }
11404
11405    void printOomLevel(PrintWriter pw, String name, int adj) {
11406        pw.print("    ");
11407        if (adj >= 0) {
11408            pw.print(' ');
11409            if (adj < 10) pw.print(' ');
11410        } else {
11411            if (adj > -10) pw.print(' ');
11412        }
11413        pw.print(adj);
11414        pw.print(": ");
11415        pw.print(name);
11416        pw.print(" (");
11417        pw.print(mProcessList.getMemLevel(adj)/1024);
11418        pw.println(" kB)");
11419    }
11420
11421    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11422            int opti, boolean dumpAll) {
11423        boolean needSep = false;
11424
11425        if (mLruProcesses.size() > 0) {
11426            if (needSep) pw.println();
11427            needSep = true;
11428            pw.println("  OOM levels:");
11429            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11430            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11431            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11432            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11433            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11434            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11435            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11436            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11437            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11438            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11439            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11440            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11441            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11442
11443            if (needSep) pw.println();
11444            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11445                    pw.print(" total, non-act at ");
11446                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11447                    pw.print(", non-svc at ");
11448                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11449                    pw.println("):");
11450            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11451            needSep = true;
11452        }
11453
11454        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11455
11456        pw.println();
11457        pw.println("  mHomeProcess: " + mHomeProcess);
11458        pw.println("  mPreviousProcess: " + mPreviousProcess);
11459        if (mHeavyWeightProcess != null) {
11460            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11461        }
11462
11463        return true;
11464    }
11465
11466    /**
11467     * There are three ways to call this:
11468     *  - no provider specified: dump all the providers
11469     *  - a flattened component name that matched an existing provider was specified as the
11470     *    first arg: dump that one provider
11471     *  - the first arg isn't the flattened component name of an existing provider:
11472     *    dump all providers whose component contains the first arg as a substring
11473     */
11474    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11475            int opti, boolean dumpAll) {
11476        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11477    }
11478
11479    static class ItemMatcher {
11480        ArrayList<ComponentName> components;
11481        ArrayList<String> strings;
11482        ArrayList<Integer> objects;
11483        boolean all;
11484
11485        ItemMatcher() {
11486            all = true;
11487        }
11488
11489        void build(String name) {
11490            ComponentName componentName = ComponentName.unflattenFromString(name);
11491            if (componentName != null) {
11492                if (components == null) {
11493                    components = new ArrayList<ComponentName>();
11494                }
11495                components.add(componentName);
11496                all = false;
11497            } else {
11498                int objectId = 0;
11499                // Not a '/' separated full component name; maybe an object ID?
11500                try {
11501                    objectId = Integer.parseInt(name, 16);
11502                    if (objects == null) {
11503                        objects = new ArrayList<Integer>();
11504                    }
11505                    objects.add(objectId);
11506                    all = false;
11507                } catch (RuntimeException e) {
11508                    // Not an integer; just do string match.
11509                    if (strings == null) {
11510                        strings = new ArrayList<String>();
11511                    }
11512                    strings.add(name);
11513                    all = false;
11514                }
11515            }
11516        }
11517
11518        int build(String[] args, int opti) {
11519            for (; opti<args.length; opti++) {
11520                String name = args[opti];
11521                if ("--".equals(name)) {
11522                    return opti+1;
11523                }
11524                build(name);
11525            }
11526            return opti;
11527        }
11528
11529        boolean match(Object object, ComponentName comp) {
11530            if (all) {
11531                return true;
11532            }
11533            if (components != null) {
11534                for (int i=0; i<components.size(); i++) {
11535                    if (components.get(i).equals(comp)) {
11536                        return true;
11537                    }
11538                }
11539            }
11540            if (objects != null) {
11541                for (int i=0; i<objects.size(); i++) {
11542                    if (System.identityHashCode(object) == objects.get(i)) {
11543                        return true;
11544                    }
11545                }
11546            }
11547            if (strings != null) {
11548                String flat = comp.flattenToString();
11549                for (int i=0; i<strings.size(); i++) {
11550                    if (flat.contains(strings.get(i))) {
11551                        return true;
11552                    }
11553                }
11554            }
11555            return false;
11556        }
11557    }
11558
11559    /**
11560     * There are three things that cmd can be:
11561     *  - a flattened component name that matches an existing activity
11562     *  - the cmd arg isn't the flattened component name of an existing activity:
11563     *    dump all activity whose component contains the cmd as a substring
11564     *  - A hex number of the ActivityRecord object instance.
11565     */
11566    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11567            int opti, boolean dumpAll) {
11568        ArrayList<ActivityRecord> activities;
11569
11570        synchronized (this) {
11571            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11572        }
11573
11574        if (activities.size() <= 0) {
11575            return false;
11576        }
11577
11578        String[] newArgs = new String[args.length - opti];
11579        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11580
11581        TaskRecord lastTask = null;
11582        boolean needSep = false;
11583        for (int i=activities.size()-1; i>=0; i--) {
11584            ActivityRecord r = activities.get(i);
11585            if (needSep) {
11586                pw.println();
11587            }
11588            needSep = true;
11589            synchronized (this) {
11590                if (lastTask != r.task) {
11591                    lastTask = r.task;
11592                    pw.print("TASK "); pw.print(lastTask.affinity);
11593                            pw.print(" id="); pw.println(lastTask.taskId);
11594                    if (dumpAll) {
11595                        lastTask.dump(pw, "  ");
11596                    }
11597                }
11598            }
11599            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11600        }
11601        return true;
11602    }
11603
11604    /**
11605     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11606     * there is a thread associated with the activity.
11607     */
11608    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11609            final ActivityRecord r, String[] args, boolean dumpAll) {
11610        String innerPrefix = prefix + "  ";
11611        synchronized (this) {
11612            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11613                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11614                    pw.print(" pid=");
11615                    if (r.app != null) pw.println(r.app.pid);
11616                    else pw.println("(not running)");
11617            if (dumpAll) {
11618                r.dump(pw, innerPrefix);
11619            }
11620        }
11621        if (r.app != null && r.app.thread != null) {
11622            // flush anything that is already in the PrintWriter since the thread is going
11623            // to write to the file descriptor directly
11624            pw.flush();
11625            try {
11626                TransferPipe tp = new TransferPipe();
11627                try {
11628                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11629                            r.appToken, innerPrefix, args);
11630                    tp.go(fd);
11631                } finally {
11632                    tp.kill();
11633                }
11634            } catch (IOException e) {
11635                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11636            } catch (RemoteException e) {
11637                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11638            }
11639        }
11640    }
11641
11642    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11643            int opti, boolean dumpAll, String dumpPackage) {
11644        boolean needSep = false;
11645        boolean onlyHistory = false;
11646        boolean printedAnything = false;
11647
11648        if ("history".equals(dumpPackage)) {
11649            if (opti < args.length && "-s".equals(args[opti])) {
11650                dumpAll = false;
11651            }
11652            onlyHistory = true;
11653            dumpPackage = null;
11654        }
11655
11656        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11657        if (!onlyHistory && dumpAll) {
11658            if (mRegisteredReceivers.size() > 0) {
11659                boolean printed = false;
11660                Iterator it = mRegisteredReceivers.values().iterator();
11661                while (it.hasNext()) {
11662                    ReceiverList r = (ReceiverList)it.next();
11663                    if (dumpPackage != null && (r.app == null ||
11664                            !dumpPackage.equals(r.app.info.packageName))) {
11665                        continue;
11666                    }
11667                    if (!printed) {
11668                        pw.println("  Registered Receivers:");
11669                        needSep = true;
11670                        printed = true;
11671                        printedAnything = true;
11672                    }
11673                    pw.print("  * "); pw.println(r);
11674                    r.dump(pw, "    ");
11675                }
11676            }
11677
11678            if (mReceiverResolver.dump(pw, needSep ?
11679                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11680                    "    ", dumpPackage, false)) {
11681                needSep = true;
11682                printedAnything = true;
11683            }
11684        }
11685
11686        for (BroadcastQueue q : mBroadcastQueues) {
11687            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11688            printedAnything |= needSep;
11689        }
11690
11691        needSep = true;
11692
11693        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11694            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11695                if (needSep) {
11696                    pw.println();
11697                }
11698                needSep = true;
11699                printedAnything = true;
11700                pw.print("  Sticky broadcasts for user ");
11701                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11702                StringBuilder sb = new StringBuilder(128);
11703                for (Map.Entry<String, ArrayList<Intent>> ent
11704                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11705                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11706                    if (dumpAll) {
11707                        pw.println(":");
11708                        ArrayList<Intent> intents = ent.getValue();
11709                        final int N = intents.size();
11710                        for (int i=0; i<N; i++) {
11711                            sb.setLength(0);
11712                            sb.append("    Intent: ");
11713                            intents.get(i).toShortString(sb, false, true, false, false);
11714                            pw.println(sb.toString());
11715                            Bundle bundle = intents.get(i).getExtras();
11716                            if (bundle != null) {
11717                                pw.print("      ");
11718                                pw.println(bundle.toString());
11719                            }
11720                        }
11721                    } else {
11722                        pw.println("");
11723                    }
11724                }
11725            }
11726        }
11727
11728        if (!onlyHistory && dumpAll) {
11729            pw.println();
11730            for (BroadcastQueue queue : mBroadcastQueues) {
11731                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11732                        + queue.mBroadcastsScheduled);
11733            }
11734            pw.println("  mHandler:");
11735            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11736            needSep = true;
11737            printedAnything = true;
11738        }
11739
11740        if (!printedAnything) {
11741            pw.println("  (nothing)");
11742        }
11743    }
11744
11745    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11746            int opti, boolean dumpAll, String dumpPackage) {
11747        boolean needSep;
11748        boolean printedAnything = false;
11749
11750        ItemMatcher matcher = new ItemMatcher();
11751        matcher.build(args, opti);
11752
11753        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11754
11755        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11756        printedAnything |= needSep;
11757
11758        if (mLaunchingProviders.size() > 0) {
11759            boolean printed = false;
11760            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11761                ContentProviderRecord r = mLaunchingProviders.get(i);
11762                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11763                    continue;
11764                }
11765                if (!printed) {
11766                    if (needSep) pw.println();
11767                    needSep = true;
11768                    pw.println("  Launching content providers:");
11769                    printed = true;
11770                    printedAnything = true;
11771                }
11772                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11773                        pw.println(r);
11774            }
11775        }
11776
11777        if (mGrantedUriPermissions.size() > 0) {
11778            boolean printed = false;
11779            int dumpUid = -2;
11780            if (dumpPackage != null) {
11781                try {
11782                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11783                } catch (NameNotFoundException e) {
11784                    dumpUid = -1;
11785                }
11786            }
11787            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11788                int uid = mGrantedUriPermissions.keyAt(i);
11789                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11790                    continue;
11791                }
11792                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11793                if (!printed) {
11794                    if (needSep) pw.println();
11795                    needSep = true;
11796                    pw.println("  Granted Uri Permissions:");
11797                    printed = true;
11798                    printedAnything = true;
11799                }
11800                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11801                for (UriPermission perm : perms.values()) {
11802                    pw.print("    "); pw.println(perm);
11803                    if (dumpAll) {
11804                        perm.dump(pw, "      ");
11805                    }
11806                }
11807            }
11808        }
11809
11810        if (!printedAnything) {
11811            pw.println("  (nothing)");
11812        }
11813    }
11814
11815    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11816            int opti, boolean dumpAll, String dumpPackage) {
11817        boolean printed = false;
11818
11819        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11820
11821        if (mIntentSenderRecords.size() > 0) {
11822            Iterator<WeakReference<PendingIntentRecord>> it
11823                    = mIntentSenderRecords.values().iterator();
11824            while (it.hasNext()) {
11825                WeakReference<PendingIntentRecord> ref = it.next();
11826                PendingIntentRecord rec = ref != null ? ref.get(): null;
11827                if (dumpPackage != null && (rec == null
11828                        || !dumpPackage.equals(rec.key.packageName))) {
11829                    continue;
11830                }
11831                printed = true;
11832                if (rec != null) {
11833                    pw.print("  * "); pw.println(rec);
11834                    if (dumpAll) {
11835                        rec.dump(pw, "    ");
11836                    }
11837                } else {
11838                    pw.print("  * "); pw.println(ref);
11839                }
11840            }
11841        }
11842
11843        if (!printed) {
11844            pw.println("  (nothing)");
11845        }
11846    }
11847
11848    private static final int dumpProcessList(PrintWriter pw,
11849            ActivityManagerService service, List list,
11850            String prefix, String normalLabel, String persistentLabel,
11851            String dumpPackage) {
11852        int numPers = 0;
11853        final int N = list.size()-1;
11854        for (int i=N; i>=0; i--) {
11855            ProcessRecord r = (ProcessRecord)list.get(i);
11856            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11857                continue;
11858            }
11859            pw.println(String.format("%s%s #%2d: %s",
11860                    prefix, (r.persistent ? persistentLabel : normalLabel),
11861                    i, r.toString()));
11862            if (r.persistent) {
11863                numPers++;
11864            }
11865        }
11866        return numPers;
11867    }
11868
11869    private static final boolean dumpProcessOomList(PrintWriter pw,
11870            ActivityManagerService service, List<ProcessRecord> origList,
11871            String prefix, String normalLabel, String persistentLabel,
11872            boolean inclDetails, String dumpPackage) {
11873
11874        ArrayList<Pair<ProcessRecord, Integer>> list
11875                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11876        for (int i=0; i<origList.size(); i++) {
11877            ProcessRecord r = origList.get(i);
11878            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11879                continue;
11880            }
11881            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11882        }
11883
11884        if (list.size() <= 0) {
11885            return false;
11886        }
11887
11888        Comparator<Pair<ProcessRecord, Integer>> comparator
11889                = new Comparator<Pair<ProcessRecord, Integer>>() {
11890            @Override
11891            public int compare(Pair<ProcessRecord, Integer> object1,
11892                    Pair<ProcessRecord, Integer> object2) {
11893                if (object1.first.setAdj != object2.first.setAdj) {
11894                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11895                }
11896                if (object1.second.intValue() != object2.second.intValue()) {
11897                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11898                }
11899                return 0;
11900            }
11901        };
11902
11903        Collections.sort(list, comparator);
11904
11905        final long curRealtime = SystemClock.elapsedRealtime();
11906        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11907        final long curUptime = SystemClock.uptimeMillis();
11908        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11909
11910        for (int i=list.size()-1; i>=0; i--) {
11911            ProcessRecord r = list.get(i).first;
11912            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11913            char schedGroup;
11914            switch (r.setSchedGroup) {
11915                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11916                    schedGroup = 'B';
11917                    break;
11918                case Process.THREAD_GROUP_DEFAULT:
11919                    schedGroup = 'F';
11920                    break;
11921                default:
11922                    schedGroup = '?';
11923                    break;
11924            }
11925            char foreground;
11926            if (r.foregroundActivities) {
11927                foreground = 'A';
11928            } else if (r.foregroundServices) {
11929                foreground = 'S';
11930            } else {
11931                foreground = ' ';
11932            }
11933            String procState = ProcessList.makeProcStateString(r.curProcState);
11934            pw.print(prefix);
11935            pw.print(r.persistent ? persistentLabel : normalLabel);
11936            pw.print(" #");
11937            int num = (origList.size()-1)-list.get(i).second;
11938            if (num < 10) pw.print(' ');
11939            pw.print(num);
11940            pw.print(": ");
11941            pw.print(oomAdj);
11942            pw.print(' ');
11943            pw.print(schedGroup);
11944            pw.print('/');
11945            pw.print(foreground);
11946            pw.print('/');
11947            pw.print(procState);
11948            pw.print(" trm:");
11949            if (r.trimMemoryLevel < 10) pw.print(' ');
11950            pw.print(r.trimMemoryLevel);
11951            pw.print(' ');
11952            pw.print(r.toShortString());
11953            pw.print(" (");
11954            pw.print(r.adjType);
11955            pw.println(')');
11956            if (r.adjSource != null || r.adjTarget != null) {
11957                pw.print(prefix);
11958                pw.print("    ");
11959                if (r.adjTarget instanceof ComponentName) {
11960                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11961                } else if (r.adjTarget != null) {
11962                    pw.print(r.adjTarget.toString());
11963                } else {
11964                    pw.print("{null}");
11965                }
11966                pw.print("<=");
11967                if (r.adjSource instanceof ProcessRecord) {
11968                    pw.print("Proc{");
11969                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11970                    pw.println("}");
11971                } else if (r.adjSource != null) {
11972                    pw.println(r.adjSource.toString());
11973                } else {
11974                    pw.println("{null}");
11975                }
11976            }
11977            if (inclDetails) {
11978                pw.print(prefix);
11979                pw.print("    ");
11980                pw.print("oom: max="); pw.print(r.maxAdj);
11981                pw.print(" curRaw="); pw.print(r.curRawAdj);
11982                pw.print(" setRaw="); pw.print(r.setRawAdj);
11983                pw.print(" cur="); pw.print(r.curAdj);
11984                pw.print(" set="); pw.println(r.setAdj);
11985                pw.print(prefix);
11986                pw.print("    ");
11987                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11988                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11989                pw.print(" lastPss="); pw.print(r.lastPss);
11990                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11991                pw.print(prefix);
11992                pw.print("    ");
11993                pw.print("keeping="); pw.print(r.keeping);
11994                pw.print(" cached="); pw.print(r.cached);
11995                pw.print(" empty="); pw.print(r.empty);
11996                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11997
11998                if (!r.keeping) {
11999                    if (r.lastWakeTime != 0) {
12000                        long wtime;
12001                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12002                        synchronized (stats) {
12003                            wtime = stats.getProcessWakeTime(r.info.uid,
12004                                    r.pid, curRealtime);
12005                        }
12006                        long timeUsed = wtime - r.lastWakeTime;
12007                        pw.print(prefix);
12008                        pw.print("    ");
12009                        pw.print("keep awake over ");
12010                        TimeUtils.formatDuration(realtimeSince, pw);
12011                        pw.print(" used ");
12012                        TimeUtils.formatDuration(timeUsed, pw);
12013                        pw.print(" (");
12014                        pw.print((timeUsed*100)/realtimeSince);
12015                        pw.println("%)");
12016                    }
12017                    if (r.lastCpuTime != 0) {
12018                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12019                        pw.print(prefix);
12020                        pw.print("    ");
12021                        pw.print("run cpu over ");
12022                        TimeUtils.formatDuration(uptimeSince, pw);
12023                        pw.print(" used ");
12024                        TimeUtils.formatDuration(timeUsed, pw);
12025                        pw.print(" (");
12026                        pw.print((timeUsed*100)/uptimeSince);
12027                        pw.println("%)");
12028                    }
12029                }
12030            }
12031        }
12032        return true;
12033    }
12034
12035    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12036        ArrayList<ProcessRecord> procs;
12037        synchronized (this) {
12038            if (args != null && args.length > start
12039                    && args[start].charAt(0) != '-') {
12040                procs = new ArrayList<ProcessRecord>();
12041                int pid = -1;
12042                try {
12043                    pid = Integer.parseInt(args[start]);
12044                } catch (NumberFormatException e) {
12045                }
12046                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12047                    ProcessRecord proc = mLruProcesses.get(i);
12048                    if (proc.pid == pid) {
12049                        procs.add(proc);
12050                    } else if (proc.processName.equals(args[start])) {
12051                        procs.add(proc);
12052                    }
12053                }
12054                if (procs.size() <= 0) {
12055                    return null;
12056                }
12057            } else {
12058                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12059            }
12060        }
12061        return procs;
12062    }
12063
12064    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12065            PrintWriter pw, String[] args) {
12066        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12067        if (procs == null) {
12068            pw.println("No process found for: " + args[0]);
12069            return;
12070        }
12071
12072        long uptime = SystemClock.uptimeMillis();
12073        long realtime = SystemClock.elapsedRealtime();
12074        pw.println("Applications Graphics Acceleration Info:");
12075        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12076
12077        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12078            ProcessRecord r = procs.get(i);
12079            if (r.thread != null) {
12080                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12081                pw.flush();
12082                try {
12083                    TransferPipe tp = new TransferPipe();
12084                    try {
12085                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12086                        tp.go(fd);
12087                    } finally {
12088                        tp.kill();
12089                    }
12090                } catch (IOException e) {
12091                    pw.println("Failure while dumping the app: " + r);
12092                    pw.flush();
12093                } catch (RemoteException e) {
12094                    pw.println("Got a RemoteException while dumping the app " + r);
12095                    pw.flush();
12096                }
12097            }
12098        }
12099    }
12100
12101    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12102        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12103        if (procs == null) {
12104            pw.println("No process found for: " + args[0]);
12105            return;
12106        }
12107
12108        pw.println("Applications Database Info:");
12109
12110        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12111            ProcessRecord r = procs.get(i);
12112            if (r.thread != null) {
12113                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12114                pw.flush();
12115                try {
12116                    TransferPipe tp = new TransferPipe();
12117                    try {
12118                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12119                        tp.go(fd);
12120                    } finally {
12121                        tp.kill();
12122                    }
12123                } catch (IOException e) {
12124                    pw.println("Failure while dumping the app: " + r);
12125                    pw.flush();
12126                } catch (RemoteException e) {
12127                    pw.println("Got a RemoteException while dumping the app " + r);
12128                    pw.flush();
12129                }
12130            }
12131        }
12132    }
12133
12134    final static class MemItem {
12135        final boolean isProc;
12136        final String label;
12137        final String shortLabel;
12138        final long pss;
12139        final int id;
12140        final boolean hasActivities;
12141        ArrayList<MemItem> subitems;
12142
12143        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12144                boolean _hasActivities) {
12145            isProc = true;
12146            label = _label;
12147            shortLabel = _shortLabel;
12148            pss = _pss;
12149            id = _id;
12150            hasActivities = _hasActivities;
12151        }
12152
12153        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12154            isProc = false;
12155            label = _label;
12156            shortLabel = _shortLabel;
12157            pss = _pss;
12158            id = _id;
12159            hasActivities = false;
12160        }
12161    }
12162
12163    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12164            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12165        if (sort && !isCompact) {
12166            Collections.sort(items, new Comparator<MemItem>() {
12167                @Override
12168                public int compare(MemItem lhs, MemItem rhs) {
12169                    if (lhs.pss < rhs.pss) {
12170                        return 1;
12171                    } else if (lhs.pss > rhs.pss) {
12172                        return -1;
12173                    }
12174                    return 0;
12175                }
12176            });
12177        }
12178
12179        for (int i=0; i<items.size(); i++) {
12180            MemItem mi = items.get(i);
12181            if (!isCompact) {
12182                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12183            } else if (mi.isProc) {
12184                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12185                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12186                pw.println(mi.hasActivities ? ",a" : ",e");
12187            } else {
12188                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12189                pw.println(mi.pss);
12190            }
12191            if (mi.subitems != null) {
12192                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12193                        true, isCompact);
12194            }
12195        }
12196    }
12197
12198    // These are in KB.
12199    static final long[] DUMP_MEM_BUCKETS = new long[] {
12200        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12201        120*1024, 160*1024, 200*1024,
12202        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12203        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12204    };
12205
12206    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12207            boolean stackLike) {
12208        int start = label.lastIndexOf('.');
12209        if (start >= 0) start++;
12210        else start = 0;
12211        int end = label.length();
12212        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12213            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12214                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12215                out.append(bucket);
12216                out.append(stackLike ? "MB." : "MB ");
12217                out.append(label, start, end);
12218                return;
12219            }
12220        }
12221        out.append(memKB/1024);
12222        out.append(stackLike ? "MB." : "MB ");
12223        out.append(label, start, end);
12224    }
12225
12226    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12227            ProcessList.NATIVE_ADJ,
12228            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12229            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12230            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12231            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12232            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12233    };
12234    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12235            "Native",
12236            "System", "Persistent", "Foreground",
12237            "Visible", "Perceptible",
12238            "Heavy Weight", "Backup",
12239            "A Services", "Home",
12240            "Previous", "B Services", "Cached"
12241    };
12242    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12243            "native",
12244            "sys", "pers", "fore",
12245            "vis", "percept",
12246            "heavy", "backup",
12247            "servicea", "home",
12248            "prev", "serviceb", "cached"
12249    };
12250
12251    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12252            long realtime, boolean isCheckinRequest, boolean isCompact) {
12253        if (isCheckinRequest || isCompact) {
12254            // short checkin version
12255            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12256        } else {
12257            pw.println("Applications Memory Usage (kB):");
12258            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12259        }
12260    }
12261
12262    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12263            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12264        boolean dumpDetails = false;
12265        boolean dumpFullDetails = false;
12266        boolean dumpDalvik = false;
12267        boolean oomOnly = false;
12268        boolean isCompact = false;
12269        boolean localOnly = false;
12270
12271        int opti = 0;
12272        while (opti < args.length) {
12273            String opt = args[opti];
12274            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12275                break;
12276            }
12277            opti++;
12278            if ("-a".equals(opt)) {
12279                dumpDetails = true;
12280                dumpFullDetails = true;
12281                dumpDalvik = true;
12282            } else if ("-d".equals(opt)) {
12283                dumpDalvik = true;
12284            } else if ("-c".equals(opt)) {
12285                isCompact = true;
12286            } else if ("--oom".equals(opt)) {
12287                oomOnly = true;
12288            } else if ("--local".equals(opt)) {
12289                localOnly = true;
12290            } else if ("-h".equals(opt)) {
12291                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12292                pw.println("  -a: include all available information for each process.");
12293                pw.println("  -d: include dalvik details when dumping process details.");
12294                pw.println("  -c: dump in a compact machine-parseable representation.");
12295                pw.println("  --oom: only show processes organized by oom adj.");
12296                pw.println("  --local: only collect details locally, don't call process.");
12297                pw.println("If [process] is specified it can be the name or ");
12298                pw.println("pid of a specific process to dump.");
12299                return;
12300            } else {
12301                pw.println("Unknown argument: " + opt + "; use -h for help");
12302            }
12303        }
12304
12305        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12306        long uptime = SystemClock.uptimeMillis();
12307        long realtime = SystemClock.elapsedRealtime();
12308        final long[] tmpLong = new long[1];
12309
12310        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12311        if (procs == null) {
12312            // No Java processes.  Maybe they want to print a native process.
12313            if (args != null && args.length > opti
12314                    && args[opti].charAt(0) != '-') {
12315                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12316                        = new ArrayList<ProcessCpuTracker.Stats>();
12317                updateCpuStatsNow();
12318                int findPid = -1;
12319                try {
12320                    findPid = Integer.parseInt(args[opti]);
12321                } catch (NumberFormatException e) {
12322                }
12323                synchronized (mProcessCpuThread) {
12324                    final int N = mProcessCpuTracker.countStats();
12325                    for (int i=0; i<N; i++) {
12326                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12327                        if (st.pid == findPid || (st.baseName != null
12328                                && st.baseName.equals(args[opti]))) {
12329                            nativeProcs.add(st);
12330                        }
12331                    }
12332                }
12333                if (nativeProcs.size() > 0) {
12334                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12335                            isCompact);
12336                    Debug.MemoryInfo mi = null;
12337                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12338                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12339                        final int pid = r.pid;
12340                        if (!isCheckinRequest && dumpDetails) {
12341                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12342                        }
12343                        if (mi == null) {
12344                            mi = new Debug.MemoryInfo();
12345                        }
12346                        if (dumpDetails || (!brief && !oomOnly)) {
12347                            Debug.getMemoryInfo(pid, mi);
12348                        } else {
12349                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12350                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12351                        }
12352                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12353                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12354                        if (isCheckinRequest) {
12355                            pw.println();
12356                        }
12357                    }
12358                    return;
12359                }
12360            }
12361            pw.println("No process found for: " + args[opti]);
12362            return;
12363        }
12364
12365        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12366            dumpDetails = true;
12367        }
12368
12369        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12370
12371        String[] innerArgs = new String[args.length-opti];
12372        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12373
12374        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12375        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12376        long nativePss=0, dalvikPss=0, otherPss=0;
12377        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12378
12379        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12380        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12381                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12382
12383        long totalPss = 0;
12384        long cachedPss = 0;
12385
12386        Debug.MemoryInfo mi = null;
12387        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12388            final ProcessRecord r = procs.get(i);
12389            final IApplicationThread thread;
12390            final int pid;
12391            final int oomAdj;
12392            final boolean hasActivities;
12393            synchronized (this) {
12394                thread = r.thread;
12395                pid = r.pid;
12396                oomAdj = r.getSetAdjWithServices();
12397                hasActivities = r.activities.size() > 0;
12398            }
12399            if (thread != null) {
12400                if (!isCheckinRequest && dumpDetails) {
12401                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12402                }
12403                if (mi == null) {
12404                    mi = new Debug.MemoryInfo();
12405                }
12406                if (dumpDetails || (!brief && !oomOnly)) {
12407                    Debug.getMemoryInfo(pid, mi);
12408                } else {
12409                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12410                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12411                }
12412                if (dumpDetails) {
12413                    if (localOnly) {
12414                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12415                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12416                        if (isCheckinRequest) {
12417                            pw.println();
12418                        }
12419                    } else {
12420                        try {
12421                            pw.flush();
12422                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12423                                    dumpDalvik, innerArgs);
12424                        } catch (RemoteException e) {
12425                            if (!isCheckinRequest) {
12426                                pw.println("Got RemoteException!");
12427                                pw.flush();
12428                            }
12429                        }
12430                    }
12431                }
12432
12433                final long myTotalPss = mi.getTotalPss();
12434                final long myTotalUss = mi.getTotalUss();
12435
12436                synchronized (this) {
12437                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12438                        // Record this for posterity if the process has been stable.
12439                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12440                    }
12441                }
12442
12443                if (!isCheckinRequest && mi != null) {
12444                    totalPss += myTotalPss;
12445                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12446                            (hasActivities ? " / activities)" : ")"),
12447                            r.processName, myTotalPss, pid, hasActivities);
12448                    procMems.add(pssItem);
12449                    procMemsMap.put(pid, pssItem);
12450
12451                    nativePss += mi.nativePss;
12452                    dalvikPss += mi.dalvikPss;
12453                    otherPss += mi.otherPss;
12454                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12455                        long mem = mi.getOtherPss(j);
12456                        miscPss[j] += mem;
12457                        otherPss -= mem;
12458                    }
12459
12460                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12461                        cachedPss += myTotalPss;
12462                    }
12463
12464                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12465                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12466                                || oomIndex == (oomPss.length-1)) {
12467                            oomPss[oomIndex] += myTotalPss;
12468                            if (oomProcs[oomIndex] == null) {
12469                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12470                            }
12471                            oomProcs[oomIndex].add(pssItem);
12472                            break;
12473                        }
12474                    }
12475                }
12476            }
12477        }
12478
12479        if (!isCheckinRequest && procs.size() > 1) {
12480            // If we are showing aggregations, also look for native processes to
12481            // include so that our aggregations are more accurate.
12482            updateCpuStatsNow();
12483            synchronized (mProcessCpuThread) {
12484                final int N = mProcessCpuTracker.countStats();
12485                for (int i=0; i<N; i++) {
12486                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12487                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12488                        if (mi == null) {
12489                            mi = new Debug.MemoryInfo();
12490                        }
12491                        if (!brief && !oomOnly) {
12492                            Debug.getMemoryInfo(st.pid, mi);
12493                        } else {
12494                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12495                            mi.nativePrivateDirty = (int)tmpLong[0];
12496                        }
12497
12498                        final long myTotalPss = mi.getTotalPss();
12499                        totalPss += myTotalPss;
12500
12501                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12502                                st.name, myTotalPss, st.pid, false);
12503                        procMems.add(pssItem);
12504
12505                        nativePss += mi.nativePss;
12506                        dalvikPss += mi.dalvikPss;
12507                        otherPss += mi.otherPss;
12508                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12509                            long mem = mi.getOtherPss(j);
12510                            miscPss[j] += mem;
12511                            otherPss -= mem;
12512                        }
12513                        oomPss[0] += myTotalPss;
12514                        if (oomProcs[0] == null) {
12515                            oomProcs[0] = new ArrayList<MemItem>();
12516                        }
12517                        oomProcs[0].add(pssItem);
12518                    }
12519                }
12520            }
12521
12522            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12523
12524            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12525            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12526            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12527            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12528                String label = Debug.MemoryInfo.getOtherLabel(j);
12529                catMems.add(new MemItem(label, label, miscPss[j], j));
12530            }
12531
12532            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12533            for (int j=0; j<oomPss.length; j++) {
12534                if (oomPss[j] != 0) {
12535                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12536                            : DUMP_MEM_OOM_LABEL[j];
12537                    MemItem item = new MemItem(label, label, oomPss[j],
12538                            DUMP_MEM_OOM_ADJ[j]);
12539                    item.subitems = oomProcs[j];
12540                    oomMems.add(item);
12541                }
12542            }
12543
12544            if (!brief && !oomOnly && !isCompact) {
12545                pw.println();
12546                pw.println("Total PSS by process:");
12547                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12548                pw.println();
12549            }
12550            if (!isCompact) {
12551                pw.println("Total PSS by OOM adjustment:");
12552            }
12553            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12554            if (!brief && !oomOnly) {
12555                PrintWriter out = categoryPw != null ? categoryPw : pw;
12556                if (!isCompact) {
12557                    out.println();
12558                    out.println("Total PSS by category:");
12559                }
12560                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12561            }
12562            if (!isCompact) {
12563                pw.println();
12564            }
12565            MemInfoReader memInfo = new MemInfoReader();
12566            memInfo.readMemInfo();
12567            if (!brief) {
12568                if (!isCompact) {
12569                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12570                    pw.print(" kB (status ");
12571                    switch (mLastMemoryLevel) {
12572                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12573                            pw.println("normal)");
12574                            break;
12575                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12576                            pw.println("moderate)");
12577                            break;
12578                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12579                            pw.println("low)");
12580                            break;
12581                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12582                            pw.println("critical)");
12583                            break;
12584                        default:
12585                            pw.print(mLastMemoryLevel);
12586                            pw.println(")");
12587                            break;
12588                    }
12589                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12590                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12591                            pw.print(cachedPss); pw.print(" cached pss + ");
12592                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12593                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12594                } else {
12595                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12596                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12597                            + memInfo.getFreeSizeKb()); pw.print(",");
12598                    pw.println(totalPss - cachedPss);
12599                }
12600            }
12601            if (!isCompact) {
12602                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12603                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12604                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12605                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12606                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12607                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12608                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12609                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12610                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12611                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12612                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12613            }
12614            if (!brief) {
12615                if (memInfo.getZramTotalSizeKb() != 0) {
12616                    if (!isCompact) {
12617                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12618                                pw.print(" kB physical used for ");
12619                                pw.print(memInfo.getSwapTotalSizeKb()
12620                                        - memInfo.getSwapFreeSizeKb());
12621                                pw.print(" kB in swap (");
12622                                pw.print(memInfo.getSwapTotalSizeKb());
12623                                pw.println(" kB total swap)");
12624                    } else {
12625                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12626                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12627                                pw.println(memInfo.getSwapFreeSizeKb());
12628                    }
12629                }
12630                final int[] SINGLE_LONG_FORMAT = new int[] {
12631                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12632                };
12633                long[] longOut = new long[1];
12634                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12635                        SINGLE_LONG_FORMAT, null, longOut, null);
12636                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12637                longOut[0] = 0;
12638                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12639                        SINGLE_LONG_FORMAT, null, longOut, null);
12640                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12641                longOut[0] = 0;
12642                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12643                        SINGLE_LONG_FORMAT, null, longOut, null);
12644                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12645                longOut[0] = 0;
12646                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12647                        SINGLE_LONG_FORMAT, null, longOut, null);
12648                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12649                if (!isCompact) {
12650                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12651                        pw.print("      KSM: "); pw.print(sharing);
12652                                pw.print(" kB saved from shared ");
12653                                pw.print(shared); pw.println(" kB");
12654                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12655                                pw.print(voltile); pw.println(" kB volatile");
12656                    }
12657                    pw.print("   Tuning: ");
12658                    pw.print(ActivityManager.staticGetMemoryClass());
12659                    pw.print(" (large ");
12660                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12661                    pw.print("), oom ");
12662                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12663                    pw.print(" kB");
12664                    pw.print(", restore limit ");
12665                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12666                    pw.print(" kB");
12667                    if (ActivityManager.isLowRamDeviceStatic()) {
12668                        pw.print(" (low-ram)");
12669                    }
12670                    if (ActivityManager.isHighEndGfx()) {
12671                        pw.print(" (high-end-gfx)");
12672                    }
12673                    pw.println();
12674                } else {
12675                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12676                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12677                    pw.println(voltile);
12678                    pw.print("tuning,");
12679                    pw.print(ActivityManager.staticGetMemoryClass());
12680                    pw.print(',');
12681                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12682                    pw.print(',');
12683                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12684                    if (ActivityManager.isLowRamDeviceStatic()) {
12685                        pw.print(",low-ram");
12686                    }
12687                    if (ActivityManager.isHighEndGfx()) {
12688                        pw.print(",high-end-gfx");
12689                    }
12690                    pw.println();
12691                }
12692            }
12693        }
12694    }
12695
12696    /**
12697     * Searches array of arguments for the specified string
12698     * @param args array of argument strings
12699     * @param value value to search for
12700     * @return true if the value is contained in the array
12701     */
12702    private static boolean scanArgs(String[] args, String value) {
12703        if (args != null) {
12704            for (String arg : args) {
12705                if (value.equals(arg)) {
12706                    return true;
12707                }
12708            }
12709        }
12710        return false;
12711    }
12712
12713    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12714            ContentProviderRecord cpr, boolean always) {
12715        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12716
12717        if (!inLaunching || always) {
12718            synchronized (cpr) {
12719                cpr.launchingApp = null;
12720                cpr.notifyAll();
12721            }
12722            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12723            String names[] = cpr.info.authority.split(";");
12724            for (int j = 0; j < names.length; j++) {
12725                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12726            }
12727        }
12728
12729        for (int i=0; i<cpr.connections.size(); i++) {
12730            ContentProviderConnection conn = cpr.connections.get(i);
12731            if (conn.waiting) {
12732                // If this connection is waiting for the provider, then we don't
12733                // need to mess with its process unless we are always removing
12734                // or for some reason the provider is not currently launching.
12735                if (inLaunching && !always) {
12736                    continue;
12737                }
12738            }
12739            ProcessRecord capp = conn.client;
12740            conn.dead = true;
12741            if (conn.stableCount > 0) {
12742                if (!capp.persistent && capp.thread != null
12743                        && capp.pid != 0
12744                        && capp.pid != MY_PID) {
12745                    killUnneededProcessLocked(capp, "depends on provider "
12746                            + cpr.name.flattenToShortString()
12747                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12748                }
12749            } else if (capp.thread != null && conn.provider.provider != null) {
12750                try {
12751                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12752                } catch (RemoteException e) {
12753                }
12754                // In the protocol here, we don't expect the client to correctly
12755                // clean up this connection, we'll just remove it.
12756                cpr.connections.remove(i);
12757                conn.client.conProviders.remove(conn);
12758            }
12759        }
12760
12761        if (inLaunching && always) {
12762            mLaunchingProviders.remove(cpr);
12763        }
12764        return inLaunching;
12765    }
12766
12767    /**
12768     * Main code for cleaning up a process when it has gone away.  This is
12769     * called both as a result of the process dying, or directly when stopping
12770     * a process when running in single process mode.
12771     */
12772    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12773            boolean restarting, boolean allowRestart, int index) {
12774        if (index >= 0) {
12775            removeLruProcessLocked(app);
12776            ProcessList.remove(app.pid);
12777        }
12778
12779        mProcessesToGc.remove(app);
12780        mPendingPssProcesses.remove(app);
12781
12782        // Dismiss any open dialogs.
12783        if (app.crashDialog != null && !app.forceCrashReport) {
12784            app.crashDialog.dismiss();
12785            app.crashDialog = null;
12786        }
12787        if (app.anrDialog != null) {
12788            app.anrDialog.dismiss();
12789            app.anrDialog = null;
12790        }
12791        if (app.waitDialog != null) {
12792            app.waitDialog.dismiss();
12793            app.waitDialog = null;
12794        }
12795
12796        app.crashing = false;
12797        app.notResponding = false;
12798
12799        app.resetPackageList(mProcessStats);
12800        app.unlinkDeathRecipient();
12801        app.makeInactive(mProcessStats);
12802        app.forcingToForeground = null;
12803        updateProcessForegroundLocked(app, false, false);
12804        app.foregroundActivities = false;
12805        app.hasShownUi = false;
12806        app.treatLikeActivity = false;
12807        app.hasAboveClient = false;
12808        app.hasClientActivities = false;
12809
12810        mServices.killServicesLocked(app, allowRestart);
12811
12812        boolean restart = false;
12813
12814        // Remove published content providers.
12815        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12816            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12817            final boolean always = app.bad || !allowRestart;
12818            if (removeDyingProviderLocked(app, cpr, always) || always) {
12819                // We left the provider in the launching list, need to
12820                // restart it.
12821                restart = true;
12822            }
12823
12824            cpr.provider = null;
12825            cpr.proc = null;
12826        }
12827        app.pubProviders.clear();
12828
12829        // Take care of any launching providers waiting for this process.
12830        if (checkAppInLaunchingProvidersLocked(app, false)) {
12831            restart = true;
12832        }
12833
12834        // Unregister from connected content providers.
12835        if (!app.conProviders.isEmpty()) {
12836            for (int i=0; i<app.conProviders.size(); i++) {
12837                ContentProviderConnection conn = app.conProviders.get(i);
12838                conn.provider.connections.remove(conn);
12839            }
12840            app.conProviders.clear();
12841        }
12842
12843        // At this point there may be remaining entries in mLaunchingProviders
12844        // where we were the only one waiting, so they are no longer of use.
12845        // Look for these and clean up if found.
12846        // XXX Commented out for now.  Trying to figure out a way to reproduce
12847        // the actual situation to identify what is actually going on.
12848        if (false) {
12849            for (int i=0; i<mLaunchingProviders.size(); i++) {
12850                ContentProviderRecord cpr = (ContentProviderRecord)
12851                        mLaunchingProviders.get(i);
12852                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12853                    synchronized (cpr) {
12854                        cpr.launchingApp = null;
12855                        cpr.notifyAll();
12856                    }
12857                }
12858            }
12859        }
12860
12861        skipCurrentReceiverLocked(app);
12862
12863        // Unregister any receivers.
12864        for (int i=app.receivers.size()-1; i>=0; i--) {
12865            removeReceiverLocked(app.receivers.valueAt(i));
12866        }
12867        app.receivers.clear();
12868
12869        // If the app is undergoing backup, tell the backup manager about it
12870        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12871            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12872                    + mBackupTarget.appInfo + " died during backup");
12873            try {
12874                IBackupManager bm = IBackupManager.Stub.asInterface(
12875                        ServiceManager.getService(Context.BACKUP_SERVICE));
12876                bm.agentDisconnected(app.info.packageName);
12877            } catch (RemoteException e) {
12878                // can't happen; backup manager is local
12879            }
12880        }
12881
12882        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12883            ProcessChangeItem item = mPendingProcessChanges.get(i);
12884            if (item.pid == app.pid) {
12885                mPendingProcessChanges.remove(i);
12886                mAvailProcessChanges.add(item);
12887            }
12888        }
12889        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12890
12891        // If the caller is restarting this app, then leave it in its
12892        // current lists and let the caller take care of it.
12893        if (restarting) {
12894            return;
12895        }
12896
12897        if (!app.persistent || app.isolated) {
12898            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12899                    "Removing non-persistent process during cleanup: " + app);
12900            mProcessNames.remove(app.processName, app.uid);
12901            mIsolatedProcesses.remove(app.uid);
12902            if (mHeavyWeightProcess == app) {
12903                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12904                        mHeavyWeightProcess.userId, 0));
12905                mHeavyWeightProcess = null;
12906            }
12907        } else if (!app.removed) {
12908            // This app is persistent, so we need to keep its record around.
12909            // If it is not already on the pending app list, add it there
12910            // and start a new process for it.
12911            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12912                mPersistentStartingProcesses.add(app);
12913                restart = true;
12914            }
12915        }
12916        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12917                "Clean-up removing on hold: " + app);
12918        mProcessesOnHold.remove(app);
12919
12920        if (app == mHomeProcess) {
12921            mHomeProcess = null;
12922        }
12923        if (app == mPreviousProcess) {
12924            mPreviousProcess = null;
12925        }
12926
12927        if (restart && !app.isolated) {
12928            // We have components that still need to be running in the
12929            // process, so re-launch it.
12930            mProcessNames.put(app.processName, app.uid, app);
12931            startProcessLocked(app, "restart", app.processName);
12932        } else if (app.pid > 0 && app.pid != MY_PID) {
12933            // Goodbye!
12934            boolean removed;
12935            synchronized (mPidsSelfLocked) {
12936                mPidsSelfLocked.remove(app.pid);
12937                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12938            }
12939            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12940                    app.processName, app.info.uid);
12941            if (app.isolated) {
12942                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12943            }
12944            app.setPid(0);
12945        }
12946    }
12947
12948    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12949        // Look through the content providers we are waiting to have launched,
12950        // and if any run in this process then either schedule a restart of
12951        // the process or kill the client waiting for it if this process has
12952        // gone bad.
12953        int NL = mLaunchingProviders.size();
12954        boolean restart = false;
12955        for (int i=0; i<NL; i++) {
12956            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12957            if (cpr.launchingApp == app) {
12958                if (!alwaysBad && !app.bad) {
12959                    restart = true;
12960                } else {
12961                    removeDyingProviderLocked(app, cpr, true);
12962                    // cpr should have been removed from mLaunchingProviders
12963                    NL = mLaunchingProviders.size();
12964                    i--;
12965                }
12966            }
12967        }
12968        return restart;
12969    }
12970
12971    // =========================================================
12972    // SERVICES
12973    // =========================================================
12974
12975    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12976            int flags) {
12977        enforceNotIsolatedCaller("getServices");
12978        synchronized (this) {
12979            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12980        }
12981    }
12982
12983    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12984        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12985        synchronized (this) {
12986            return mServices.getRunningServiceControlPanelLocked(name);
12987        }
12988    }
12989
12990    public ComponentName startService(IApplicationThread caller, Intent service,
12991            String resolvedType, int userId) {
12992        enforceNotIsolatedCaller("startService");
12993        // Refuse possible leaked file descriptors
12994        if (service != null && service.hasFileDescriptors() == true) {
12995            throw new IllegalArgumentException("File descriptors passed in Intent");
12996        }
12997
12998        if (DEBUG_SERVICE)
12999            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13000        synchronized(this) {
13001            final int callingPid = Binder.getCallingPid();
13002            final int callingUid = Binder.getCallingUid();
13003            final long origId = Binder.clearCallingIdentity();
13004            ComponentName res = mServices.startServiceLocked(caller, service,
13005                    resolvedType, callingPid, callingUid, userId);
13006            Binder.restoreCallingIdentity(origId);
13007            return res;
13008        }
13009    }
13010
13011    ComponentName startServiceInPackage(int uid,
13012            Intent service, String resolvedType, int userId) {
13013        synchronized(this) {
13014            if (DEBUG_SERVICE)
13015                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13016            final long origId = Binder.clearCallingIdentity();
13017            ComponentName res = mServices.startServiceLocked(null, service,
13018                    resolvedType, -1, uid, userId);
13019            Binder.restoreCallingIdentity(origId);
13020            return res;
13021        }
13022    }
13023
13024    public int stopService(IApplicationThread caller, Intent service,
13025            String resolvedType, int userId) {
13026        enforceNotIsolatedCaller("stopService");
13027        // Refuse possible leaked file descriptors
13028        if (service != null && service.hasFileDescriptors() == true) {
13029            throw new IllegalArgumentException("File descriptors passed in Intent");
13030        }
13031
13032        synchronized(this) {
13033            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13034        }
13035    }
13036
13037    public IBinder peekService(Intent service, String resolvedType) {
13038        enforceNotIsolatedCaller("peekService");
13039        // Refuse possible leaked file descriptors
13040        if (service != null && service.hasFileDescriptors() == true) {
13041            throw new IllegalArgumentException("File descriptors passed in Intent");
13042        }
13043        synchronized(this) {
13044            return mServices.peekServiceLocked(service, resolvedType);
13045        }
13046    }
13047
13048    public boolean stopServiceToken(ComponentName className, IBinder token,
13049            int startId) {
13050        synchronized(this) {
13051            return mServices.stopServiceTokenLocked(className, token, startId);
13052        }
13053    }
13054
13055    public void setServiceForeground(ComponentName className, IBinder token,
13056            int id, Notification notification, boolean removeNotification) {
13057        synchronized(this) {
13058            mServices.setServiceForegroundLocked(className, token, id, notification,
13059                    removeNotification);
13060        }
13061    }
13062
13063    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13064            boolean requireFull, String name, String callerPackage) {
13065        final int callingUserId = UserHandle.getUserId(callingUid);
13066        if (callingUserId != userId) {
13067            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13068                if ((requireFull || checkComponentPermission(
13069                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13070                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13071                        && checkComponentPermission(
13072                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13073                                callingPid, callingUid, -1, true)
13074                                != PackageManager.PERMISSION_GRANTED) {
13075                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13076                        // In this case, they would like to just execute as their
13077                        // owner user instead of failing.
13078                        userId = callingUserId;
13079                    } else {
13080                        StringBuilder builder = new StringBuilder(128);
13081                        builder.append("Permission Denial: ");
13082                        builder.append(name);
13083                        if (callerPackage != null) {
13084                            builder.append(" from ");
13085                            builder.append(callerPackage);
13086                        }
13087                        builder.append(" asks to run as user ");
13088                        builder.append(userId);
13089                        builder.append(" but is calling from user ");
13090                        builder.append(UserHandle.getUserId(callingUid));
13091                        builder.append("; this requires ");
13092                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13093                        if (!requireFull) {
13094                            builder.append(" or ");
13095                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13096                        }
13097                        String msg = builder.toString();
13098                        Slog.w(TAG, msg);
13099                        throw new SecurityException(msg);
13100                    }
13101                }
13102            }
13103            if (userId == UserHandle.USER_CURRENT
13104                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13105                // Note that we may be accessing this outside of a lock...
13106                // shouldn't be a big deal, if this is being called outside
13107                // of a locked context there is intrinsically a race with
13108                // the value the caller will receive and someone else changing it.
13109                userId = mCurrentUserId;
13110            }
13111            if (!allowAll && userId < 0) {
13112                throw new IllegalArgumentException(
13113                        "Call does not support special user #" + userId);
13114            }
13115        }
13116        return userId;
13117    }
13118
13119    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13120            String className, int flags) {
13121        boolean result = false;
13122        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13123            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13124                if (ActivityManager.checkUidPermission(
13125                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13126                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13127                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13128                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13129                            + " requests FLAG_SINGLE_USER, but app does not hold "
13130                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13131                    Slog.w(TAG, msg);
13132                    throw new SecurityException(msg);
13133                }
13134                result = true;
13135            }
13136        } else if (componentProcessName == aInfo.packageName) {
13137            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13138        } else if ("system".equals(componentProcessName)) {
13139            result = true;
13140        }
13141        if (DEBUG_MU) {
13142            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13143                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13144        }
13145        return result;
13146    }
13147
13148    public int bindService(IApplicationThread caller, IBinder token,
13149            Intent service, String resolvedType,
13150            IServiceConnection connection, int flags, int userId) {
13151        enforceNotIsolatedCaller("bindService");
13152        // Refuse possible leaked file descriptors
13153        if (service != null && service.hasFileDescriptors() == true) {
13154            throw new IllegalArgumentException("File descriptors passed in Intent");
13155        }
13156
13157        synchronized(this) {
13158            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13159                    connection, flags, userId);
13160        }
13161    }
13162
13163    public boolean unbindService(IServiceConnection connection) {
13164        synchronized (this) {
13165            return mServices.unbindServiceLocked(connection);
13166        }
13167    }
13168
13169    public void publishService(IBinder token, Intent intent, IBinder service) {
13170        // Refuse possible leaked file descriptors
13171        if (intent != null && intent.hasFileDescriptors() == true) {
13172            throw new IllegalArgumentException("File descriptors passed in Intent");
13173        }
13174
13175        synchronized(this) {
13176            if (!(token instanceof ServiceRecord)) {
13177                throw new IllegalArgumentException("Invalid service token");
13178            }
13179            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13180        }
13181    }
13182
13183    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13184        // Refuse possible leaked file descriptors
13185        if (intent != null && intent.hasFileDescriptors() == true) {
13186            throw new IllegalArgumentException("File descriptors passed in Intent");
13187        }
13188
13189        synchronized(this) {
13190            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13191        }
13192    }
13193
13194    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13195        synchronized(this) {
13196            if (!(token instanceof ServiceRecord)) {
13197                throw new IllegalArgumentException("Invalid service token");
13198            }
13199            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13200        }
13201    }
13202
13203    // =========================================================
13204    // BACKUP AND RESTORE
13205    // =========================================================
13206
13207    // Cause the target app to be launched if necessary and its backup agent
13208    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13209    // activity manager to announce its creation.
13210    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13211        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13212        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13213
13214        synchronized(this) {
13215            // !!! TODO: currently no check here that we're already bound
13216            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13217            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13218            synchronized (stats) {
13219                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13220            }
13221
13222            // Backup agent is now in use, its package can't be stopped.
13223            try {
13224                AppGlobals.getPackageManager().setPackageStoppedState(
13225                        app.packageName, false, UserHandle.getUserId(app.uid));
13226            } catch (RemoteException e) {
13227            } catch (IllegalArgumentException e) {
13228                Slog.w(TAG, "Failed trying to unstop package "
13229                        + app.packageName + ": " + e);
13230            }
13231
13232            BackupRecord r = new BackupRecord(ss, app, backupMode);
13233            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13234                    ? new ComponentName(app.packageName, app.backupAgentName)
13235                    : new ComponentName("android", "FullBackupAgent");
13236            // startProcessLocked() returns existing proc's record if it's already running
13237            ProcessRecord proc = startProcessLocked(app.processName, app,
13238                    false, 0, "backup", hostingName, false, false, false);
13239            if (proc == null) {
13240                Slog.e(TAG, "Unable to start backup agent process " + r);
13241                return false;
13242            }
13243
13244            r.app = proc;
13245            mBackupTarget = r;
13246            mBackupAppName = app.packageName;
13247
13248            // Try not to kill the process during backup
13249            updateOomAdjLocked(proc);
13250
13251            // If the process is already attached, schedule the creation of the backup agent now.
13252            // If it is not yet live, this will be done when it attaches to the framework.
13253            if (proc.thread != null) {
13254                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13255                try {
13256                    proc.thread.scheduleCreateBackupAgent(app,
13257                            compatibilityInfoForPackageLocked(app), backupMode);
13258                } catch (RemoteException e) {
13259                    // Will time out on the backup manager side
13260                }
13261            } else {
13262                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13263            }
13264            // Invariants: at this point, the target app process exists and the application
13265            // is either already running or in the process of coming up.  mBackupTarget and
13266            // mBackupAppName describe the app, so that when it binds back to the AM we
13267            // know that it's scheduled for a backup-agent operation.
13268        }
13269
13270        return true;
13271    }
13272
13273    @Override
13274    public void clearPendingBackup() {
13275        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13276        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13277
13278        synchronized (this) {
13279            mBackupTarget = null;
13280            mBackupAppName = null;
13281        }
13282    }
13283
13284    // A backup agent has just come up
13285    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13286        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13287                + " = " + agent);
13288
13289        synchronized(this) {
13290            if (!agentPackageName.equals(mBackupAppName)) {
13291                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13292                return;
13293            }
13294        }
13295
13296        long oldIdent = Binder.clearCallingIdentity();
13297        try {
13298            IBackupManager bm = IBackupManager.Stub.asInterface(
13299                    ServiceManager.getService(Context.BACKUP_SERVICE));
13300            bm.agentConnected(agentPackageName, agent);
13301        } catch (RemoteException e) {
13302            // can't happen; the backup manager service is local
13303        } catch (Exception e) {
13304            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13305            e.printStackTrace();
13306        } finally {
13307            Binder.restoreCallingIdentity(oldIdent);
13308        }
13309    }
13310
13311    // done with this agent
13312    public void unbindBackupAgent(ApplicationInfo appInfo) {
13313        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13314        if (appInfo == null) {
13315            Slog.w(TAG, "unbind backup agent for null app");
13316            return;
13317        }
13318
13319        synchronized(this) {
13320            try {
13321                if (mBackupAppName == null) {
13322                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13323                    return;
13324                }
13325
13326                if (!mBackupAppName.equals(appInfo.packageName)) {
13327                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13328                    return;
13329                }
13330
13331                // Not backing this app up any more; reset its OOM adjustment
13332                final ProcessRecord proc = mBackupTarget.app;
13333                updateOomAdjLocked(proc);
13334
13335                // If the app crashed during backup, 'thread' will be null here
13336                if (proc.thread != null) {
13337                    try {
13338                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13339                                compatibilityInfoForPackageLocked(appInfo));
13340                    } catch (Exception e) {
13341                        Slog.e(TAG, "Exception when unbinding backup agent:");
13342                        e.printStackTrace();
13343                    }
13344                }
13345            } finally {
13346                mBackupTarget = null;
13347                mBackupAppName = null;
13348            }
13349        }
13350    }
13351    // =========================================================
13352    // BROADCASTS
13353    // =========================================================
13354
13355    private final List getStickiesLocked(String action, IntentFilter filter,
13356            List cur, int userId) {
13357        final ContentResolver resolver = mContext.getContentResolver();
13358        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13359        if (stickies == null) {
13360            return cur;
13361        }
13362        final ArrayList<Intent> list = stickies.get(action);
13363        if (list == null) {
13364            return cur;
13365        }
13366        int N = list.size();
13367        for (int i=0; i<N; i++) {
13368            Intent intent = list.get(i);
13369            if (filter.match(resolver, intent, true, TAG) >= 0) {
13370                if (cur == null) {
13371                    cur = new ArrayList<Intent>();
13372                }
13373                cur.add(intent);
13374            }
13375        }
13376        return cur;
13377    }
13378
13379    boolean isPendingBroadcastProcessLocked(int pid) {
13380        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13381                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13382    }
13383
13384    void skipPendingBroadcastLocked(int pid) {
13385            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13386            for (BroadcastQueue queue : mBroadcastQueues) {
13387                queue.skipPendingBroadcastLocked(pid);
13388            }
13389    }
13390
13391    // The app just attached; send any pending broadcasts that it should receive
13392    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13393        boolean didSomething = false;
13394        for (BroadcastQueue queue : mBroadcastQueues) {
13395            didSomething |= queue.sendPendingBroadcastsLocked(app);
13396        }
13397        return didSomething;
13398    }
13399
13400    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13401            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13402        enforceNotIsolatedCaller("registerReceiver");
13403        int callingUid;
13404        int callingPid;
13405        synchronized(this) {
13406            ProcessRecord callerApp = null;
13407            if (caller != null) {
13408                callerApp = getRecordForAppLocked(caller);
13409                if (callerApp == null) {
13410                    throw new SecurityException(
13411                            "Unable to find app for caller " + caller
13412                            + " (pid=" + Binder.getCallingPid()
13413                            + ") when registering receiver " + receiver);
13414                }
13415                if (callerApp.info.uid != Process.SYSTEM_UID &&
13416                        !callerApp.pkgList.containsKey(callerPackage) &&
13417                        !"android".equals(callerPackage)) {
13418                    throw new SecurityException("Given caller package " + callerPackage
13419                            + " is not running in process " + callerApp);
13420                }
13421                callingUid = callerApp.info.uid;
13422                callingPid = callerApp.pid;
13423            } else {
13424                callerPackage = null;
13425                callingUid = Binder.getCallingUid();
13426                callingPid = Binder.getCallingPid();
13427            }
13428
13429            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13430                    true, true, "registerReceiver", callerPackage);
13431
13432            List allSticky = null;
13433
13434            // Look for any matching sticky broadcasts...
13435            Iterator actions = filter.actionsIterator();
13436            if (actions != null) {
13437                while (actions.hasNext()) {
13438                    String action = (String)actions.next();
13439                    allSticky = getStickiesLocked(action, filter, allSticky,
13440                            UserHandle.USER_ALL);
13441                    allSticky = getStickiesLocked(action, filter, allSticky,
13442                            UserHandle.getUserId(callingUid));
13443                }
13444            } else {
13445                allSticky = getStickiesLocked(null, filter, allSticky,
13446                        UserHandle.USER_ALL);
13447                allSticky = getStickiesLocked(null, filter, allSticky,
13448                        UserHandle.getUserId(callingUid));
13449            }
13450
13451            // The first sticky in the list is returned directly back to
13452            // the client.
13453            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13454
13455            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13456                    + ": " + sticky);
13457
13458            if (receiver == null) {
13459                return sticky;
13460            }
13461
13462            ReceiverList rl
13463                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13464            if (rl == null) {
13465                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13466                        userId, receiver);
13467                if (rl.app != null) {
13468                    rl.app.receivers.add(rl);
13469                } else {
13470                    try {
13471                        receiver.asBinder().linkToDeath(rl, 0);
13472                    } catch (RemoteException e) {
13473                        return sticky;
13474                    }
13475                    rl.linkedToDeath = true;
13476                }
13477                mRegisteredReceivers.put(receiver.asBinder(), rl);
13478            } else if (rl.uid != callingUid) {
13479                throw new IllegalArgumentException(
13480                        "Receiver requested to register for uid " + callingUid
13481                        + " was previously registered for uid " + rl.uid);
13482            } else if (rl.pid != callingPid) {
13483                throw new IllegalArgumentException(
13484                        "Receiver requested to register for pid " + callingPid
13485                        + " was previously registered for pid " + rl.pid);
13486            } else if (rl.userId != userId) {
13487                throw new IllegalArgumentException(
13488                        "Receiver requested to register for user " + userId
13489                        + " was previously registered for user " + rl.userId);
13490            }
13491            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13492                    permission, callingUid, userId);
13493            rl.add(bf);
13494            if (!bf.debugCheck()) {
13495                Slog.w(TAG, "==> For Dynamic broadast");
13496            }
13497            mReceiverResolver.addFilter(bf);
13498
13499            // Enqueue broadcasts for all existing stickies that match
13500            // this filter.
13501            if (allSticky != null) {
13502                ArrayList receivers = new ArrayList();
13503                receivers.add(bf);
13504
13505                int N = allSticky.size();
13506                for (int i=0; i<N; i++) {
13507                    Intent intent = (Intent)allSticky.get(i);
13508                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13509                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13510                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13511                            null, null, false, true, true, -1);
13512                    queue.enqueueParallelBroadcastLocked(r);
13513                    queue.scheduleBroadcastsLocked();
13514                }
13515            }
13516
13517            return sticky;
13518        }
13519    }
13520
13521    public void unregisterReceiver(IIntentReceiver receiver) {
13522        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13523
13524        final long origId = Binder.clearCallingIdentity();
13525        try {
13526            boolean doTrim = false;
13527
13528            synchronized(this) {
13529                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13530                if (rl != null) {
13531                    if (rl.curBroadcast != null) {
13532                        BroadcastRecord r = rl.curBroadcast;
13533                        final boolean doNext = finishReceiverLocked(
13534                                receiver.asBinder(), r.resultCode, r.resultData,
13535                                r.resultExtras, r.resultAbort);
13536                        if (doNext) {
13537                            doTrim = true;
13538                            r.queue.processNextBroadcast(false);
13539                        }
13540                    }
13541
13542                    if (rl.app != null) {
13543                        rl.app.receivers.remove(rl);
13544                    }
13545                    removeReceiverLocked(rl);
13546                    if (rl.linkedToDeath) {
13547                        rl.linkedToDeath = false;
13548                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13549                    }
13550                }
13551            }
13552
13553            // If we actually concluded any broadcasts, we might now be able
13554            // to trim the recipients' apps from our working set
13555            if (doTrim) {
13556                trimApplications();
13557                return;
13558            }
13559
13560        } finally {
13561            Binder.restoreCallingIdentity(origId);
13562        }
13563    }
13564
13565    void removeReceiverLocked(ReceiverList rl) {
13566        mRegisteredReceivers.remove(rl.receiver.asBinder());
13567        int N = rl.size();
13568        for (int i=0; i<N; i++) {
13569            mReceiverResolver.removeFilter(rl.get(i));
13570        }
13571    }
13572
13573    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13574        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13575            ProcessRecord r = mLruProcesses.get(i);
13576            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13577                try {
13578                    r.thread.dispatchPackageBroadcast(cmd, packages);
13579                } catch (RemoteException ex) {
13580                }
13581            }
13582        }
13583    }
13584
13585    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13586            int[] users) {
13587        List<ResolveInfo> receivers = null;
13588        try {
13589            HashSet<ComponentName> singleUserReceivers = null;
13590            boolean scannedFirstReceivers = false;
13591            for (int user : users) {
13592                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13593                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13594                if (user != 0 && newReceivers != null) {
13595                    // If this is not the primary user, we need to check for
13596                    // any receivers that should be filtered out.
13597                    for (int i=0; i<newReceivers.size(); i++) {
13598                        ResolveInfo ri = newReceivers.get(i);
13599                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13600                            newReceivers.remove(i);
13601                            i--;
13602                        }
13603                    }
13604                }
13605                if (newReceivers != null && newReceivers.size() == 0) {
13606                    newReceivers = null;
13607                }
13608                if (receivers == null) {
13609                    receivers = newReceivers;
13610                } else if (newReceivers != null) {
13611                    // We need to concatenate the additional receivers
13612                    // found with what we have do far.  This would be easy,
13613                    // but we also need to de-dup any receivers that are
13614                    // singleUser.
13615                    if (!scannedFirstReceivers) {
13616                        // Collect any single user receivers we had already retrieved.
13617                        scannedFirstReceivers = true;
13618                        for (int i=0; i<receivers.size(); i++) {
13619                            ResolveInfo ri = receivers.get(i);
13620                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13621                                ComponentName cn = new ComponentName(
13622                                        ri.activityInfo.packageName, ri.activityInfo.name);
13623                                if (singleUserReceivers == null) {
13624                                    singleUserReceivers = new HashSet<ComponentName>();
13625                                }
13626                                singleUserReceivers.add(cn);
13627                            }
13628                        }
13629                    }
13630                    // Add the new results to the existing results, tracking
13631                    // and de-dupping single user receivers.
13632                    for (int i=0; i<newReceivers.size(); i++) {
13633                        ResolveInfo ri = newReceivers.get(i);
13634                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13635                            ComponentName cn = new ComponentName(
13636                                    ri.activityInfo.packageName, ri.activityInfo.name);
13637                            if (singleUserReceivers == null) {
13638                                singleUserReceivers = new HashSet<ComponentName>();
13639                            }
13640                            if (!singleUserReceivers.contains(cn)) {
13641                                singleUserReceivers.add(cn);
13642                                receivers.add(ri);
13643                            }
13644                        } else {
13645                            receivers.add(ri);
13646                        }
13647                    }
13648                }
13649            }
13650        } catch (RemoteException ex) {
13651            // pm is in same process, this will never happen.
13652        }
13653        return receivers;
13654    }
13655
13656    private final int broadcastIntentLocked(ProcessRecord callerApp,
13657            String callerPackage, Intent intent, String resolvedType,
13658            IIntentReceiver resultTo, int resultCode, String resultData,
13659            Bundle map, String requiredPermission, int appOp,
13660            boolean ordered, boolean sticky, int callingPid, int callingUid,
13661            int userId) {
13662        intent = new Intent(intent);
13663
13664        // By default broadcasts do not go to stopped apps.
13665        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13666
13667        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13668            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13669            + " ordered=" + ordered + " userid=" + userId);
13670        if ((resultTo != null) && !ordered) {
13671            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13672        }
13673
13674        userId = handleIncomingUser(callingPid, callingUid, userId,
13675                true, false, "broadcast", callerPackage);
13676
13677        // Make sure that the user who is receiving this broadcast is started.
13678        // If not, we will just skip it.
13679        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13680            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13681                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13682                Slog.w(TAG, "Skipping broadcast of " + intent
13683                        + ": user " + userId + " is stopped");
13684                return ActivityManager.BROADCAST_SUCCESS;
13685            }
13686        }
13687
13688        /*
13689         * Prevent non-system code (defined here to be non-persistent
13690         * processes) from sending protected broadcasts.
13691         */
13692        int callingAppId = UserHandle.getAppId(callingUid);
13693        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13694            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13695            callingUid == 0) {
13696            // Always okay.
13697        } else if (callerApp == null || !callerApp.persistent) {
13698            try {
13699                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13700                        intent.getAction())) {
13701                    String msg = "Permission Denial: not allowed to send broadcast "
13702                            + intent.getAction() + " from pid="
13703                            + callingPid + ", uid=" + callingUid;
13704                    Slog.w(TAG, msg);
13705                    throw new SecurityException(msg);
13706                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13707                    // Special case for compatibility: we don't want apps to send this,
13708                    // but historically it has not been protected and apps may be using it
13709                    // to poke their own app widget.  So, instead of making it protected,
13710                    // just limit it to the caller.
13711                    if (callerApp == null) {
13712                        String msg = "Permission Denial: not allowed to send broadcast "
13713                                + intent.getAction() + " from unknown caller.";
13714                        Slog.w(TAG, msg);
13715                        throw new SecurityException(msg);
13716                    } else if (intent.getComponent() != null) {
13717                        // They are good enough to send to an explicit component...  verify
13718                        // it is being sent to the calling app.
13719                        if (!intent.getComponent().getPackageName().equals(
13720                                callerApp.info.packageName)) {
13721                            String msg = "Permission Denial: not allowed to send broadcast "
13722                                    + intent.getAction() + " to "
13723                                    + intent.getComponent().getPackageName() + " from "
13724                                    + callerApp.info.packageName;
13725                            Slog.w(TAG, msg);
13726                            throw new SecurityException(msg);
13727                        }
13728                    } else {
13729                        // Limit broadcast to their own package.
13730                        intent.setPackage(callerApp.info.packageName);
13731                    }
13732                }
13733            } catch (RemoteException e) {
13734                Slog.w(TAG, "Remote exception", e);
13735                return ActivityManager.BROADCAST_SUCCESS;
13736            }
13737        }
13738
13739        // Handle special intents: if this broadcast is from the package
13740        // manager about a package being removed, we need to remove all of
13741        // its activities from the history stack.
13742        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13743                intent.getAction());
13744        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13745                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13746                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13747                || uidRemoved) {
13748            if (checkComponentPermission(
13749                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13750                    callingPid, callingUid, -1, true)
13751                    == PackageManager.PERMISSION_GRANTED) {
13752                if (uidRemoved) {
13753                    final Bundle intentExtras = intent.getExtras();
13754                    final int uid = intentExtras != null
13755                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13756                    if (uid >= 0) {
13757                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13758                        synchronized (bs) {
13759                            bs.removeUidStatsLocked(uid);
13760                        }
13761                        mAppOpsService.uidRemoved(uid);
13762                    }
13763                } else {
13764                    // If resources are unavailable just force stop all
13765                    // those packages and flush the attribute cache as well.
13766                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13767                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13768                        if (list != null && (list.length > 0)) {
13769                            for (String pkg : list) {
13770                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13771                                        "storage unmount");
13772                            }
13773                            sendPackageBroadcastLocked(
13774                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13775                        }
13776                    } else {
13777                        Uri data = intent.getData();
13778                        String ssp;
13779                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13780                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13781                                    intent.getAction());
13782                            boolean fullUninstall = removed &&
13783                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13784                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13785                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13786                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13787                                        false, fullUninstall, userId,
13788                                        removed ? "pkg removed" : "pkg changed");
13789                            }
13790                            if (removed) {
13791                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13792                                        new String[] {ssp}, userId);
13793                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13794                                    mAppOpsService.packageRemoved(
13795                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13796
13797                                    // Remove all permissions granted from/to this package
13798                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13799                                }
13800                            }
13801                        }
13802                    }
13803                }
13804            } else {
13805                String msg = "Permission Denial: " + intent.getAction()
13806                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13807                        + ", uid=" + callingUid + ")"
13808                        + " requires "
13809                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13810                Slog.w(TAG, msg);
13811                throw new SecurityException(msg);
13812            }
13813
13814        // Special case for adding a package: by default turn on compatibility
13815        // mode.
13816        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13817            Uri data = intent.getData();
13818            String ssp;
13819            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13820                mCompatModePackages.handlePackageAddedLocked(ssp,
13821                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13822            }
13823        }
13824
13825        /*
13826         * If this is the time zone changed action, queue up a message that will reset the timezone
13827         * of all currently running processes. This message will get queued up before the broadcast
13828         * happens.
13829         */
13830        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13831            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13832        }
13833
13834        /*
13835         * If the user set the time, let all running processes know.
13836         */
13837        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13838            final int is24Hour = intent.getBooleanExtra(
13839                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13840            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13841        }
13842
13843        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13844            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13845        }
13846
13847        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13848            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13849            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13850        }
13851
13852        // Add to the sticky list if requested.
13853        if (sticky) {
13854            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13855                    callingPid, callingUid)
13856                    != PackageManager.PERMISSION_GRANTED) {
13857                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13858                        + callingPid + ", uid=" + callingUid
13859                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13860                Slog.w(TAG, msg);
13861                throw new SecurityException(msg);
13862            }
13863            if (requiredPermission != null) {
13864                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13865                        + " and enforce permission " + requiredPermission);
13866                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13867            }
13868            if (intent.getComponent() != null) {
13869                throw new SecurityException(
13870                        "Sticky broadcasts can't target a specific component");
13871            }
13872            // We use userId directly here, since the "all" target is maintained
13873            // as a separate set of sticky broadcasts.
13874            if (userId != UserHandle.USER_ALL) {
13875                // But first, if this is not a broadcast to all users, then
13876                // make sure it doesn't conflict with an existing broadcast to
13877                // all users.
13878                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13879                        UserHandle.USER_ALL);
13880                if (stickies != null) {
13881                    ArrayList<Intent> list = stickies.get(intent.getAction());
13882                    if (list != null) {
13883                        int N = list.size();
13884                        int i;
13885                        for (i=0; i<N; i++) {
13886                            if (intent.filterEquals(list.get(i))) {
13887                                throw new IllegalArgumentException(
13888                                        "Sticky broadcast " + intent + " for user "
13889                                        + userId + " conflicts with existing global broadcast");
13890                            }
13891                        }
13892                    }
13893                }
13894            }
13895            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13896            if (stickies == null) {
13897                stickies = new ArrayMap<String, ArrayList<Intent>>();
13898                mStickyBroadcasts.put(userId, stickies);
13899            }
13900            ArrayList<Intent> list = stickies.get(intent.getAction());
13901            if (list == null) {
13902                list = new ArrayList<Intent>();
13903                stickies.put(intent.getAction(), list);
13904            }
13905            int N = list.size();
13906            int i;
13907            for (i=0; i<N; i++) {
13908                if (intent.filterEquals(list.get(i))) {
13909                    // This sticky already exists, replace it.
13910                    list.set(i, new Intent(intent));
13911                    break;
13912                }
13913            }
13914            if (i >= N) {
13915                list.add(new Intent(intent));
13916            }
13917        }
13918
13919        int[] users;
13920        if (userId == UserHandle.USER_ALL) {
13921            // Caller wants broadcast to go to all started users.
13922            users = mStartedUserArray;
13923        } else {
13924            // Caller wants broadcast to go to one specific user.
13925            users = new int[] {userId};
13926        }
13927
13928        // Figure out who all will receive this broadcast.
13929        List receivers = null;
13930        List<BroadcastFilter> registeredReceivers = null;
13931        // Need to resolve the intent to interested receivers...
13932        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13933                 == 0) {
13934            receivers = collectReceiverComponents(intent, resolvedType, users);
13935        }
13936        if (intent.getComponent() == null) {
13937            registeredReceivers = mReceiverResolver.queryIntent(intent,
13938                    resolvedType, false, userId);
13939        }
13940
13941        final boolean replacePending =
13942                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13943
13944        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13945                + " replacePending=" + replacePending);
13946
13947        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13948        if (!ordered && NR > 0) {
13949            // If we are not serializing this broadcast, then send the
13950            // registered receivers separately so they don't wait for the
13951            // components to be launched.
13952            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13953            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13954                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13955                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13956                    ordered, sticky, false, userId);
13957            if (DEBUG_BROADCAST) Slog.v(
13958                    TAG, "Enqueueing parallel broadcast " + r);
13959            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13960            if (!replaced) {
13961                queue.enqueueParallelBroadcastLocked(r);
13962                queue.scheduleBroadcastsLocked();
13963            }
13964            registeredReceivers = null;
13965            NR = 0;
13966        }
13967
13968        // Merge into one list.
13969        int ir = 0;
13970        if (receivers != null) {
13971            // A special case for PACKAGE_ADDED: do not allow the package
13972            // being added to see this broadcast.  This prevents them from
13973            // using this as a back door to get run as soon as they are
13974            // installed.  Maybe in the future we want to have a special install
13975            // broadcast or such for apps, but we'd like to deliberately make
13976            // this decision.
13977            String skipPackages[] = null;
13978            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13979                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13980                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13981                Uri data = intent.getData();
13982                if (data != null) {
13983                    String pkgName = data.getSchemeSpecificPart();
13984                    if (pkgName != null) {
13985                        skipPackages = new String[] { pkgName };
13986                    }
13987                }
13988            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13989                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13990            }
13991            if (skipPackages != null && (skipPackages.length > 0)) {
13992                for (String skipPackage : skipPackages) {
13993                    if (skipPackage != null) {
13994                        int NT = receivers.size();
13995                        for (int it=0; it<NT; it++) {
13996                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13997                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13998                                receivers.remove(it);
13999                                it--;
14000                                NT--;
14001                            }
14002                        }
14003                    }
14004                }
14005            }
14006
14007            int NT = receivers != null ? receivers.size() : 0;
14008            int it = 0;
14009            ResolveInfo curt = null;
14010            BroadcastFilter curr = null;
14011            while (it < NT && ir < NR) {
14012                if (curt == null) {
14013                    curt = (ResolveInfo)receivers.get(it);
14014                }
14015                if (curr == null) {
14016                    curr = registeredReceivers.get(ir);
14017                }
14018                if (curr.getPriority() >= curt.priority) {
14019                    // Insert this broadcast record into the final list.
14020                    receivers.add(it, curr);
14021                    ir++;
14022                    curr = null;
14023                    it++;
14024                    NT++;
14025                } else {
14026                    // Skip to the next ResolveInfo in the final list.
14027                    it++;
14028                    curt = null;
14029                }
14030            }
14031        }
14032        while (ir < NR) {
14033            if (receivers == null) {
14034                receivers = new ArrayList();
14035            }
14036            receivers.add(registeredReceivers.get(ir));
14037            ir++;
14038        }
14039
14040        if ((receivers != null && receivers.size() > 0)
14041                || resultTo != null) {
14042            BroadcastQueue queue = broadcastQueueForIntent(intent);
14043            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14044                    callerPackage, callingPid, callingUid, resolvedType,
14045                    requiredPermission, appOp, receivers, resultTo, resultCode,
14046                    resultData, map, ordered, sticky, false, userId);
14047            if (DEBUG_BROADCAST) Slog.v(
14048                    TAG, "Enqueueing ordered broadcast " + r
14049                    + ": prev had " + queue.mOrderedBroadcasts.size());
14050            if (DEBUG_BROADCAST) {
14051                int seq = r.intent.getIntExtra("seq", -1);
14052                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14053            }
14054            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14055            if (!replaced) {
14056                queue.enqueueOrderedBroadcastLocked(r);
14057                queue.scheduleBroadcastsLocked();
14058            }
14059        }
14060
14061        return ActivityManager.BROADCAST_SUCCESS;
14062    }
14063
14064    final Intent verifyBroadcastLocked(Intent intent) {
14065        // Refuse possible leaked file descriptors
14066        if (intent != null && intent.hasFileDescriptors() == true) {
14067            throw new IllegalArgumentException("File descriptors passed in Intent");
14068        }
14069
14070        int flags = intent.getFlags();
14071
14072        if (!mProcessesReady) {
14073            // if the caller really truly claims to know what they're doing, go
14074            // ahead and allow the broadcast without launching any receivers
14075            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14076                intent = new Intent(intent);
14077                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14078            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14079                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14080                        + " before boot completion");
14081                throw new IllegalStateException("Cannot broadcast before boot completed");
14082            }
14083        }
14084
14085        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14086            throw new IllegalArgumentException(
14087                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14088        }
14089
14090        return intent;
14091    }
14092
14093    public final int broadcastIntent(IApplicationThread caller,
14094            Intent intent, String resolvedType, IIntentReceiver resultTo,
14095            int resultCode, String resultData, Bundle map,
14096            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14097        enforceNotIsolatedCaller("broadcastIntent");
14098        synchronized(this) {
14099            intent = verifyBroadcastLocked(intent);
14100
14101            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14102            final int callingPid = Binder.getCallingPid();
14103            final int callingUid = Binder.getCallingUid();
14104            final long origId = Binder.clearCallingIdentity();
14105            int res = broadcastIntentLocked(callerApp,
14106                    callerApp != null ? callerApp.info.packageName : null,
14107                    intent, resolvedType, resultTo,
14108                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14109                    callingPid, callingUid, userId);
14110            Binder.restoreCallingIdentity(origId);
14111            return res;
14112        }
14113    }
14114
14115    int broadcastIntentInPackage(String packageName, int uid,
14116            Intent intent, String resolvedType, IIntentReceiver resultTo,
14117            int resultCode, String resultData, Bundle map,
14118            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14119        synchronized(this) {
14120            intent = verifyBroadcastLocked(intent);
14121
14122            final long origId = Binder.clearCallingIdentity();
14123            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14124                    resultTo, resultCode, resultData, map, requiredPermission,
14125                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14126            Binder.restoreCallingIdentity(origId);
14127            return res;
14128        }
14129    }
14130
14131    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14132        // Refuse possible leaked file descriptors
14133        if (intent != null && intent.hasFileDescriptors() == true) {
14134            throw new IllegalArgumentException("File descriptors passed in Intent");
14135        }
14136
14137        userId = handleIncomingUser(Binder.getCallingPid(),
14138                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14139
14140        synchronized(this) {
14141            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14142                    != PackageManager.PERMISSION_GRANTED) {
14143                String msg = "Permission Denial: unbroadcastIntent() from pid="
14144                        + Binder.getCallingPid()
14145                        + ", uid=" + Binder.getCallingUid()
14146                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14147                Slog.w(TAG, msg);
14148                throw new SecurityException(msg);
14149            }
14150            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14151            if (stickies != null) {
14152                ArrayList<Intent> list = stickies.get(intent.getAction());
14153                if (list != null) {
14154                    int N = list.size();
14155                    int i;
14156                    for (i=0; i<N; i++) {
14157                        if (intent.filterEquals(list.get(i))) {
14158                            list.remove(i);
14159                            break;
14160                        }
14161                    }
14162                    if (list.size() <= 0) {
14163                        stickies.remove(intent.getAction());
14164                    }
14165                }
14166                if (stickies.size() <= 0) {
14167                    mStickyBroadcasts.remove(userId);
14168                }
14169            }
14170        }
14171    }
14172
14173    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14174            String resultData, Bundle resultExtras, boolean resultAbort) {
14175        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14176        if (r == null) {
14177            Slog.w(TAG, "finishReceiver called but not found on queue");
14178            return false;
14179        }
14180
14181        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14182    }
14183
14184    void backgroundServicesFinishedLocked(int userId) {
14185        for (BroadcastQueue queue : mBroadcastQueues) {
14186            queue.backgroundServicesFinishedLocked(userId);
14187        }
14188    }
14189
14190    public void finishReceiver(IBinder who, int resultCode, String resultData,
14191            Bundle resultExtras, boolean resultAbort) {
14192        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14193
14194        // Refuse possible leaked file descriptors
14195        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14196            throw new IllegalArgumentException("File descriptors passed in Bundle");
14197        }
14198
14199        final long origId = Binder.clearCallingIdentity();
14200        try {
14201            boolean doNext = false;
14202            BroadcastRecord r;
14203
14204            synchronized(this) {
14205                r = broadcastRecordForReceiverLocked(who);
14206                if (r != null) {
14207                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14208                        resultData, resultExtras, resultAbort, true);
14209                }
14210            }
14211
14212            if (doNext) {
14213                r.queue.processNextBroadcast(false);
14214            }
14215            trimApplications();
14216        } finally {
14217            Binder.restoreCallingIdentity(origId);
14218        }
14219    }
14220
14221    // =========================================================
14222    // INSTRUMENTATION
14223    // =========================================================
14224
14225    public boolean startInstrumentation(ComponentName className,
14226            String profileFile, int flags, Bundle arguments,
14227            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14228            int userId) {
14229        enforceNotIsolatedCaller("startInstrumentation");
14230        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14231                userId, false, true, "startInstrumentation", null);
14232        // Refuse possible leaked file descriptors
14233        if (arguments != null && arguments.hasFileDescriptors()) {
14234            throw new IllegalArgumentException("File descriptors passed in Bundle");
14235        }
14236
14237        synchronized(this) {
14238            InstrumentationInfo ii = null;
14239            ApplicationInfo ai = null;
14240            try {
14241                ii = mContext.getPackageManager().getInstrumentationInfo(
14242                    className, STOCK_PM_FLAGS);
14243                ai = AppGlobals.getPackageManager().getApplicationInfo(
14244                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14245            } catch (PackageManager.NameNotFoundException e) {
14246            } catch (RemoteException e) {
14247            }
14248            if (ii == null) {
14249                reportStartInstrumentationFailure(watcher, className,
14250                        "Unable to find instrumentation info for: " + className);
14251                return false;
14252            }
14253            if (ai == null) {
14254                reportStartInstrumentationFailure(watcher, className,
14255                        "Unable to find instrumentation target package: " + ii.targetPackage);
14256                return false;
14257            }
14258
14259            int match = mContext.getPackageManager().checkSignatures(
14260                    ii.targetPackage, ii.packageName);
14261            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14262                String msg = "Permission Denial: starting instrumentation "
14263                        + className + " from pid="
14264                        + Binder.getCallingPid()
14265                        + ", uid=" + Binder.getCallingPid()
14266                        + " not allowed because package " + ii.packageName
14267                        + " does not have a signature matching the target "
14268                        + ii.targetPackage;
14269                reportStartInstrumentationFailure(watcher, className, msg);
14270                throw new SecurityException(msg);
14271            }
14272
14273            final long origId = Binder.clearCallingIdentity();
14274            // Instrumentation can kill and relaunch even persistent processes
14275            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14276                    "start instr");
14277            ProcessRecord app = addAppLocked(ai, false);
14278            app.instrumentationClass = className;
14279            app.instrumentationInfo = ai;
14280            app.instrumentationProfileFile = profileFile;
14281            app.instrumentationArguments = arguments;
14282            app.instrumentationWatcher = watcher;
14283            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14284            app.instrumentationResultClass = className;
14285            Binder.restoreCallingIdentity(origId);
14286        }
14287
14288        return true;
14289    }
14290
14291    /**
14292     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14293     * error to the logs, but if somebody is watching, send the report there too.  This enables
14294     * the "am" command to report errors with more information.
14295     *
14296     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14297     * @param cn The component name of the instrumentation.
14298     * @param report The error report.
14299     */
14300    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14301            ComponentName cn, String report) {
14302        Slog.w(TAG, report);
14303        try {
14304            if (watcher != null) {
14305                Bundle results = new Bundle();
14306                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14307                results.putString("Error", report);
14308                watcher.instrumentationStatus(cn, -1, results);
14309            }
14310        } catch (RemoteException e) {
14311            Slog.w(TAG, e);
14312        }
14313    }
14314
14315    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14316        if (app.instrumentationWatcher != null) {
14317            try {
14318                // NOTE:  IInstrumentationWatcher *must* be oneway here
14319                app.instrumentationWatcher.instrumentationFinished(
14320                    app.instrumentationClass,
14321                    resultCode,
14322                    results);
14323            } catch (RemoteException e) {
14324            }
14325        }
14326        if (app.instrumentationUiAutomationConnection != null) {
14327            try {
14328                app.instrumentationUiAutomationConnection.shutdown();
14329            } catch (RemoteException re) {
14330                /* ignore */
14331            }
14332            // Only a UiAutomation can set this flag and now that
14333            // it is finished we make sure it is reset to its default.
14334            mUserIsMonkey = false;
14335        }
14336        app.instrumentationWatcher = null;
14337        app.instrumentationUiAutomationConnection = null;
14338        app.instrumentationClass = null;
14339        app.instrumentationInfo = null;
14340        app.instrumentationProfileFile = null;
14341        app.instrumentationArguments = null;
14342
14343        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14344                "finished inst");
14345    }
14346
14347    public void finishInstrumentation(IApplicationThread target,
14348            int resultCode, Bundle results) {
14349        int userId = UserHandle.getCallingUserId();
14350        // Refuse possible leaked file descriptors
14351        if (results != null && results.hasFileDescriptors()) {
14352            throw new IllegalArgumentException("File descriptors passed in Intent");
14353        }
14354
14355        synchronized(this) {
14356            ProcessRecord app = getRecordForAppLocked(target);
14357            if (app == null) {
14358                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14359                return;
14360            }
14361            final long origId = Binder.clearCallingIdentity();
14362            finishInstrumentationLocked(app, resultCode, results);
14363            Binder.restoreCallingIdentity(origId);
14364        }
14365    }
14366
14367    // =========================================================
14368    // CONFIGURATION
14369    // =========================================================
14370
14371    public ConfigurationInfo getDeviceConfigurationInfo() {
14372        ConfigurationInfo config = new ConfigurationInfo();
14373        synchronized (this) {
14374            config.reqTouchScreen = mConfiguration.touchscreen;
14375            config.reqKeyboardType = mConfiguration.keyboard;
14376            config.reqNavigation = mConfiguration.navigation;
14377            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14378                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14379                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14380            }
14381            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14382                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14383                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14384            }
14385            config.reqGlEsVersion = GL_ES_VERSION;
14386        }
14387        return config;
14388    }
14389
14390    ActivityStack getFocusedStack() {
14391        return mStackSupervisor.getFocusedStack();
14392    }
14393
14394    public Configuration getConfiguration() {
14395        Configuration ci;
14396        synchronized(this) {
14397            ci = new Configuration(mConfiguration);
14398        }
14399        return ci;
14400    }
14401
14402    public void updatePersistentConfiguration(Configuration values) {
14403        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14404                "updateConfiguration()");
14405        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14406                "updateConfiguration()");
14407        if (values == null) {
14408            throw new NullPointerException("Configuration must not be null");
14409        }
14410
14411        synchronized(this) {
14412            final long origId = Binder.clearCallingIdentity();
14413            updateConfigurationLocked(values, null, true, false);
14414            Binder.restoreCallingIdentity(origId);
14415        }
14416    }
14417
14418    public void updateConfiguration(Configuration values) {
14419        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14420                "updateConfiguration()");
14421
14422        synchronized(this) {
14423            if (values == null && mWindowManager != null) {
14424                // sentinel: fetch the current configuration from the window manager
14425                values = mWindowManager.computeNewConfiguration();
14426            }
14427
14428            if (mWindowManager != null) {
14429                mProcessList.applyDisplaySize(mWindowManager);
14430            }
14431
14432            final long origId = Binder.clearCallingIdentity();
14433            if (values != null) {
14434                Settings.System.clearConfiguration(values);
14435            }
14436            updateConfigurationLocked(values, null, false, false);
14437            Binder.restoreCallingIdentity(origId);
14438        }
14439    }
14440
14441    /**
14442     * Do either or both things: (1) change the current configuration, and (2)
14443     * make sure the given activity is running with the (now) current
14444     * configuration.  Returns true if the activity has been left running, or
14445     * false if <var>starting</var> is being destroyed to match the new
14446     * configuration.
14447     * @param persistent TODO
14448     */
14449    boolean updateConfigurationLocked(Configuration values,
14450            ActivityRecord starting, boolean persistent, boolean initLocale) {
14451        int changes = 0;
14452
14453        if (values != null) {
14454            Configuration newConfig = new Configuration(mConfiguration);
14455            changes = newConfig.updateFrom(values);
14456            if (changes != 0) {
14457                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14458                    Slog.i(TAG, "Updating configuration to: " + values);
14459                }
14460
14461                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14462
14463                if (values.locale != null && !initLocale) {
14464                    saveLocaleLocked(values.locale,
14465                                     !values.locale.equals(mConfiguration.locale),
14466                                     values.userSetLocale);
14467                }
14468
14469                mConfigurationSeq++;
14470                if (mConfigurationSeq <= 0) {
14471                    mConfigurationSeq = 1;
14472                }
14473                newConfig.seq = mConfigurationSeq;
14474                mConfiguration = newConfig;
14475                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14476                mUsageStatsService.noteStartConfig(newConfig);
14477
14478                final Configuration configCopy = new Configuration(mConfiguration);
14479
14480                // TODO: If our config changes, should we auto dismiss any currently
14481                // showing dialogs?
14482                mShowDialogs = shouldShowDialogs(newConfig);
14483
14484                AttributeCache ac = AttributeCache.instance();
14485                if (ac != null) {
14486                    ac.updateConfiguration(configCopy);
14487                }
14488
14489                // Make sure all resources in our process are updated
14490                // right now, so that anyone who is going to retrieve
14491                // resource values after we return will be sure to get
14492                // the new ones.  This is especially important during
14493                // boot, where the first config change needs to guarantee
14494                // all resources have that config before following boot
14495                // code is executed.
14496                mSystemThread.applyConfigurationToResources(configCopy);
14497
14498                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14499                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14500                    msg.obj = new Configuration(configCopy);
14501                    mHandler.sendMessage(msg);
14502                }
14503
14504                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14505                    ProcessRecord app = mLruProcesses.get(i);
14506                    try {
14507                        if (app.thread != null) {
14508                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14509                                    + app.processName + " new config " + mConfiguration);
14510                            app.thread.scheduleConfigurationChanged(configCopy);
14511                        }
14512                    } catch (Exception e) {
14513                    }
14514                }
14515                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14516                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14517                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14518                        | Intent.FLAG_RECEIVER_FOREGROUND);
14519                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14520                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14521                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14522                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14523                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14524                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14525                    broadcastIntentLocked(null, null, intent,
14526                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14527                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14528                }
14529            }
14530        }
14531
14532        boolean kept = true;
14533        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14534        // mainStack is null during startup.
14535        if (mainStack != null) {
14536            if (changes != 0 && starting == null) {
14537                // If the configuration changed, and the caller is not already
14538                // in the process of starting an activity, then find the top
14539                // activity to check if its configuration needs to change.
14540                starting = mainStack.topRunningActivityLocked(null);
14541            }
14542
14543            if (starting != null) {
14544                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14545                // And we need to make sure at this point that all other activities
14546                // are made visible with the correct configuration.
14547                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14548            }
14549        }
14550
14551        if (values != null && mWindowManager != null) {
14552            mWindowManager.setNewConfiguration(mConfiguration);
14553        }
14554
14555        return kept;
14556    }
14557
14558    /**
14559     * Decide based on the configuration whether we should shouw the ANR,
14560     * crash, etc dialogs.  The idea is that if there is no affordnace to
14561     * press the on-screen buttons, we shouldn't show the dialog.
14562     *
14563     * A thought: SystemUI might also want to get told about this, the Power
14564     * dialog / global actions also might want different behaviors.
14565     */
14566    private static final boolean shouldShowDialogs(Configuration config) {
14567        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14568                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14569    }
14570
14571    /**
14572     * Save the locale.  You must be inside a synchronized (this) block.
14573     */
14574    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14575        if(isDiff) {
14576            SystemProperties.set("user.language", l.getLanguage());
14577            SystemProperties.set("user.region", l.getCountry());
14578        }
14579
14580        if(isPersist) {
14581            SystemProperties.set("persist.sys.language", l.getLanguage());
14582            SystemProperties.set("persist.sys.country", l.getCountry());
14583            SystemProperties.set("persist.sys.localevar", l.getVariant());
14584        }
14585    }
14586
14587    @Override
14588    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14589        ActivityRecord srec = ActivityRecord.forToken(token);
14590        return srec != null && srec.task.affinity != null &&
14591                srec.task.affinity.equals(destAffinity);
14592    }
14593
14594    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14595            Intent resultData) {
14596
14597        synchronized (this) {
14598            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14599            if (stack != null) {
14600                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14601            }
14602            return false;
14603        }
14604    }
14605
14606    public int getLaunchedFromUid(IBinder activityToken) {
14607        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14608        if (srec == null) {
14609            return -1;
14610        }
14611        return srec.launchedFromUid;
14612    }
14613
14614    public String getLaunchedFromPackage(IBinder activityToken) {
14615        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14616        if (srec == null) {
14617            return null;
14618        }
14619        return srec.launchedFromPackage;
14620    }
14621
14622    // =========================================================
14623    // LIFETIME MANAGEMENT
14624    // =========================================================
14625
14626    // Returns which broadcast queue the app is the current [or imminent] receiver
14627    // on, or 'null' if the app is not an active broadcast recipient.
14628    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14629        BroadcastRecord r = app.curReceiver;
14630        if (r != null) {
14631            return r.queue;
14632        }
14633
14634        // It's not the current receiver, but it might be starting up to become one
14635        synchronized (this) {
14636            for (BroadcastQueue queue : mBroadcastQueues) {
14637                r = queue.mPendingBroadcast;
14638                if (r != null && r.curApp == app) {
14639                    // found it; report which queue it's in
14640                    return queue;
14641                }
14642            }
14643        }
14644
14645        return null;
14646    }
14647
14648    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14649            boolean doingAll, long now) {
14650        if (mAdjSeq == app.adjSeq) {
14651            // This adjustment has already been computed.
14652            return app.curRawAdj;
14653        }
14654
14655        if (app.thread == null) {
14656            app.adjSeq = mAdjSeq;
14657            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14658            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14659            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14660        }
14661
14662        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14663        app.adjSource = null;
14664        app.adjTarget = null;
14665        app.empty = false;
14666        app.cached = false;
14667
14668        final int activitiesSize = app.activities.size();
14669
14670        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14671            // The max adjustment doesn't allow this app to be anything
14672            // below foreground, so it is not worth doing work for it.
14673            app.adjType = "fixed";
14674            app.adjSeq = mAdjSeq;
14675            app.curRawAdj = app.maxAdj;
14676            app.foregroundActivities = false;
14677            app.keeping = true;
14678            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14679            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14680            // System processes can do UI, and when they do we want to have
14681            // them trim their memory after the user leaves the UI.  To
14682            // facilitate this, here we need to determine whether or not it
14683            // is currently showing UI.
14684            app.systemNoUi = true;
14685            if (app == TOP_APP) {
14686                app.systemNoUi = false;
14687            } else if (activitiesSize > 0) {
14688                for (int j = 0; j < activitiesSize; j++) {
14689                    final ActivityRecord r = app.activities.get(j);
14690                    if (r.visible) {
14691                        app.systemNoUi = false;
14692                    }
14693                }
14694            }
14695            if (!app.systemNoUi) {
14696                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14697            }
14698            return (app.curAdj=app.maxAdj);
14699        }
14700
14701        app.keeping = false;
14702        app.systemNoUi = false;
14703
14704        // Determine the importance of the process, starting with most
14705        // important to least, and assign an appropriate OOM adjustment.
14706        int adj;
14707        int schedGroup;
14708        int procState;
14709        boolean foregroundActivities = false;
14710        boolean interesting = false;
14711        BroadcastQueue queue;
14712        if (app == TOP_APP) {
14713            // The last app on the list is the foreground app.
14714            adj = ProcessList.FOREGROUND_APP_ADJ;
14715            schedGroup = Process.THREAD_GROUP_DEFAULT;
14716            app.adjType = "top-activity";
14717            foregroundActivities = true;
14718            interesting = true;
14719            procState = ActivityManager.PROCESS_STATE_TOP;
14720        } else if (app.instrumentationClass != null) {
14721            // Don't want to kill running instrumentation.
14722            adj = ProcessList.FOREGROUND_APP_ADJ;
14723            schedGroup = Process.THREAD_GROUP_DEFAULT;
14724            app.adjType = "instrumentation";
14725            interesting = true;
14726            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14727        } else if ((queue = isReceivingBroadcast(app)) != null) {
14728            // An app that is currently receiving a broadcast also
14729            // counts as being in the foreground for OOM killer purposes.
14730            // It's placed in a sched group based on the nature of the
14731            // broadcast as reflected by which queue it's active in.
14732            adj = ProcessList.FOREGROUND_APP_ADJ;
14733            schedGroup = (queue == mFgBroadcastQueue)
14734                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14735            app.adjType = "broadcast";
14736            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14737        } else if (app.executingServices.size() > 0) {
14738            // An app that is currently executing a service callback also
14739            // counts as being in the foreground.
14740            adj = ProcessList.FOREGROUND_APP_ADJ;
14741            schedGroup = app.execServicesFg ?
14742                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14743            app.adjType = "exec-service";
14744            procState = ActivityManager.PROCESS_STATE_SERVICE;
14745            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14746        } else {
14747            // As far as we know the process is empty.  We may change our mind later.
14748            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14749            // At this point we don't actually know the adjustment.  Use the cached adj
14750            // value that the caller wants us to.
14751            adj = cachedAdj;
14752            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14753            app.cached = true;
14754            app.empty = true;
14755            app.adjType = "cch-empty";
14756        }
14757
14758        // Examine all activities if not already foreground.
14759        if (!foregroundActivities && activitiesSize > 0) {
14760            for (int j = 0; j < activitiesSize; j++) {
14761                final ActivityRecord r = app.activities.get(j);
14762                if (r.app != app) {
14763                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14764                            + app + "?!?");
14765                    continue;
14766                }
14767                if (r.visible) {
14768                    // App has a visible activity; only upgrade adjustment.
14769                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14770                        adj = ProcessList.VISIBLE_APP_ADJ;
14771                        app.adjType = "visible";
14772                    }
14773                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14774                        procState = ActivityManager.PROCESS_STATE_TOP;
14775                    }
14776                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14777                    app.cached = false;
14778                    app.empty = false;
14779                    foregroundActivities = true;
14780                    break;
14781                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14782                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14783                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14784                        app.adjType = "pausing";
14785                    }
14786                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14787                        procState = ActivityManager.PROCESS_STATE_TOP;
14788                    }
14789                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14790                    app.cached = false;
14791                    app.empty = false;
14792                    foregroundActivities = true;
14793                } else if (r.state == ActivityState.STOPPING) {
14794                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14795                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14796                        app.adjType = "stopping";
14797                    }
14798                    // For the process state, we will at this point consider the
14799                    // process to be cached.  It will be cached either as an activity
14800                    // or empty depending on whether the activity is finishing.  We do
14801                    // this so that we can treat the process as cached for purposes of
14802                    // memory trimming (determing current memory level, trim command to
14803                    // send to process) since there can be an arbitrary number of stopping
14804                    // processes and they should soon all go into the cached state.
14805                    if (!r.finishing) {
14806                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14807                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14808                        }
14809                    }
14810                    app.cached = false;
14811                    app.empty = false;
14812                    foregroundActivities = true;
14813                } else {
14814                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14815                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14816                        app.adjType = "cch-act";
14817                    }
14818                }
14819            }
14820        }
14821
14822        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14823            if (app.foregroundServices) {
14824                // The user is aware of this app, so make it visible.
14825                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14826                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14827                app.cached = false;
14828                app.adjType = "fg-service";
14829                schedGroup = Process.THREAD_GROUP_DEFAULT;
14830            } else if (app.forcingToForeground != null) {
14831                // The user is aware of this app, so make it visible.
14832                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14833                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14834                app.cached = false;
14835                app.adjType = "force-fg";
14836                app.adjSource = app.forcingToForeground;
14837                schedGroup = Process.THREAD_GROUP_DEFAULT;
14838            }
14839        }
14840
14841        if (app.foregroundServices) {
14842            interesting = true;
14843        }
14844
14845        if (app == mHeavyWeightProcess) {
14846            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14847                // We don't want to kill the current heavy-weight process.
14848                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14849                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14850                app.cached = false;
14851                app.adjType = "heavy";
14852            }
14853            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14854                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14855            }
14856        }
14857
14858        if (app == mHomeProcess) {
14859            if (adj > ProcessList.HOME_APP_ADJ) {
14860                // This process is hosting what we currently consider to be the
14861                // home app, so we don't want to let it go into the background.
14862                adj = ProcessList.HOME_APP_ADJ;
14863                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14864                app.cached = false;
14865                app.adjType = "home";
14866            }
14867            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14868                procState = ActivityManager.PROCESS_STATE_HOME;
14869            }
14870        }
14871
14872        if (app == mPreviousProcess && app.activities.size() > 0) {
14873            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14874                // This was the previous process that showed UI to the user.
14875                // We want to try to keep it around more aggressively, to give
14876                // a good experience around switching between two apps.
14877                adj = ProcessList.PREVIOUS_APP_ADJ;
14878                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14879                app.cached = false;
14880                app.adjType = "previous";
14881            }
14882            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14883                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14884            }
14885        }
14886
14887        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14888                + " reason=" + app.adjType);
14889
14890        // By default, we use the computed adjustment.  It may be changed if
14891        // there are applications dependent on our services or providers, but
14892        // this gives us a baseline and makes sure we don't get into an
14893        // infinite recursion.
14894        app.adjSeq = mAdjSeq;
14895        app.curRawAdj = adj;
14896        app.hasStartedServices = false;
14897
14898        if (mBackupTarget != null && app == mBackupTarget.app) {
14899            // If possible we want to avoid killing apps while they're being backed up
14900            if (adj > ProcessList.BACKUP_APP_ADJ) {
14901                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14902                adj = ProcessList.BACKUP_APP_ADJ;
14903                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14904                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14905                }
14906                app.adjType = "backup";
14907                app.cached = false;
14908            }
14909            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14910                procState = ActivityManager.PROCESS_STATE_BACKUP;
14911            }
14912        }
14913
14914        boolean mayBeTop = false;
14915
14916        for (int is = app.services.size()-1;
14917                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14918                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14919                        || procState > ActivityManager.PROCESS_STATE_TOP);
14920                is--) {
14921            ServiceRecord s = app.services.valueAt(is);
14922            if (s.startRequested) {
14923                app.hasStartedServices = true;
14924                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14925                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14926                }
14927                if (app.hasShownUi && app != mHomeProcess) {
14928                    // If this process has shown some UI, let it immediately
14929                    // go to the LRU list because it may be pretty heavy with
14930                    // UI stuff.  We'll tag it with a label just to help
14931                    // debug and understand what is going on.
14932                    if (adj > ProcessList.SERVICE_ADJ) {
14933                        app.adjType = "cch-started-ui-services";
14934                    }
14935                } else {
14936                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14937                        // This service has seen some activity within
14938                        // recent memory, so we will keep its process ahead
14939                        // of the background processes.
14940                        if (adj > ProcessList.SERVICE_ADJ) {
14941                            adj = ProcessList.SERVICE_ADJ;
14942                            app.adjType = "started-services";
14943                            app.cached = false;
14944                        }
14945                    }
14946                    // If we have let the service slide into the background
14947                    // state, still have some text describing what it is doing
14948                    // even though the service no longer has an impact.
14949                    if (adj > ProcessList.SERVICE_ADJ) {
14950                        app.adjType = "cch-started-services";
14951                    }
14952                }
14953                // Don't kill this process because it is doing work; it
14954                // has said it is doing work.
14955                app.keeping = true;
14956            }
14957            for (int conni = s.connections.size()-1;
14958                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14959                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14960                            || procState > ActivityManager.PROCESS_STATE_TOP);
14961                    conni--) {
14962                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14963                for (int i = 0;
14964                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14965                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14966                                || procState > ActivityManager.PROCESS_STATE_TOP);
14967                        i++) {
14968                    // XXX should compute this based on the max of
14969                    // all connected clients.
14970                    ConnectionRecord cr = clist.get(i);
14971                    if (cr.binding.client == app) {
14972                        // Binding to ourself is not interesting.
14973                        continue;
14974                    }
14975                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14976                        ProcessRecord client = cr.binding.client;
14977                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14978                                TOP_APP, doingAll, now);
14979                        int clientProcState = client.curProcState;
14980                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14981                            // If the other app is cached for any reason, for purposes here
14982                            // we are going to consider it empty.  The specific cached state
14983                            // doesn't propagate except under certain conditions.
14984                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14985                        }
14986                        String adjType = null;
14987                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14988                            // Not doing bind OOM management, so treat
14989                            // this guy more like a started service.
14990                            if (app.hasShownUi && app != mHomeProcess) {
14991                                // If this process has shown some UI, let it immediately
14992                                // go to the LRU list because it may be pretty heavy with
14993                                // UI stuff.  We'll tag it with a label just to help
14994                                // debug and understand what is going on.
14995                                if (adj > clientAdj) {
14996                                    adjType = "cch-bound-ui-services";
14997                                }
14998                                app.cached = false;
14999                                clientAdj = adj;
15000                                clientProcState = procState;
15001                            } else {
15002                                if (now >= (s.lastActivity
15003                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15004                                    // This service has not seen activity within
15005                                    // recent memory, so allow it to drop to the
15006                                    // LRU list if there is no other reason to keep
15007                                    // it around.  We'll also tag it with a label just
15008                                    // to help debug and undertand what is going on.
15009                                    if (adj > clientAdj) {
15010                                        adjType = "cch-bound-services";
15011                                    }
15012                                    clientAdj = adj;
15013                                }
15014                            }
15015                        }
15016                        if (adj > clientAdj) {
15017                            // If this process has recently shown UI, and
15018                            // the process that is binding to it is less
15019                            // important than being visible, then we don't
15020                            // care about the binding as much as we care
15021                            // about letting this process get into the LRU
15022                            // list to be killed and restarted if needed for
15023                            // memory.
15024                            if (app.hasShownUi && app != mHomeProcess
15025                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15026                                adjType = "cch-bound-ui-services";
15027                            } else {
15028                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15029                                        |Context.BIND_IMPORTANT)) != 0) {
15030                                    adj = clientAdj;
15031                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15032                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15033                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15034                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15035                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15036                                    adj = clientAdj;
15037                                } else {
15038                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15039                                        adj = ProcessList.VISIBLE_APP_ADJ;
15040                                    }
15041                                }
15042                                if (!client.cached) {
15043                                    app.cached = false;
15044                                }
15045                                if (client.keeping) {
15046                                    app.keeping = true;
15047                                }
15048                                adjType = "service";
15049                            }
15050                        }
15051                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15052                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15053                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15054                            }
15055                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15056                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15057                                    // Special handling of clients who are in the top state.
15058                                    // We *may* want to consider this process to be in the
15059                                    // top state as well, but only if there is not another
15060                                    // reason for it to be running.  Being on the top is a
15061                                    // special state, meaning you are specifically running
15062                                    // for the current top app.  If the process is already
15063                                    // running in the background for some other reason, it
15064                                    // is more important to continue considering it to be
15065                                    // in the background state.
15066                                    mayBeTop = true;
15067                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15068                                } else {
15069                                    // Special handling for above-top states (persistent
15070                                    // processes).  These should not bring the current process
15071                                    // into the top state, since they are not on top.  Instead
15072                                    // give them the best state after that.
15073                                    clientProcState =
15074                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15075                                }
15076                            }
15077                        } else {
15078                            if (clientProcState <
15079                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15080                                clientProcState =
15081                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15082                            }
15083                        }
15084                        if (procState > clientProcState) {
15085                            procState = clientProcState;
15086                        }
15087                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15088                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15089                            app.pendingUiClean = true;
15090                        }
15091                        if (adjType != null) {
15092                            app.adjType = adjType;
15093                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15094                                    .REASON_SERVICE_IN_USE;
15095                            app.adjSource = cr.binding.client;
15096                            app.adjSourceOom = clientAdj;
15097                            app.adjTarget = s.name;
15098                        }
15099                    }
15100                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15101                        app.treatLikeActivity = true;
15102                    }
15103                    final ActivityRecord a = cr.activity;
15104                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15105                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15106                                (a.visible || a.state == ActivityState.RESUMED
15107                                 || a.state == ActivityState.PAUSING)) {
15108                            adj = ProcessList.FOREGROUND_APP_ADJ;
15109                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15110                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15111                            }
15112                            app.cached = false;
15113                            app.adjType = "service";
15114                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15115                                    .REASON_SERVICE_IN_USE;
15116                            app.adjSource = a;
15117                            app.adjSourceOom = adj;
15118                            app.adjTarget = s.name;
15119                        }
15120                    }
15121                }
15122            }
15123        }
15124
15125        for (int provi = app.pubProviders.size()-1;
15126                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15127                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15128                        || procState > ActivityManager.PROCESS_STATE_TOP);
15129                provi--) {
15130            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15131            for (int i = cpr.connections.size()-1;
15132                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15133                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15134                            || procState > ActivityManager.PROCESS_STATE_TOP);
15135                    i--) {
15136                ContentProviderConnection conn = cpr.connections.get(i);
15137                ProcessRecord client = conn.client;
15138                if (client == app) {
15139                    // Being our own client is not interesting.
15140                    continue;
15141                }
15142                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15143                int clientProcState = client.curProcState;
15144                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15145                    // If the other app is cached for any reason, for purposes here
15146                    // we are going to consider it empty.
15147                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15148                }
15149                if (adj > clientAdj) {
15150                    if (app.hasShownUi && app != mHomeProcess
15151                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15152                        app.adjType = "cch-ui-provider";
15153                    } else {
15154                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15155                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15156                        app.adjType = "provider";
15157                    }
15158                    app.cached &= client.cached;
15159                    app.keeping |= client.keeping;
15160                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15161                            .REASON_PROVIDER_IN_USE;
15162                    app.adjSource = client;
15163                    app.adjSourceOom = clientAdj;
15164                    app.adjTarget = cpr.name;
15165                }
15166                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15167                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15168                        // Special handling of clients who are in the top state.
15169                        // We *may* want to consider this process to be in the
15170                        // top state as well, but only if there is not another
15171                        // reason for it to be running.  Being on the top is a
15172                        // special state, meaning you are specifically running
15173                        // for the current top app.  If the process is already
15174                        // running in the background for some other reason, it
15175                        // is more important to continue considering it to be
15176                        // in the background state.
15177                        mayBeTop = true;
15178                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15179                    } else {
15180                        // Special handling for above-top states (persistent
15181                        // processes).  These should not bring the current process
15182                        // into the top state, since they are not on top.  Instead
15183                        // give them the best state after that.
15184                        clientProcState =
15185                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15186                    }
15187                }
15188                if (procState > clientProcState) {
15189                    procState = clientProcState;
15190                }
15191                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15192                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15193                }
15194            }
15195            // If the provider has external (non-framework) process
15196            // dependencies, ensure that its adjustment is at least
15197            // FOREGROUND_APP_ADJ.
15198            if (cpr.hasExternalProcessHandles()) {
15199                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15200                    adj = ProcessList.FOREGROUND_APP_ADJ;
15201                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15202                    app.cached = false;
15203                    app.keeping = true;
15204                    app.adjType = "provider";
15205                    app.adjTarget = cpr.name;
15206                }
15207                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15208                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15209                }
15210            }
15211        }
15212
15213        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15214            // A client of one of our services or providers is in the top state.  We
15215            // *may* want to be in the top state, but not if we are already running in
15216            // the background for some other reason.  For the decision here, we are going
15217            // to pick out a few specific states that we want to remain in when a client
15218            // is top (states that tend to be longer-term) and otherwise allow it to go
15219            // to the top state.
15220            switch (procState) {
15221                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15222                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15223                case ActivityManager.PROCESS_STATE_SERVICE:
15224                    // These all are longer-term states, so pull them up to the top
15225                    // of the background states, but not all the way to the top state.
15226                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15227                    break;
15228                default:
15229                    // Otherwise, top is a better choice, so take it.
15230                    procState = ActivityManager.PROCESS_STATE_TOP;
15231                    break;
15232            }
15233        }
15234
15235        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15236            if (app.hasClientActivities) {
15237                // This is a cached process, but with client activities.  Mark it so.
15238                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15239                app.adjType = "cch-client-act";
15240            } else if (app.treatLikeActivity) {
15241                // This is a cached process, but somebody wants us to treat it like it has
15242                // an activity, okay!
15243                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15244                app.adjType = "cch-as-act";
15245            }
15246        }
15247
15248        if (adj == ProcessList.SERVICE_ADJ) {
15249            if (doingAll) {
15250                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15251                mNewNumServiceProcs++;
15252                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15253                if (!app.serviceb) {
15254                    // This service isn't far enough down on the LRU list to
15255                    // normally be a B service, but if we are low on RAM and it
15256                    // is large we want to force it down since we would prefer to
15257                    // keep launcher over it.
15258                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15259                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15260                        app.serviceHighRam = true;
15261                        app.serviceb = true;
15262                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15263                    } else {
15264                        mNewNumAServiceProcs++;
15265                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15266                    }
15267                } else {
15268                    app.serviceHighRam = false;
15269                }
15270            }
15271            if (app.serviceb) {
15272                adj = ProcessList.SERVICE_B_ADJ;
15273            }
15274        }
15275
15276        app.curRawAdj = adj;
15277
15278        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15279        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15280        if (adj > app.maxAdj) {
15281            adj = app.maxAdj;
15282            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15283                schedGroup = Process.THREAD_GROUP_DEFAULT;
15284            }
15285        }
15286        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15287            app.keeping = true;
15288        }
15289
15290        // Do final modification to adj.  Everything we do between here and applying
15291        // the final setAdj must be done in this function, because we will also use
15292        // it when computing the final cached adj later.  Note that we don't need to
15293        // worry about this for max adj above, since max adj will always be used to
15294        // keep it out of the cached vaues.
15295        app.curAdj = app.modifyRawOomAdj(adj);
15296        app.curSchedGroup = schedGroup;
15297        app.curProcState = procState;
15298        app.foregroundActivities = foregroundActivities;
15299
15300        return app.curRawAdj;
15301    }
15302
15303    /**
15304     * Schedule PSS collection of a process.
15305     */
15306    void requestPssLocked(ProcessRecord proc, int procState) {
15307        if (mPendingPssProcesses.contains(proc)) {
15308            return;
15309        }
15310        if (mPendingPssProcesses.size() == 0) {
15311            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15312        }
15313        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15314        proc.pssProcState = procState;
15315        mPendingPssProcesses.add(proc);
15316    }
15317
15318    /**
15319     * Schedule PSS collection of all processes.
15320     */
15321    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15322        if (!always) {
15323            if (now < (mLastFullPssTime +
15324                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15325                return;
15326            }
15327        }
15328        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15329        mLastFullPssTime = now;
15330        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15331        mPendingPssProcesses.clear();
15332        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15333            ProcessRecord app = mLruProcesses.get(i);
15334            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15335                app.pssProcState = app.setProcState;
15336                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15337                        isSleeping(), now);
15338                mPendingPssProcesses.add(app);
15339            }
15340        }
15341        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15342    }
15343
15344    /**
15345     * Ask a given process to GC right now.
15346     */
15347    final void performAppGcLocked(ProcessRecord app) {
15348        try {
15349            app.lastRequestedGc = SystemClock.uptimeMillis();
15350            if (app.thread != null) {
15351                if (app.reportLowMemory) {
15352                    app.reportLowMemory = false;
15353                    app.thread.scheduleLowMemory();
15354                } else {
15355                    app.thread.processInBackground();
15356                }
15357            }
15358        } catch (Exception e) {
15359            // whatever.
15360        }
15361    }
15362
15363    /**
15364     * Returns true if things are idle enough to perform GCs.
15365     */
15366    private final boolean canGcNowLocked() {
15367        boolean processingBroadcasts = false;
15368        for (BroadcastQueue q : mBroadcastQueues) {
15369            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15370                processingBroadcasts = true;
15371            }
15372        }
15373        return !processingBroadcasts
15374                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15375    }
15376
15377    /**
15378     * Perform GCs on all processes that are waiting for it, but only
15379     * if things are idle.
15380     */
15381    final void performAppGcsLocked() {
15382        final int N = mProcessesToGc.size();
15383        if (N <= 0) {
15384            return;
15385        }
15386        if (canGcNowLocked()) {
15387            while (mProcessesToGc.size() > 0) {
15388                ProcessRecord proc = mProcessesToGc.remove(0);
15389                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15390                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15391                            <= SystemClock.uptimeMillis()) {
15392                        // To avoid spamming the system, we will GC processes one
15393                        // at a time, waiting a few seconds between each.
15394                        performAppGcLocked(proc);
15395                        scheduleAppGcsLocked();
15396                        return;
15397                    } else {
15398                        // It hasn't been long enough since we last GCed this
15399                        // process...  put it in the list to wait for its time.
15400                        addProcessToGcListLocked(proc);
15401                        break;
15402                    }
15403                }
15404            }
15405
15406            scheduleAppGcsLocked();
15407        }
15408    }
15409
15410    /**
15411     * If all looks good, perform GCs on all processes waiting for them.
15412     */
15413    final void performAppGcsIfAppropriateLocked() {
15414        if (canGcNowLocked()) {
15415            performAppGcsLocked();
15416            return;
15417        }
15418        // Still not idle, wait some more.
15419        scheduleAppGcsLocked();
15420    }
15421
15422    /**
15423     * Schedule the execution of all pending app GCs.
15424     */
15425    final void scheduleAppGcsLocked() {
15426        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15427
15428        if (mProcessesToGc.size() > 0) {
15429            // Schedule a GC for the time to the next process.
15430            ProcessRecord proc = mProcessesToGc.get(0);
15431            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15432
15433            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15434            long now = SystemClock.uptimeMillis();
15435            if (when < (now+GC_TIMEOUT)) {
15436                when = now + GC_TIMEOUT;
15437            }
15438            mHandler.sendMessageAtTime(msg, when);
15439        }
15440    }
15441
15442    /**
15443     * Add a process to the array of processes waiting to be GCed.  Keeps the
15444     * list in sorted order by the last GC time.  The process can't already be
15445     * on the list.
15446     */
15447    final void addProcessToGcListLocked(ProcessRecord proc) {
15448        boolean added = false;
15449        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15450            if (mProcessesToGc.get(i).lastRequestedGc <
15451                    proc.lastRequestedGc) {
15452                added = true;
15453                mProcessesToGc.add(i+1, proc);
15454                break;
15455            }
15456        }
15457        if (!added) {
15458            mProcessesToGc.add(0, proc);
15459        }
15460    }
15461
15462    /**
15463     * Set up to ask a process to GC itself.  This will either do it
15464     * immediately, or put it on the list of processes to gc the next
15465     * time things are idle.
15466     */
15467    final void scheduleAppGcLocked(ProcessRecord app) {
15468        long now = SystemClock.uptimeMillis();
15469        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15470            return;
15471        }
15472        if (!mProcessesToGc.contains(app)) {
15473            addProcessToGcListLocked(app);
15474            scheduleAppGcsLocked();
15475        }
15476    }
15477
15478    final void checkExcessivePowerUsageLocked(boolean doKills) {
15479        updateCpuStatsNow();
15480
15481        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15482        boolean doWakeKills = doKills;
15483        boolean doCpuKills = doKills;
15484        if (mLastPowerCheckRealtime == 0) {
15485            doWakeKills = false;
15486        }
15487        if (mLastPowerCheckUptime == 0) {
15488            doCpuKills = false;
15489        }
15490        if (stats.isScreenOn()) {
15491            doWakeKills = false;
15492        }
15493        final long curRealtime = SystemClock.elapsedRealtime();
15494        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15495        final long curUptime = SystemClock.uptimeMillis();
15496        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15497        mLastPowerCheckRealtime = curRealtime;
15498        mLastPowerCheckUptime = curUptime;
15499        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15500            doWakeKills = false;
15501        }
15502        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15503            doCpuKills = false;
15504        }
15505        int i = mLruProcesses.size();
15506        while (i > 0) {
15507            i--;
15508            ProcessRecord app = mLruProcesses.get(i);
15509            if (!app.keeping) {
15510                long wtime;
15511                synchronized (stats) {
15512                    wtime = stats.getProcessWakeTime(app.info.uid,
15513                            app.pid, curRealtime);
15514                }
15515                long wtimeUsed = wtime - app.lastWakeTime;
15516                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15517                if (DEBUG_POWER) {
15518                    StringBuilder sb = new StringBuilder(128);
15519                    sb.append("Wake for ");
15520                    app.toShortString(sb);
15521                    sb.append(": over ");
15522                    TimeUtils.formatDuration(realtimeSince, sb);
15523                    sb.append(" used ");
15524                    TimeUtils.formatDuration(wtimeUsed, sb);
15525                    sb.append(" (");
15526                    sb.append((wtimeUsed*100)/realtimeSince);
15527                    sb.append("%)");
15528                    Slog.i(TAG, sb.toString());
15529                    sb.setLength(0);
15530                    sb.append("CPU for ");
15531                    app.toShortString(sb);
15532                    sb.append(": over ");
15533                    TimeUtils.formatDuration(uptimeSince, sb);
15534                    sb.append(" used ");
15535                    TimeUtils.formatDuration(cputimeUsed, sb);
15536                    sb.append(" (");
15537                    sb.append((cputimeUsed*100)/uptimeSince);
15538                    sb.append("%)");
15539                    Slog.i(TAG, sb.toString());
15540                }
15541                // If a process has held a wake lock for more
15542                // than 50% of the time during this period,
15543                // that sounds bad.  Kill!
15544                if (doWakeKills && realtimeSince > 0
15545                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15546                    synchronized (stats) {
15547                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15548                                realtimeSince, wtimeUsed);
15549                    }
15550                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15551                            + " during " + realtimeSince);
15552                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15553                } else if (doCpuKills && uptimeSince > 0
15554                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15555                    synchronized (stats) {
15556                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15557                                uptimeSince, cputimeUsed);
15558                    }
15559                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15560                            + " during " + uptimeSince);
15561                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15562                } else {
15563                    app.lastWakeTime = wtime;
15564                    app.lastCpuTime = app.curCpuTime;
15565                }
15566            }
15567        }
15568    }
15569
15570    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15571            ProcessRecord TOP_APP, boolean doingAll, long now) {
15572        boolean success = true;
15573
15574        if (app.curRawAdj != app.setRawAdj) {
15575            if (wasKeeping && !app.keeping) {
15576                // This app is no longer something we want to keep.  Note
15577                // its current wake lock time to later know to kill it if
15578                // it is not behaving well.
15579                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15580                synchronized (stats) {
15581                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15582                            app.pid, SystemClock.elapsedRealtime());
15583                }
15584                app.lastCpuTime = app.curCpuTime;
15585            }
15586
15587            app.setRawAdj = app.curRawAdj;
15588        }
15589
15590        int changes = 0;
15591
15592        if (app.curAdj != app.setAdj) {
15593            ProcessList.setOomAdj(app.pid, app.curAdj);
15594            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15595                TAG, "Set " + app.pid + " " + app.processName +
15596                " adj " + app.curAdj + ": " + app.adjType);
15597            app.setAdj = app.curAdj;
15598        }
15599
15600        if (app.setSchedGroup != app.curSchedGroup) {
15601            app.setSchedGroup = app.curSchedGroup;
15602            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15603                    "Setting process group of " + app.processName
15604                    + " to " + app.curSchedGroup);
15605            if (app.waitingToKill != null &&
15606                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15607                killUnneededProcessLocked(app, app.waitingToKill);
15608                success = false;
15609            } else {
15610                if (true) {
15611                    long oldId = Binder.clearCallingIdentity();
15612                    try {
15613                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15614                    } catch (Exception e) {
15615                        Slog.w(TAG, "Failed setting process group of " + app.pid
15616                                + " to " + app.curSchedGroup);
15617                        e.printStackTrace();
15618                    } finally {
15619                        Binder.restoreCallingIdentity(oldId);
15620                    }
15621                } else {
15622                    if (app.thread != null) {
15623                        try {
15624                            app.thread.setSchedulingGroup(app.curSchedGroup);
15625                        } catch (RemoteException e) {
15626                        }
15627                    }
15628                }
15629                Process.setSwappiness(app.pid,
15630                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15631            }
15632        }
15633        if (app.repForegroundActivities != app.foregroundActivities) {
15634            app.repForegroundActivities = app.foregroundActivities;
15635            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15636        }
15637        if (app.repProcState != app.curProcState) {
15638            app.repProcState = app.curProcState;
15639            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15640            if (app.thread != null) {
15641                try {
15642                    if (false) {
15643                        //RuntimeException h = new RuntimeException("here");
15644                        Slog.i(TAG, "Sending new process state " + app.repProcState
15645                                + " to " + app /*, h*/);
15646                    }
15647                    app.thread.setProcessState(app.repProcState);
15648                } catch (RemoteException e) {
15649                }
15650            }
15651        }
15652        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15653                app.setProcState)) {
15654            app.lastStateTime = now;
15655            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15656                    isSleeping(), now);
15657            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15658                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15659                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15660                    + (app.nextPssTime-now) + ": " + app);
15661        } else {
15662            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15663                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15664                requestPssLocked(app, app.setProcState);
15665                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15666                        isSleeping(), now);
15667            } else if (false && DEBUG_PSS) {
15668                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15669            }
15670        }
15671        if (app.setProcState != app.curProcState) {
15672            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15673                    "Proc state change of " + app.processName
15674                    + " to " + app.curProcState);
15675            app.setProcState = app.curProcState;
15676            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15677                app.notCachedSinceIdle = false;
15678            }
15679            if (!doingAll) {
15680                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15681            } else {
15682                app.procStateChanged = true;
15683            }
15684        }
15685
15686        if (changes != 0) {
15687            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15688            int i = mPendingProcessChanges.size()-1;
15689            ProcessChangeItem item = null;
15690            while (i >= 0) {
15691                item = mPendingProcessChanges.get(i);
15692                if (item.pid == app.pid) {
15693                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15694                    break;
15695                }
15696                i--;
15697            }
15698            if (i < 0) {
15699                // No existing item in pending changes; need a new one.
15700                final int NA = mAvailProcessChanges.size();
15701                if (NA > 0) {
15702                    item = mAvailProcessChanges.remove(NA-1);
15703                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15704                } else {
15705                    item = new ProcessChangeItem();
15706                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15707                }
15708                item.changes = 0;
15709                item.pid = app.pid;
15710                item.uid = app.info.uid;
15711                if (mPendingProcessChanges.size() == 0) {
15712                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15713                            "*** Enqueueing dispatch processes changed!");
15714                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15715                }
15716                mPendingProcessChanges.add(item);
15717            }
15718            item.changes |= changes;
15719            item.processState = app.repProcState;
15720            item.foregroundActivities = app.repForegroundActivities;
15721            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15722                    + Integer.toHexString(System.identityHashCode(item))
15723                    + " " + app.toShortString() + ": changes=" + item.changes
15724                    + " procState=" + item.processState
15725                    + " foreground=" + item.foregroundActivities
15726                    + " type=" + app.adjType + " source=" + app.adjSource
15727                    + " target=" + app.adjTarget);
15728        }
15729
15730        return success;
15731    }
15732
15733    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15734        if (proc.thread != null && proc.baseProcessTracker != null) {
15735            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15736        }
15737    }
15738
15739    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15740            ProcessRecord TOP_APP, boolean doingAll, long now) {
15741        if (app.thread == null) {
15742            return false;
15743        }
15744
15745        final boolean wasKeeping = app.keeping;
15746
15747        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15748
15749        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15750    }
15751
15752    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15753            boolean oomAdj) {
15754        if (isForeground != proc.foregroundServices) {
15755            proc.foregroundServices = isForeground;
15756            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15757                    proc.info.uid);
15758            if (isForeground) {
15759                if (curProcs == null) {
15760                    curProcs = new ArrayList<ProcessRecord>();
15761                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15762                }
15763                if (!curProcs.contains(proc)) {
15764                    curProcs.add(proc);
15765                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15766                            proc.info.packageName, proc.info.uid);
15767                }
15768            } else {
15769                if (curProcs != null) {
15770                    if (curProcs.remove(proc)) {
15771                        mBatteryStatsService.noteEvent(
15772                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15773                                proc.info.packageName, proc.info.uid);
15774                        if (curProcs.size() <= 0) {
15775                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15776                        }
15777                    }
15778                }
15779            }
15780            if (oomAdj) {
15781                updateOomAdjLocked();
15782            }
15783        }
15784    }
15785
15786    private final ActivityRecord resumedAppLocked() {
15787        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15788        String pkg;
15789        int uid;
15790        if (act != null && !act.sleeping) {
15791            pkg = act.packageName;
15792            uid = act.info.applicationInfo.uid;
15793        } else {
15794            pkg = null;
15795            uid = -1;
15796        }
15797        // Has the UID or resumed package name changed?
15798        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15799                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15800            if (mCurResumedPackage != null) {
15801                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15802                        mCurResumedPackage, mCurResumedUid);
15803            }
15804            mCurResumedPackage = pkg;
15805            mCurResumedUid = uid;
15806            if (mCurResumedPackage != null) {
15807                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15808                        mCurResumedPackage, mCurResumedUid);
15809            }
15810        }
15811        return act;
15812    }
15813
15814    final boolean updateOomAdjLocked(ProcessRecord app) {
15815        final ActivityRecord TOP_ACT = resumedAppLocked();
15816        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15817        final boolean wasCached = app.cached;
15818
15819        mAdjSeq++;
15820
15821        // This is the desired cached adjusment we want to tell it to use.
15822        // If our app is currently cached, we know it, and that is it.  Otherwise,
15823        // we don't know it yet, and it needs to now be cached we will then
15824        // need to do a complete oom adj.
15825        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15826                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15827        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15828                SystemClock.uptimeMillis());
15829        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15830            // Changed to/from cached state, so apps after it in the LRU
15831            // list may also be changed.
15832            updateOomAdjLocked();
15833        }
15834        return success;
15835    }
15836
15837    final void updateOomAdjLocked() {
15838        final ActivityRecord TOP_ACT = resumedAppLocked();
15839        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15840        final long now = SystemClock.uptimeMillis();
15841        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15842        final int N = mLruProcesses.size();
15843
15844        if (false) {
15845            RuntimeException e = new RuntimeException();
15846            e.fillInStackTrace();
15847            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15848        }
15849
15850        mAdjSeq++;
15851        mNewNumServiceProcs = 0;
15852        mNewNumAServiceProcs = 0;
15853
15854        final int emptyProcessLimit;
15855        final int cachedProcessLimit;
15856        if (mProcessLimit <= 0) {
15857            emptyProcessLimit = cachedProcessLimit = 0;
15858        } else if (mProcessLimit == 1) {
15859            emptyProcessLimit = 1;
15860            cachedProcessLimit = 0;
15861        } else {
15862            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15863            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15864        }
15865
15866        // Let's determine how many processes we have running vs.
15867        // how many slots we have for background processes; we may want
15868        // to put multiple processes in a slot of there are enough of
15869        // them.
15870        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15871                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15872        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15873        if (numEmptyProcs > cachedProcessLimit) {
15874            // If there are more empty processes than our limit on cached
15875            // processes, then use the cached process limit for the factor.
15876            // This ensures that the really old empty processes get pushed
15877            // down to the bottom, so if we are running low on memory we will
15878            // have a better chance at keeping around more cached processes
15879            // instead of a gazillion empty processes.
15880            numEmptyProcs = cachedProcessLimit;
15881        }
15882        int emptyFactor = numEmptyProcs/numSlots;
15883        if (emptyFactor < 1) emptyFactor = 1;
15884        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15885        if (cachedFactor < 1) cachedFactor = 1;
15886        int stepCached = 0;
15887        int stepEmpty = 0;
15888        int numCached = 0;
15889        int numEmpty = 0;
15890        int numTrimming = 0;
15891
15892        mNumNonCachedProcs = 0;
15893        mNumCachedHiddenProcs = 0;
15894
15895        // First update the OOM adjustment for each of the
15896        // application processes based on their current state.
15897        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15898        int nextCachedAdj = curCachedAdj+1;
15899        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15900        int nextEmptyAdj = curEmptyAdj+2;
15901        for (int i=N-1; i>=0; i--) {
15902            ProcessRecord app = mLruProcesses.get(i);
15903            if (!app.killedByAm && app.thread != null) {
15904                app.procStateChanged = false;
15905                final boolean wasKeeping = app.keeping;
15906                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15907
15908                // If we haven't yet assigned the final cached adj
15909                // to the process, do that now.
15910                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15911                    switch (app.curProcState) {
15912                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15913                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15914                            // This process is a cached process holding activities...
15915                            // assign it the next cached value for that type, and then
15916                            // step that cached level.
15917                            app.curRawAdj = curCachedAdj;
15918                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15919                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15920                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15921                                    + ")");
15922                            if (curCachedAdj != nextCachedAdj) {
15923                                stepCached++;
15924                                if (stepCached >= cachedFactor) {
15925                                    stepCached = 0;
15926                                    curCachedAdj = nextCachedAdj;
15927                                    nextCachedAdj += 2;
15928                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15929                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15930                                    }
15931                                }
15932                            }
15933                            break;
15934                        default:
15935                            // For everything else, assign next empty cached process
15936                            // level and bump that up.  Note that this means that
15937                            // long-running services that have dropped down to the
15938                            // cached level will be treated as empty (since their process
15939                            // state is still as a service), which is what we want.
15940                            app.curRawAdj = curEmptyAdj;
15941                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15942                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15943                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15944                                    + ")");
15945                            if (curEmptyAdj != nextEmptyAdj) {
15946                                stepEmpty++;
15947                                if (stepEmpty >= emptyFactor) {
15948                                    stepEmpty = 0;
15949                                    curEmptyAdj = nextEmptyAdj;
15950                                    nextEmptyAdj += 2;
15951                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15952                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15953                                    }
15954                                }
15955                            }
15956                            break;
15957                    }
15958                }
15959
15960                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15961
15962                // Count the number of process types.
15963                switch (app.curProcState) {
15964                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15965                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15966                        mNumCachedHiddenProcs++;
15967                        numCached++;
15968                        if (numCached > cachedProcessLimit) {
15969                            killUnneededProcessLocked(app, "cached #" + numCached);
15970                        }
15971                        break;
15972                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15973                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15974                                && app.lastActivityTime < oldTime) {
15975                            killUnneededProcessLocked(app, "empty for "
15976                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15977                                    / 1000) + "s");
15978                        } else {
15979                            numEmpty++;
15980                            if (numEmpty > emptyProcessLimit) {
15981                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15982                            }
15983                        }
15984                        break;
15985                    default:
15986                        mNumNonCachedProcs++;
15987                        break;
15988                }
15989
15990                if (app.isolated && app.services.size() <= 0) {
15991                    // If this is an isolated process, and there are no
15992                    // services running in it, then the process is no longer
15993                    // needed.  We agressively kill these because we can by
15994                    // definition not re-use the same process again, and it is
15995                    // good to avoid having whatever code was running in them
15996                    // left sitting around after no longer needed.
15997                    killUnneededProcessLocked(app, "isolated not needed");
15998                }
15999
16000                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16001                        && !app.killedByAm) {
16002                    numTrimming++;
16003                }
16004            }
16005        }
16006
16007        mNumServiceProcs = mNewNumServiceProcs;
16008
16009        // Now determine the memory trimming level of background processes.
16010        // Unfortunately we need to start at the back of the list to do this
16011        // properly.  We only do this if the number of background apps we
16012        // are managing to keep around is less than half the maximum we desire;
16013        // if we are keeping a good number around, we'll let them use whatever
16014        // memory they want.
16015        final int numCachedAndEmpty = numCached + numEmpty;
16016        int memFactor;
16017        if (numCached <= ProcessList.TRIM_CACHED_APPS
16018                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16019            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16020                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16021            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16022                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16023            } else {
16024                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16025            }
16026        } else {
16027            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16028        }
16029        // We always allow the memory level to go up (better).  We only allow it to go
16030        // down if we are in a state where that is allowed, *and* the total number of processes
16031        // has gone down since last time.
16032        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16033                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16034                + " last=" + mLastNumProcesses);
16035        if (memFactor > mLastMemoryLevel) {
16036            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16037                memFactor = mLastMemoryLevel;
16038                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16039            }
16040        }
16041        mLastMemoryLevel = memFactor;
16042        mLastNumProcesses = mLruProcesses.size();
16043        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16044        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16045        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16046            if (mLowRamStartTime == 0) {
16047                mLowRamStartTime = now;
16048            }
16049            int step = 0;
16050            int fgTrimLevel;
16051            switch (memFactor) {
16052                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16053                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16054                    break;
16055                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16056                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16057                    break;
16058                default:
16059                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16060                    break;
16061            }
16062            int factor = numTrimming/3;
16063            int minFactor = 2;
16064            if (mHomeProcess != null) minFactor++;
16065            if (mPreviousProcess != null) minFactor++;
16066            if (factor < minFactor) factor = minFactor;
16067            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16068            for (int i=N-1; i>=0; i--) {
16069                ProcessRecord app = mLruProcesses.get(i);
16070                if (allChanged || app.procStateChanged) {
16071                    setProcessTrackerState(app, trackerMemFactor, now);
16072                    app.procStateChanged = false;
16073                }
16074                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16075                        && !app.killedByAm) {
16076                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16077                        try {
16078                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16079                                    "Trimming memory of " + app.processName
16080                                    + " to " + curLevel);
16081                            app.thread.scheduleTrimMemory(curLevel);
16082                        } catch (RemoteException e) {
16083                        }
16084                        if (false) {
16085                            // For now we won't do this; our memory trimming seems
16086                            // to be good enough at this point that destroying
16087                            // activities causes more harm than good.
16088                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16089                                    && app != mHomeProcess && app != mPreviousProcess) {
16090                                // Need to do this on its own message because the stack may not
16091                                // be in a consistent state at this point.
16092                                // For these apps we will also finish their activities
16093                                // to help them free memory.
16094                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16095                            }
16096                        }
16097                    }
16098                    app.trimMemoryLevel = curLevel;
16099                    step++;
16100                    if (step >= factor) {
16101                        step = 0;
16102                        switch (curLevel) {
16103                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16104                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16105                                break;
16106                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16107                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16108                                break;
16109                        }
16110                    }
16111                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16112                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16113                            && app.thread != null) {
16114                        try {
16115                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16116                                    "Trimming memory of heavy-weight " + app.processName
16117                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16118                            app.thread.scheduleTrimMemory(
16119                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16120                        } catch (RemoteException e) {
16121                        }
16122                    }
16123                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16124                } else {
16125                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16126                            || app.systemNoUi) && app.pendingUiClean) {
16127                        // If this application is now in the background and it
16128                        // had done UI, then give it the special trim level to
16129                        // have it free UI resources.
16130                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16131                        if (app.trimMemoryLevel < level && app.thread != null) {
16132                            try {
16133                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16134                                        "Trimming memory of bg-ui " + app.processName
16135                                        + " to " + level);
16136                                app.thread.scheduleTrimMemory(level);
16137                            } catch (RemoteException e) {
16138                            }
16139                        }
16140                        app.pendingUiClean = false;
16141                    }
16142                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16143                        try {
16144                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16145                                    "Trimming memory of fg " + app.processName
16146                                    + " to " + fgTrimLevel);
16147                            app.thread.scheduleTrimMemory(fgTrimLevel);
16148                        } catch (RemoteException e) {
16149                        }
16150                    }
16151                    app.trimMemoryLevel = fgTrimLevel;
16152                }
16153            }
16154        } else {
16155            if (mLowRamStartTime != 0) {
16156                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16157                mLowRamStartTime = 0;
16158            }
16159            for (int i=N-1; i>=0; i--) {
16160                ProcessRecord app = mLruProcesses.get(i);
16161                if (allChanged || app.procStateChanged) {
16162                    setProcessTrackerState(app, trackerMemFactor, now);
16163                    app.procStateChanged = false;
16164                }
16165                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16166                        || app.systemNoUi) && app.pendingUiClean) {
16167                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16168                            && app.thread != null) {
16169                        try {
16170                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16171                                    "Trimming memory of ui hidden " + app.processName
16172                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16173                            app.thread.scheduleTrimMemory(
16174                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16175                        } catch (RemoteException e) {
16176                        }
16177                    }
16178                    app.pendingUiClean = false;
16179                }
16180                app.trimMemoryLevel = 0;
16181            }
16182        }
16183
16184        if (mAlwaysFinishActivities) {
16185            // Need to do this on its own message because the stack may not
16186            // be in a consistent state at this point.
16187            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16188        }
16189
16190        if (allChanged) {
16191            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16192        }
16193
16194        if (mProcessStats.shouldWriteNowLocked(now)) {
16195            mHandler.post(new Runnable() {
16196                @Override public void run() {
16197                    synchronized (ActivityManagerService.this) {
16198                        mProcessStats.writeStateAsyncLocked();
16199                    }
16200                }
16201            });
16202        }
16203
16204        if (DEBUG_OOM_ADJ) {
16205            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16206        }
16207    }
16208
16209    final void trimApplications() {
16210        synchronized (this) {
16211            int i;
16212
16213            // First remove any unused application processes whose package
16214            // has been removed.
16215            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16216                final ProcessRecord app = mRemovedProcesses.get(i);
16217                if (app.activities.size() == 0
16218                        && app.curReceiver == null && app.services.size() == 0) {
16219                    Slog.i(
16220                        TAG, "Exiting empty application process "
16221                        + app.processName + " ("
16222                        + (app.thread != null ? app.thread.asBinder() : null)
16223                        + ")\n");
16224                    if (app.pid > 0 && app.pid != MY_PID) {
16225                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16226                                app.processName, app.setAdj, "empty");
16227                        app.killedByAm = true;
16228                        Process.killProcessQuiet(app.pid);
16229                    } else {
16230                        try {
16231                            app.thread.scheduleExit();
16232                        } catch (Exception e) {
16233                            // Ignore exceptions.
16234                        }
16235                    }
16236                    cleanUpApplicationRecordLocked(app, false, true, -1);
16237                    mRemovedProcesses.remove(i);
16238
16239                    if (app.persistent) {
16240                        if (app.persistent) {
16241                            addAppLocked(app.info, false);
16242                        }
16243                    }
16244                }
16245            }
16246
16247            // Now update the oom adj for all processes.
16248            updateOomAdjLocked();
16249        }
16250    }
16251
16252    /** This method sends the specified signal to each of the persistent apps */
16253    public void signalPersistentProcesses(int sig) throws RemoteException {
16254        if (sig != Process.SIGNAL_USR1) {
16255            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16256        }
16257
16258        synchronized (this) {
16259            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16260                    != PackageManager.PERMISSION_GRANTED) {
16261                throw new SecurityException("Requires permission "
16262                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16263            }
16264
16265            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16266                ProcessRecord r = mLruProcesses.get(i);
16267                if (r.thread != null && r.persistent) {
16268                    Process.sendSignal(r.pid, sig);
16269                }
16270            }
16271        }
16272    }
16273
16274    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16275        if (proc == null || proc == mProfileProc) {
16276            proc = mProfileProc;
16277            path = mProfileFile;
16278            profileType = mProfileType;
16279            clearProfilerLocked();
16280        }
16281        if (proc == null) {
16282            return;
16283        }
16284        try {
16285            proc.thread.profilerControl(false, path, null, profileType);
16286        } catch (RemoteException e) {
16287            throw new IllegalStateException("Process disappeared");
16288        }
16289    }
16290
16291    private void clearProfilerLocked() {
16292        if (mProfileFd != null) {
16293            try {
16294                mProfileFd.close();
16295            } catch (IOException e) {
16296            }
16297        }
16298        mProfileApp = null;
16299        mProfileProc = null;
16300        mProfileFile = null;
16301        mProfileType = 0;
16302        mAutoStopProfiler = false;
16303    }
16304
16305    public boolean profileControl(String process, int userId, boolean start,
16306            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16307
16308        try {
16309            synchronized (this) {
16310                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16311                // its own permission.
16312                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16313                        != PackageManager.PERMISSION_GRANTED) {
16314                    throw new SecurityException("Requires permission "
16315                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16316                }
16317
16318                if (start && fd == null) {
16319                    throw new IllegalArgumentException("null fd");
16320                }
16321
16322                ProcessRecord proc = null;
16323                if (process != null) {
16324                    proc = findProcessLocked(process, userId, "profileControl");
16325                }
16326
16327                if (start && (proc == null || proc.thread == null)) {
16328                    throw new IllegalArgumentException("Unknown process: " + process);
16329                }
16330
16331                if (start) {
16332                    stopProfilerLocked(null, null, 0);
16333                    setProfileApp(proc.info, proc.processName, path, fd, false);
16334                    mProfileProc = proc;
16335                    mProfileType = profileType;
16336                    try {
16337                        fd = fd.dup();
16338                    } catch (IOException e) {
16339                        fd = null;
16340                    }
16341                    proc.thread.profilerControl(start, path, fd, profileType);
16342                    fd = null;
16343                    mProfileFd = null;
16344                } else {
16345                    stopProfilerLocked(proc, path, profileType);
16346                    if (fd != null) {
16347                        try {
16348                            fd.close();
16349                        } catch (IOException e) {
16350                        }
16351                    }
16352                }
16353
16354                return true;
16355            }
16356        } catch (RemoteException e) {
16357            throw new IllegalStateException("Process disappeared");
16358        } finally {
16359            if (fd != null) {
16360                try {
16361                    fd.close();
16362                } catch (IOException e) {
16363                }
16364            }
16365        }
16366    }
16367
16368    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16369        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16370                userId, true, true, callName, null);
16371        ProcessRecord proc = null;
16372        try {
16373            int pid = Integer.parseInt(process);
16374            synchronized (mPidsSelfLocked) {
16375                proc = mPidsSelfLocked.get(pid);
16376            }
16377        } catch (NumberFormatException e) {
16378        }
16379
16380        if (proc == null) {
16381            ArrayMap<String, SparseArray<ProcessRecord>> all
16382                    = mProcessNames.getMap();
16383            SparseArray<ProcessRecord> procs = all.get(process);
16384            if (procs != null && procs.size() > 0) {
16385                proc = procs.valueAt(0);
16386                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16387                    for (int i=1; i<procs.size(); i++) {
16388                        ProcessRecord thisProc = procs.valueAt(i);
16389                        if (thisProc.userId == userId) {
16390                            proc = thisProc;
16391                            break;
16392                        }
16393                    }
16394                }
16395            }
16396        }
16397
16398        return proc;
16399    }
16400
16401    public boolean dumpHeap(String process, int userId, boolean managed,
16402            String path, ParcelFileDescriptor fd) throws RemoteException {
16403
16404        try {
16405            synchronized (this) {
16406                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16407                // its own permission (same as profileControl).
16408                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16409                        != PackageManager.PERMISSION_GRANTED) {
16410                    throw new SecurityException("Requires permission "
16411                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16412                }
16413
16414                if (fd == null) {
16415                    throw new IllegalArgumentException("null fd");
16416                }
16417
16418                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16419                if (proc == null || proc.thread == null) {
16420                    throw new IllegalArgumentException("Unknown process: " + process);
16421                }
16422
16423                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16424                if (!isDebuggable) {
16425                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16426                        throw new SecurityException("Process not debuggable: " + proc);
16427                    }
16428                }
16429
16430                proc.thread.dumpHeap(managed, path, fd);
16431                fd = null;
16432                return true;
16433            }
16434        } catch (RemoteException e) {
16435            throw new IllegalStateException("Process disappeared");
16436        } finally {
16437            if (fd != null) {
16438                try {
16439                    fd.close();
16440                } catch (IOException e) {
16441                }
16442            }
16443        }
16444    }
16445
16446    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16447    public void monitor() {
16448        synchronized (this) { }
16449    }
16450
16451    void onCoreSettingsChange(Bundle settings) {
16452        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16453            ProcessRecord processRecord = mLruProcesses.get(i);
16454            try {
16455                if (processRecord.thread != null) {
16456                    processRecord.thread.setCoreSettings(settings);
16457                }
16458            } catch (RemoteException re) {
16459                /* ignore */
16460            }
16461        }
16462    }
16463
16464    // Multi-user methods
16465
16466    /**
16467     * Start user, if its not already running, but don't bring it to foreground.
16468     */
16469    @Override
16470    public boolean startUserInBackground(final int userId) {
16471        return startUser(userId, /* foreground */ false);
16472    }
16473
16474    /**
16475     * Refreshes the list of users related to the current user when either a
16476     * user switch happens or when a new related user is started in the
16477     * background.
16478     */
16479    private void updateCurrentProfileIdsLocked() {
16480        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16481                mCurrentUserId, false /* enabledOnly */);
16482        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16483        for (int i = 0; i < currentProfileIds.length; i++) {
16484            currentProfileIds[i] = profiles.get(i).id;
16485        }
16486        mCurrentProfileIds = currentProfileIds;
16487    }
16488
16489    private Set getProfileIdsLocked(int userId) {
16490        Set userIds = new HashSet<Integer>();
16491        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16492                userId, false /* enabledOnly */);
16493        for (UserInfo user : profiles) {
16494            userIds.add(Integer.valueOf(user.id));
16495        }
16496        return userIds;
16497    }
16498
16499    @Override
16500    public boolean switchUser(final int userId) {
16501        return startUser(userId, /* foregound */ true);
16502    }
16503
16504    private boolean startUser(final int userId, boolean foreground) {
16505        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16506                != PackageManager.PERMISSION_GRANTED) {
16507            String msg = "Permission Denial: switchUser() from pid="
16508                    + Binder.getCallingPid()
16509                    + ", uid=" + Binder.getCallingUid()
16510                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16511            Slog.w(TAG, msg);
16512            throw new SecurityException(msg);
16513        }
16514
16515        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16516
16517        final long ident = Binder.clearCallingIdentity();
16518        try {
16519            synchronized (this) {
16520                final int oldUserId = mCurrentUserId;
16521                if (oldUserId == userId) {
16522                    return true;
16523                }
16524
16525                mStackSupervisor.setLockTaskModeLocked(null);
16526
16527                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16528                if (userInfo == null) {
16529                    Slog.w(TAG, "No user info for user #" + userId);
16530                    return false;
16531                }
16532
16533                if (foreground) {
16534                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16535                            R.anim.screen_user_enter);
16536                }
16537
16538                boolean needStart = false;
16539
16540                // If the user we are switching to is not currently started, then
16541                // we need to start it now.
16542                if (mStartedUsers.get(userId) == null) {
16543                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16544                    updateStartedUserArrayLocked();
16545                    needStart = true;
16546                }
16547
16548                final Integer userIdInt = Integer.valueOf(userId);
16549                mUserLru.remove(userIdInt);
16550                mUserLru.add(userIdInt);
16551
16552                if (foreground) {
16553                    mCurrentUserId = userId;
16554                    updateCurrentProfileIdsLocked();
16555                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16556                    // Once the internal notion of the active user has switched, we lock the device
16557                    // with the option to show the user switcher on the keyguard.
16558                    mWindowManager.lockNow(null);
16559                } else {
16560                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16561                    updateCurrentProfileIdsLocked();
16562                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16563                    mUserLru.remove(currentUserIdInt);
16564                    mUserLru.add(currentUserIdInt);
16565                }
16566
16567                final UserStartedState uss = mStartedUsers.get(userId);
16568
16569                // Make sure user is in the started state.  If it is currently
16570                // stopping, we need to knock that off.
16571                if (uss.mState == UserStartedState.STATE_STOPPING) {
16572                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16573                    // so we can just fairly silently bring the user back from
16574                    // the almost-dead.
16575                    uss.mState = UserStartedState.STATE_RUNNING;
16576                    updateStartedUserArrayLocked();
16577                    needStart = true;
16578                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16579                    // This means ACTION_SHUTDOWN has been sent, so we will
16580                    // need to treat this as a new boot of the user.
16581                    uss.mState = UserStartedState.STATE_BOOTING;
16582                    updateStartedUserArrayLocked();
16583                    needStart = true;
16584                }
16585
16586                if (uss.mState == UserStartedState.STATE_BOOTING) {
16587                    // Booting up a new user, need to tell system services about it.
16588                    // Note that this is on the same handler as scheduling of broadcasts,
16589                    // which is important because it needs to go first.
16590                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16591                }
16592
16593                if (foreground) {
16594                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16595                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16596                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16597                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16598                            oldUserId, userId, uss));
16599                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16600                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16601                }
16602
16603                if (needStart) {
16604                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16605                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16606                            | Intent.FLAG_RECEIVER_FOREGROUND);
16607                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16608                    broadcastIntentLocked(null, null, intent,
16609                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16610                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16611                }
16612
16613                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16614                    if (userId != UserHandle.USER_OWNER) {
16615                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16616                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16617                        broadcastIntentLocked(null, null, intent, null,
16618                                new IIntentReceiver.Stub() {
16619                                    public void performReceive(Intent intent, int resultCode,
16620                                            String data, Bundle extras, boolean ordered,
16621                                            boolean sticky, int sendingUser) {
16622                                        userInitialized(uss, userId);
16623                                    }
16624                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16625                                true, false, MY_PID, Process.SYSTEM_UID,
16626                                userId);
16627                        uss.initializing = true;
16628                    } else {
16629                        getUserManagerLocked().makeInitialized(userInfo.id);
16630                    }
16631                }
16632
16633                if (foreground) {
16634                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16635                    if (homeInFront) {
16636                        startHomeActivityLocked(userId);
16637                    } else {
16638                        mStackSupervisor.resumeTopActivitiesLocked();
16639                    }
16640                    EventLogTags.writeAmSwitchUser(userId);
16641                    getUserManagerLocked().userForeground(userId);
16642                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16643                } else {
16644                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16645                }
16646
16647                if (needStart) {
16648                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16649                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16650                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16651                    broadcastIntentLocked(null, null, intent,
16652                            null, new IIntentReceiver.Stub() {
16653                                @Override
16654                                public void performReceive(Intent intent, int resultCode, String data,
16655                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16656                                        throws RemoteException {
16657                                }
16658                            }, 0, null, null,
16659                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16660                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16661                }
16662            }
16663        } finally {
16664            Binder.restoreCallingIdentity(ident);
16665        }
16666
16667        return true;
16668    }
16669
16670    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16671        long ident = Binder.clearCallingIdentity();
16672        try {
16673            Intent intent;
16674            if (oldUserId >= 0) {
16675                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16676                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16677                        | Intent.FLAG_RECEIVER_FOREGROUND);
16678                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16679                broadcastIntentLocked(null, null, intent,
16680                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16681                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16682            }
16683            if (newUserId >= 0) {
16684                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16685                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16686                        | Intent.FLAG_RECEIVER_FOREGROUND);
16687                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16688                broadcastIntentLocked(null, null, intent,
16689                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16690                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16691                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16692                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16693                        | Intent.FLAG_RECEIVER_FOREGROUND);
16694                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16695                broadcastIntentLocked(null, null, intent,
16696                        null, null, 0, null, null,
16697                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16698                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16699            }
16700        } finally {
16701            Binder.restoreCallingIdentity(ident);
16702        }
16703    }
16704
16705    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16706            final int newUserId) {
16707        final int N = mUserSwitchObservers.beginBroadcast();
16708        if (N > 0) {
16709            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16710                int mCount = 0;
16711                @Override
16712                public void sendResult(Bundle data) throws RemoteException {
16713                    synchronized (ActivityManagerService.this) {
16714                        if (mCurUserSwitchCallback == this) {
16715                            mCount++;
16716                            if (mCount == N) {
16717                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16718                            }
16719                        }
16720                    }
16721                }
16722            };
16723            synchronized (this) {
16724                uss.switching = true;
16725                mCurUserSwitchCallback = callback;
16726            }
16727            for (int i=0; i<N; i++) {
16728                try {
16729                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16730                            newUserId, callback);
16731                } catch (RemoteException e) {
16732                }
16733            }
16734        } else {
16735            synchronized (this) {
16736                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16737            }
16738        }
16739        mUserSwitchObservers.finishBroadcast();
16740    }
16741
16742    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16743        synchronized (this) {
16744            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16745            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16746        }
16747    }
16748
16749    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16750        mCurUserSwitchCallback = null;
16751        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16752        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16753                oldUserId, newUserId, uss));
16754    }
16755
16756    void userInitialized(UserStartedState uss, int newUserId) {
16757        completeSwitchAndInitalize(uss, newUserId, true, false);
16758    }
16759
16760    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16761        completeSwitchAndInitalize(uss, newUserId, false, true);
16762    }
16763
16764    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16765            boolean clearInitializing, boolean clearSwitching) {
16766        boolean unfrozen = false;
16767        synchronized (this) {
16768            if (clearInitializing) {
16769                uss.initializing = false;
16770                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16771            }
16772            if (clearSwitching) {
16773                uss.switching = false;
16774            }
16775            if (!uss.switching && !uss.initializing) {
16776                mWindowManager.stopFreezingScreen();
16777                unfrozen = true;
16778            }
16779        }
16780        if (unfrozen) {
16781            final int N = mUserSwitchObservers.beginBroadcast();
16782            for (int i=0; i<N; i++) {
16783                try {
16784                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16785                } catch (RemoteException e) {
16786                }
16787            }
16788            mUserSwitchObservers.finishBroadcast();
16789        }
16790    }
16791
16792    void scheduleStartProfilesLocked() {
16793        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16794            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16795                    DateUtils.SECOND_IN_MILLIS);
16796        }
16797    }
16798
16799    void startProfilesLocked() {
16800        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16801        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16802                mCurrentUserId, false /* enabledOnly */);
16803        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16804        for (UserInfo user : profiles) {
16805            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16806                    && user.id != mCurrentUserId) {
16807                toStart.add(user);
16808            }
16809        }
16810        final int n = toStart.size();
16811        int i = 0;
16812        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16813            startUserInBackground(toStart.get(i).id);
16814        }
16815        if (i < n) {
16816            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16817        }
16818    }
16819
16820    void finishUserBoot(UserStartedState uss) {
16821        synchronized (this) {
16822            if (uss.mState == UserStartedState.STATE_BOOTING
16823                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16824                uss.mState = UserStartedState.STATE_RUNNING;
16825                final int userId = uss.mHandle.getIdentifier();
16826                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16827                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16828                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16829                broadcastIntentLocked(null, null, intent,
16830                        null, null, 0, null, null,
16831                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16832                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16833            }
16834        }
16835    }
16836
16837    void finishUserSwitch(UserStartedState uss) {
16838        synchronized (this) {
16839            finishUserBoot(uss);
16840
16841            startProfilesLocked();
16842
16843            int num = mUserLru.size();
16844            int i = 0;
16845            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16846                Integer oldUserId = mUserLru.get(i);
16847                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16848                if (oldUss == null) {
16849                    // Shouldn't happen, but be sane if it does.
16850                    mUserLru.remove(i);
16851                    num--;
16852                    continue;
16853                }
16854                if (oldUss.mState == UserStartedState.STATE_STOPPING
16855                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16856                    // This user is already stopping, doesn't count.
16857                    num--;
16858                    i++;
16859                    continue;
16860                }
16861                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16862                    // Owner and current can't be stopped, but count as running.
16863                    i++;
16864                    continue;
16865                }
16866                // This is a user to be stopped.
16867                stopUserLocked(oldUserId, null);
16868                num--;
16869                i++;
16870            }
16871        }
16872    }
16873
16874    @Override
16875    public int stopUser(final int userId, final IStopUserCallback callback) {
16876        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16877                != PackageManager.PERMISSION_GRANTED) {
16878            String msg = "Permission Denial: switchUser() from pid="
16879                    + Binder.getCallingPid()
16880                    + ", uid=" + Binder.getCallingUid()
16881                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16882            Slog.w(TAG, msg);
16883            throw new SecurityException(msg);
16884        }
16885        if (userId <= 0) {
16886            throw new IllegalArgumentException("Can't stop primary user " + userId);
16887        }
16888        synchronized (this) {
16889            return stopUserLocked(userId, callback);
16890        }
16891    }
16892
16893    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16894        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16895        if (mCurrentUserId == userId) {
16896            return ActivityManager.USER_OP_IS_CURRENT;
16897        }
16898
16899        final UserStartedState uss = mStartedUsers.get(userId);
16900        if (uss == null) {
16901            // User is not started, nothing to do...  but we do need to
16902            // callback if requested.
16903            if (callback != null) {
16904                mHandler.post(new Runnable() {
16905                    @Override
16906                    public void run() {
16907                        try {
16908                            callback.userStopped(userId);
16909                        } catch (RemoteException e) {
16910                        }
16911                    }
16912                });
16913            }
16914            return ActivityManager.USER_OP_SUCCESS;
16915        }
16916
16917        if (callback != null) {
16918            uss.mStopCallbacks.add(callback);
16919        }
16920
16921        if (uss.mState != UserStartedState.STATE_STOPPING
16922                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16923            uss.mState = UserStartedState.STATE_STOPPING;
16924            updateStartedUserArrayLocked();
16925
16926            long ident = Binder.clearCallingIdentity();
16927            try {
16928                // We are going to broadcast ACTION_USER_STOPPING and then
16929                // once that is done send a final ACTION_SHUTDOWN and then
16930                // stop the user.
16931                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16932                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16933                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16934                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16935                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16936                // This is the result receiver for the final shutdown broadcast.
16937                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16938                    @Override
16939                    public void performReceive(Intent intent, int resultCode, String data,
16940                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16941                        finishUserStop(uss);
16942                    }
16943                };
16944                // This is the result receiver for the initial stopping broadcast.
16945                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16946                    @Override
16947                    public void performReceive(Intent intent, int resultCode, String data,
16948                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16949                        // On to the next.
16950                        synchronized (ActivityManagerService.this) {
16951                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16952                                // Whoops, we are being started back up.  Abort, abort!
16953                                return;
16954                            }
16955                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16956                        }
16957                        mSystemServiceManager.stopUser(userId);
16958                        broadcastIntentLocked(null, null, shutdownIntent,
16959                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16960                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16961                    }
16962                };
16963                // Kick things off.
16964                broadcastIntentLocked(null, null, stoppingIntent,
16965                        null, stoppingReceiver, 0, null, null,
16966                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16967                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16968            } finally {
16969                Binder.restoreCallingIdentity(ident);
16970            }
16971        }
16972
16973        return ActivityManager.USER_OP_SUCCESS;
16974    }
16975
16976    void finishUserStop(UserStartedState uss) {
16977        final int userId = uss.mHandle.getIdentifier();
16978        boolean stopped;
16979        ArrayList<IStopUserCallback> callbacks;
16980        synchronized (this) {
16981            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16982            if (mStartedUsers.get(userId) != uss) {
16983                stopped = false;
16984            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16985                stopped = false;
16986            } else {
16987                stopped = true;
16988                // User can no longer run.
16989                mStartedUsers.remove(userId);
16990                mUserLru.remove(Integer.valueOf(userId));
16991                updateStartedUserArrayLocked();
16992
16993                // Clean up all state and processes associated with the user.
16994                // Kill all the processes for the user.
16995                forceStopUserLocked(userId, "finish user");
16996            }
16997        }
16998
16999        for (int i=0; i<callbacks.size(); i++) {
17000            try {
17001                if (stopped) callbacks.get(i).userStopped(userId);
17002                else callbacks.get(i).userStopAborted(userId);
17003            } catch (RemoteException e) {
17004            }
17005        }
17006
17007        if (stopped) {
17008            mSystemServiceManager.cleanupUser(userId);
17009            synchronized (this) {
17010                mStackSupervisor.removeUserLocked(userId);
17011            }
17012        }
17013    }
17014
17015    @Override
17016    public UserInfo getCurrentUser() {
17017        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17018                != PackageManager.PERMISSION_GRANTED) && (
17019                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17020                != PackageManager.PERMISSION_GRANTED)) {
17021            String msg = "Permission Denial: getCurrentUser() from pid="
17022                    + Binder.getCallingPid()
17023                    + ", uid=" + Binder.getCallingUid()
17024                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17025            Slog.w(TAG, msg);
17026            throw new SecurityException(msg);
17027        }
17028        synchronized (this) {
17029            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17030        }
17031    }
17032
17033    int getCurrentUserIdLocked() {
17034        return mCurrentUserId;
17035    }
17036
17037    @Override
17038    public boolean isUserRunning(int userId, boolean orStopped) {
17039        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17040                != PackageManager.PERMISSION_GRANTED) {
17041            String msg = "Permission Denial: isUserRunning() from pid="
17042                    + Binder.getCallingPid()
17043                    + ", uid=" + Binder.getCallingUid()
17044                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17045            Slog.w(TAG, msg);
17046            throw new SecurityException(msg);
17047        }
17048        synchronized (this) {
17049            return isUserRunningLocked(userId, orStopped);
17050        }
17051    }
17052
17053    boolean isUserRunningLocked(int userId, boolean orStopped) {
17054        UserStartedState state = mStartedUsers.get(userId);
17055        if (state == null) {
17056            return false;
17057        }
17058        if (orStopped) {
17059            return true;
17060        }
17061        return state.mState != UserStartedState.STATE_STOPPING
17062                && state.mState != UserStartedState.STATE_SHUTDOWN;
17063    }
17064
17065    @Override
17066    public int[] getRunningUserIds() {
17067        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17068                != PackageManager.PERMISSION_GRANTED) {
17069            String msg = "Permission Denial: isUserRunning() from pid="
17070                    + Binder.getCallingPid()
17071                    + ", uid=" + Binder.getCallingUid()
17072                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17073            Slog.w(TAG, msg);
17074            throw new SecurityException(msg);
17075        }
17076        synchronized (this) {
17077            return mStartedUserArray;
17078        }
17079    }
17080
17081    private void updateStartedUserArrayLocked() {
17082        int num = 0;
17083        for (int i=0; i<mStartedUsers.size();  i++) {
17084            UserStartedState uss = mStartedUsers.valueAt(i);
17085            // This list does not include stopping users.
17086            if (uss.mState != UserStartedState.STATE_STOPPING
17087                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17088                num++;
17089            }
17090        }
17091        mStartedUserArray = new int[num];
17092        num = 0;
17093        for (int i=0; i<mStartedUsers.size();  i++) {
17094            UserStartedState uss = mStartedUsers.valueAt(i);
17095            if (uss.mState != UserStartedState.STATE_STOPPING
17096                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17097                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17098                num++;
17099            }
17100        }
17101    }
17102
17103    @Override
17104    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17105        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17106                != PackageManager.PERMISSION_GRANTED) {
17107            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17108                    + Binder.getCallingPid()
17109                    + ", uid=" + Binder.getCallingUid()
17110                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17111            Slog.w(TAG, msg);
17112            throw new SecurityException(msg);
17113        }
17114
17115        mUserSwitchObservers.register(observer);
17116    }
17117
17118    @Override
17119    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17120        mUserSwitchObservers.unregister(observer);
17121    }
17122
17123    private boolean userExists(int userId) {
17124        if (userId == 0) {
17125            return true;
17126        }
17127        UserManagerService ums = getUserManagerLocked();
17128        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17129    }
17130
17131    int[] getUsersLocked() {
17132        UserManagerService ums = getUserManagerLocked();
17133        return ums != null ? ums.getUserIds() : new int[] { 0 };
17134    }
17135
17136    UserManagerService getUserManagerLocked() {
17137        if (mUserManager == null) {
17138            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17139            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17140        }
17141        return mUserManager;
17142    }
17143
17144    private int applyUserId(int uid, int userId) {
17145        return UserHandle.getUid(userId, uid);
17146    }
17147
17148    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17149        if (info == null) return null;
17150        ApplicationInfo newInfo = new ApplicationInfo(info);
17151        newInfo.uid = applyUserId(info.uid, userId);
17152        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17153                + info.packageName;
17154        return newInfo;
17155    }
17156
17157    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17158        if (aInfo == null
17159                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17160            return aInfo;
17161        }
17162
17163        ActivityInfo info = new ActivityInfo(aInfo);
17164        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17165        return info;
17166    }
17167
17168    private final class LocalService extends ActivityManagerInternal {
17169        @Override
17170        public void goingToSleep() {
17171            ActivityManagerService.this.goingToSleep();
17172        }
17173
17174        @Override
17175        public void wakingUp() {
17176            ActivityManagerService.this.wakingUp();
17177        }
17178    }
17179
17180    /**
17181     * An implementation of IAppTask, that allows an app to manage its own tasks via
17182     * {@link android.app.ActivityManager#AppTask}.  We keep track of the callingUid to ensure that
17183     * only the process that calls getAppTasks() can call the AppTask methods.
17184     */
17185    class AppTaskImpl extends IAppTask.Stub {
17186        private int mTaskId;
17187        private int mCallingUid;
17188
17189        public AppTaskImpl(int taskId, int callingUid) {
17190            mTaskId = taskId;
17191            mCallingUid = callingUid;
17192        }
17193
17194        @Override
17195        public void finishAndRemoveTask() {
17196            // Ensure that we are called from the same process that created this AppTask
17197            if (mCallingUid != Binder.getCallingUid()) {
17198                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17199                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17200                return;
17201            }
17202
17203            synchronized (ActivityManagerService.this) {
17204                long origId = Binder.clearCallingIdentity();
17205                try {
17206                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17207                    if (tr != null) {
17208                        // Only kill the process if we are not a new document
17209                        int flags = tr.getBaseIntent().getFlags();
17210                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17211                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17212                        removeTaskByIdLocked(mTaskId,
17213                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17214                    }
17215                } finally {
17216                    Binder.restoreCallingIdentity(origId);
17217                }
17218            }
17219        }
17220
17221        @Override
17222        public ActivityManager.RecentTaskInfo getTaskInfo() {
17223            // Ensure that we are called from the same process that created this AppTask
17224            if (mCallingUid != Binder.getCallingUid()) {
17225                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17226                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17227                return null;
17228            }
17229
17230            synchronized (ActivityManagerService.this) {
17231                long origId = Binder.clearCallingIdentity();
17232                try {
17233                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17234                    if (tr != null) {
17235                        return createRecentTaskInfoFromTaskRecord(tr);
17236                    }
17237                } finally {
17238                    Binder.restoreCallingIdentity(origId);
17239                }
17240                return null;
17241            }
17242        }
17243    }
17244}
17245