ActivityManagerService.java revision 7dab61455c32c0a93711ae977d197202dacb6bb6
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.appwidget.AppWidgetManager;
37import android.graphics.Rect;
38import android.os.BatteryStats;
39import android.os.PersistableBundle;
40import android.service.voice.IVoiceInteractionSession;
41import android.util.ArrayMap;
42
43import com.android.internal.R;
44import com.android.internal.annotations.GuardedBy;
45import com.android.internal.app.IAppOpsService;
46import com.android.internal.app.IVoiceInteractor;
47import com.android.internal.app.ProcessMap;
48import com.android.internal.app.ProcessStats;
49import com.android.internal.content.PackageMonitor;
50import com.android.internal.os.BackgroundThread;
51import com.android.internal.os.BatteryStatsImpl;
52import com.android.internal.os.ProcessCpuTracker;
53import com.android.internal.os.TransferPipe;
54import com.android.internal.os.Zygote;
55import com.android.internal.util.FastPrintWriter;
56import com.android.internal.util.FastXmlSerializer;
57import com.android.internal.util.MemInfoReader;
58import com.android.internal.util.Preconditions;
59import com.android.server.AppOpsService;
60import com.android.server.AttributeCache;
61import com.android.server.IntentResolver;
62import com.android.server.LocalServices;
63import com.android.server.ServiceThread;
64import com.android.server.SystemService;
65import com.android.server.SystemServiceManager;
66import com.android.server.Watchdog;
67import com.android.server.am.ActivityStack.ActivityState;
68import com.android.server.firewall.IntentFirewall;
69import com.android.server.pm.UserManagerService;
70import com.android.server.wm.AppTransition;
71import com.android.server.wm.WindowManagerService;
72import com.google.android.collect.Lists;
73import com.google.android.collect.Maps;
74
75import libcore.io.IoUtils;
76
77import org.xmlpull.v1.XmlPullParser;
78import org.xmlpull.v1.XmlPullParserException;
79import org.xmlpull.v1.XmlSerializer;
80
81import android.app.Activity;
82import android.app.ActivityManager;
83import android.app.ActivityManager.RunningTaskInfo;
84import android.app.ActivityManager.StackInfo;
85import android.app.ActivityManagerInternal;
86import android.app.ActivityManagerNative;
87import android.app.ActivityOptions;
88import android.app.ActivityThread;
89import android.app.AlertDialog;
90import android.app.AppGlobals;
91import android.app.ApplicationErrorReport;
92import android.app.Dialog;
93import android.app.IActivityController;
94import android.app.IApplicationThread;
95import android.app.IInstrumentationWatcher;
96import android.app.INotificationManager;
97import android.app.IProcessObserver;
98import android.app.IServiceConnection;
99import android.app.IStopUserCallback;
100import android.app.IUiAutomationConnection;
101import android.app.IUserSwitchObserver;
102import android.app.Instrumentation;
103import android.app.Notification;
104import android.app.NotificationManager;
105import android.app.PendingIntent;
106import android.app.backup.IBackupManager;
107import android.content.ActivityNotFoundException;
108import android.content.BroadcastReceiver;
109import android.content.ClipData;
110import android.content.ComponentCallbacks2;
111import android.content.ComponentName;
112import android.content.ContentProvider;
113import android.content.ContentResolver;
114import android.content.Context;
115import android.content.DialogInterface;
116import android.content.IContentProvider;
117import android.content.IIntentReceiver;
118import android.content.IIntentSender;
119import android.content.Intent;
120import android.content.IntentFilter;
121import android.content.IntentSender;
122import android.content.pm.ActivityInfo;
123import android.content.pm.ApplicationInfo;
124import android.content.pm.ConfigurationInfo;
125import android.content.pm.IPackageDataObserver;
126import android.content.pm.IPackageManager;
127import android.content.pm.InstrumentationInfo;
128import android.content.pm.PackageInfo;
129import android.content.pm.PackageManager;
130import android.content.pm.ParceledListSlice;
131import android.content.pm.UserInfo;
132import android.content.pm.PackageManager.NameNotFoundException;
133import android.content.pm.PathPermission;
134import android.content.pm.ProviderInfo;
135import android.content.pm.ResolveInfo;
136import android.content.pm.ServiceInfo;
137import android.content.res.CompatibilityInfo;
138import android.content.res.Configuration;
139import android.graphics.Bitmap;
140import android.net.Proxy;
141import android.net.ProxyInfo;
142import android.net.Uri;
143import android.os.Binder;
144import android.os.Build;
145import android.os.Bundle;
146import android.os.Debug;
147import android.os.DropBoxManager;
148import android.os.Environment;
149import android.os.FactoryTest;
150import android.os.FileObserver;
151import android.os.FileUtils;
152import android.os.Handler;
153import android.os.IBinder;
154import android.os.IPermissionController;
155import android.os.IRemoteCallback;
156import android.os.IUserManager;
157import android.os.Looper;
158import android.os.Message;
159import android.os.Parcel;
160import android.os.ParcelFileDescriptor;
161import android.os.Process;
162import android.os.RemoteCallbackList;
163import android.os.RemoteException;
164import android.os.SELinux;
165import android.os.ServiceManager;
166import android.os.StrictMode;
167import android.os.SystemClock;
168import android.os.SystemProperties;
169import android.os.UpdateLock;
170import android.os.UserHandle;
171import android.provider.Settings;
172import android.text.format.DateUtils;
173import android.text.format.Time;
174import android.util.AtomicFile;
175import android.util.EventLog;
176import android.util.Log;
177import android.util.Pair;
178import android.util.PrintWriterPrinter;
179import android.util.Slog;
180import android.util.SparseArray;
181import android.util.TimeUtils;
182import android.util.Xml;
183import android.view.Gravity;
184import android.view.LayoutInflater;
185import android.view.View;
186import android.view.WindowManager;
187
188import java.io.BufferedInputStream;
189import java.io.BufferedOutputStream;
190import java.io.DataInputStream;
191import java.io.DataOutputStream;
192import java.io.File;
193import java.io.FileDescriptor;
194import java.io.FileInputStream;
195import java.io.FileNotFoundException;
196import java.io.FileOutputStream;
197import java.io.IOException;
198import java.io.InputStreamReader;
199import java.io.PrintWriter;
200import java.io.StringWriter;
201import java.lang.ref.WeakReference;
202import java.util.ArrayList;
203import java.util.Arrays;
204import java.util.Collections;
205import java.util.Comparator;
206import java.util.HashMap;
207import java.util.HashSet;
208import java.util.Iterator;
209import java.util.List;
210import java.util.Locale;
211import java.util.Map;
212import java.util.Set;
213import java.util.concurrent.atomic.AtomicBoolean;
214import java.util.concurrent.atomic.AtomicLong;
215
216public final class ActivityManagerService extends ActivityManagerNative
217        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
218    private static final String USER_DATA_DIR = "/data/user/";
219    static final String TAG = "ActivityManager";
220    static final String TAG_MU = "ActivityManagerServiceMU";
221    static final boolean DEBUG = false;
222    static final boolean localLOGV = DEBUG;
223    static final boolean DEBUG_BACKUP = localLOGV || false;
224    static final boolean DEBUG_BROADCAST = localLOGV || false;
225    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
226    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
227    static final boolean DEBUG_CLEANUP = localLOGV || false;
228    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
229    static final boolean DEBUG_FOCUS = false;
230    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
231    static final boolean DEBUG_MU = localLOGV || false;
232    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
233    static final boolean DEBUG_LRU = localLOGV || false;
234    static final boolean DEBUG_PAUSE = localLOGV || false;
235    static final boolean DEBUG_POWER = localLOGV || false;
236    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
237    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
238    static final boolean DEBUG_PROCESSES = localLOGV || false;
239    static final boolean DEBUG_PROVIDER = localLOGV || false;
240    static final boolean DEBUG_RESULTS = localLOGV || false;
241    static final boolean DEBUG_SERVICE = localLOGV || false;
242    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
243    static final boolean DEBUG_STACK = localLOGV || false;
244    static final boolean DEBUG_SWITCH = localLOGV || false;
245    static final boolean DEBUG_TASKS = localLOGV || false;
246    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
247    static final boolean DEBUG_TRANSITION = localLOGV || false;
248    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
249    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
250    static final boolean DEBUG_VISBILITY = localLOGV || false;
251    static final boolean DEBUG_PSS = localLOGV || false;
252    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
253    static final boolean VALIDATE_TOKENS = false;
254    static final boolean SHOW_ACTIVITY_START_TIME = true;
255
256    // Control over CPU and battery monitoring.
257    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
258    static final boolean MONITOR_CPU_USAGE = true;
259    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
260    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
261    static final boolean MONITOR_THREAD_CPU_USAGE = false;
262
263    // The flags that are set for all calls we make to the package manager.
264    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
265
266    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
267
268    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
269
270    // Maximum number of recent tasks that we can remember.
271    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
272
273    // Amount of time after a call to stopAppSwitches() during which we will
274    // prevent further untrusted switches from happening.
275    static final long APP_SWITCH_DELAY_TIME = 5*1000;
276
277    // How long we wait for a launched process to attach to the activity manager
278    // before we decide it's never going to come up for real.
279    static final int PROC_START_TIMEOUT = 10*1000;
280
281    // How long we wait for a launched process to attach to the activity manager
282    // before we decide it's never going to come up for real, when the process was
283    // started with a wrapper for instrumentation (such as Valgrind) because it
284    // could take much longer than usual.
285    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
286
287    // How long to wait after going idle before forcing apps to GC.
288    static final int GC_TIMEOUT = 5*1000;
289
290    // The minimum amount of time between successive GC requests for a process.
291    static final int GC_MIN_INTERVAL = 60*1000;
292
293    // The minimum amount of time between successive PSS requests for a process.
294    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
295
296    // The minimum amount of time between successive PSS requests for a process
297    // when the request is due to the memory state being lowered.
298    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
299
300    // The rate at which we check for apps using excessive power -- 15 mins.
301    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
302
303    // The minimum sample duration we will allow before deciding we have
304    // enough data on wake locks to start killing things.
305    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
306
307    // The minimum sample duration we will allow before deciding we have
308    // enough data on CPU usage to start killing things.
309    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
310
311    // How long we allow a receiver to run before giving up on it.
312    static final int BROADCAST_FG_TIMEOUT = 10*1000;
313    static final int BROADCAST_BG_TIMEOUT = 60*1000;
314
315    // How long we wait until we timeout on key dispatching.
316    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
317
318    // How long we wait until we timeout on key dispatching during instrumentation.
319    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
320
321    // Amount of time we wait for observers to handle a user switch before
322    // giving up on them and unfreezing the screen.
323    static final int USER_SWITCH_TIMEOUT = 2*1000;
324
325    // Maximum number of users we allow to be running at a time.
326    static final int MAX_RUNNING_USERS = 3;
327
328    // How long to wait in getAssistContextExtras for the activity and foreground services
329    // to respond with the result.
330    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
331
332    // Maximum number of persisted Uri grants a package is allowed
333    static final int MAX_PERSISTED_URI_GRANTS = 128;
334
335    static final int MY_PID = Process.myPid();
336
337    static final String[] EMPTY_STRING_ARRAY = new String[0];
338
339    // How many bytes to write into the dropbox log before truncating
340    static final int DROPBOX_MAX_SIZE = 256 * 1024;
341
342    /** All system services */
343    SystemServiceManager mSystemServiceManager;
344
345    /** Run all ActivityStacks through this */
346    ActivityStackSupervisor mStackSupervisor;
347
348    public IntentFirewall mIntentFirewall;
349
350    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
351    // default actuion automatically.  Important for devices without direct input
352    // devices.
353    private boolean mShowDialogs = true;
354
355    /**
356     * Description of a request to start a new activity, which has been held
357     * due to app switches being disabled.
358     */
359    static class PendingActivityLaunch {
360        final ActivityRecord r;
361        final ActivityRecord sourceRecord;
362        final int startFlags;
363        final ActivityStack stack;
364
365        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
366                int _startFlags, ActivityStack _stack) {
367            r = _r;
368            sourceRecord = _sourceRecord;
369            startFlags = _startFlags;
370            stack = _stack;
371        }
372    }
373
374    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
375            = new ArrayList<PendingActivityLaunch>();
376
377    BroadcastQueue mFgBroadcastQueue;
378    BroadcastQueue mBgBroadcastQueue;
379    // Convenient for easy iteration over the queues. Foreground is first
380    // so that dispatch of foreground broadcasts gets precedence.
381    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
382
383    BroadcastQueue broadcastQueueForIntent(Intent intent) {
384        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
385        if (DEBUG_BACKGROUND_BROADCAST) {
386            Slog.i(TAG, "Broadcast intent " + intent + " on "
387                    + (isFg ? "foreground" : "background")
388                    + " queue");
389        }
390        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
391    }
392
393    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
394        for (BroadcastQueue queue : mBroadcastQueues) {
395            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
396            if (r != null) {
397                return r;
398            }
399        }
400        return null;
401    }
402
403    /**
404     * Activity we have told the window manager to have key focus.
405     */
406    ActivityRecord mFocusedActivity = null;
407
408    /**
409     * List of intents that were used to start the most recent tasks.
410     */
411    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * This is the process holding what we currently consider to be
572     * the "home" activity.
573     */
574    ProcessRecord mHomeProcess;
575
576    /**
577     * This is the process holding the activity the user last visited that
578     * is in a different process from the one they are currently in.
579     */
580    ProcessRecord mPreviousProcess;
581
582    /**
583     * The time at which the previous process was last visible.
584     */
585    long mPreviousProcessVisibleTime;
586
587    /**
588     * Which uses have been started, so are allowed to run code.
589     */
590    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
591
592    /**
593     * LRU list of history of current users.  Most recently current is at the end.
594     */
595    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
596
597    /**
598     * Constant array of the users that are currently started.
599     */
600    int[] mStartedUserArray = new int[] { 0 };
601
602    /**
603     * Registered observers of the user switching mechanics.
604     */
605    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
606            = new RemoteCallbackList<IUserSwitchObserver>();
607
608    /**
609     * Currently active user switch.
610     */
611    Object mCurUserSwitchCallback;
612
613    /**
614     * Packages that the user has asked to have run in screen size
615     * compatibility mode instead of filling the screen.
616     */
617    final CompatModePackages mCompatModePackages;
618
619    /**
620     * Set of IntentSenderRecord objects that are currently active.
621     */
622    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
623            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
624
625    /**
626     * Fingerprints (hashCode()) of stack traces that we've
627     * already logged DropBox entries for.  Guarded by itself.  If
628     * something (rogue user app) forces this over
629     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
630     */
631    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
632    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
633
634    /**
635     * Strict Mode background batched logging state.
636     *
637     * The string buffer is guarded by itself, and its lock is also
638     * used to determine if another batched write is already
639     * in-flight.
640     */
641    private final StringBuilder mStrictModeBuffer = new StringBuilder();
642
643    /**
644     * Keeps track of all IIntentReceivers that have been registered for
645     * broadcasts.  Hash keys are the receiver IBinder, hash value is
646     * a ReceiverList.
647     */
648    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
649            new HashMap<IBinder, ReceiverList>();
650
651    /**
652     * Resolver for broadcast intents to registered receivers.
653     * Holds BroadcastFilter (subclass of IntentFilter).
654     */
655    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
656            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
657        @Override
658        protected boolean allowFilterResult(
659                BroadcastFilter filter, List<BroadcastFilter> dest) {
660            IBinder target = filter.receiverList.receiver.asBinder();
661            for (int i=dest.size()-1; i>=0; i--) {
662                if (dest.get(i).receiverList.receiver.asBinder() == target) {
663                    return false;
664                }
665            }
666            return true;
667        }
668
669        @Override
670        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
671            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
672                    || userId == filter.owningUserId) {
673                return super.newResult(filter, match, userId);
674            }
675            return null;
676        }
677
678        @Override
679        protected BroadcastFilter[] newArray(int size) {
680            return new BroadcastFilter[size];
681        }
682
683        @Override
684        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
685            return packageName.equals(filter.packageName);
686        }
687    };
688
689    /**
690     * State of all active sticky broadcasts per user.  Keys are the action of the
691     * sticky Intent, values are an ArrayList of all broadcasted intents with
692     * that action (which should usually be one).  The SparseArray is keyed
693     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
694     * for stickies that are sent to all users.
695     */
696    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
697            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
698
699    final ActiveServices mServices;
700
701    /**
702     * Backup/restore process management
703     */
704    String mBackupAppName = null;
705    BackupRecord mBackupTarget = null;
706
707    final ProviderMap mProviderMap;
708
709    /**
710     * List of content providers who have clients waiting for them.  The
711     * application is currently being launched and the provider will be
712     * removed from this list once it is published.
713     */
714    final ArrayList<ContentProviderRecord> mLaunchingProviders
715            = new ArrayList<ContentProviderRecord>();
716
717    /**
718     * File storing persisted {@link #mGrantedUriPermissions}.
719     */
720    private final AtomicFile mGrantFile;
721
722    /** XML constants used in {@link #mGrantFile} */
723    private static final String TAG_URI_GRANTS = "uri-grants";
724    private static final String TAG_URI_GRANT = "uri-grant";
725    private static final String ATTR_USER_HANDLE = "userHandle";
726    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
727    private static final String ATTR_TARGET_USER_ID = "targetUserId";
728    private static final String ATTR_SOURCE_PKG = "sourcePkg";
729    private static final String ATTR_TARGET_PKG = "targetPkg";
730    private static final String ATTR_URI = "uri";
731    private static final String ATTR_MODE_FLAGS = "modeFlags";
732    private static final String ATTR_CREATED_TIME = "createdTime";
733    private static final String ATTR_PREFIX = "prefix";
734
735    /**
736     * Global set of specific {@link Uri} permissions that have been granted.
737     * This optimized lookup structure maps from {@link UriPermission#targetUid}
738     * to {@link UriPermission#uri} to {@link UriPermission}.
739     */
740    @GuardedBy("this")
741    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
742            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
743
744    public static class GrantUri {
745        public final int sourceUserId;
746        public final Uri uri;
747        public boolean prefix;
748
749        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
750            this.sourceUserId = sourceUserId;
751            this.uri = uri;
752            this.prefix = prefix;
753        }
754
755        @Override
756        public int hashCode() {
757            return toString().hashCode();
758        }
759
760        @Override
761        public boolean equals(Object o) {
762            if (o instanceof GrantUri) {
763                GrantUri other = (GrantUri) o;
764                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
765                        && prefix == other.prefix;
766            }
767            return false;
768        }
769
770        @Override
771        public String toString() {
772            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
773            if (prefix) result += " [prefix]";
774            return result;
775        }
776
777        public String toSafeString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
784            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
785                    ContentProvider.getUriWithoutUserId(uri), false);
786        }
787    }
788
789    CoreSettingsObserver mCoreSettingsObserver;
790
791    /**
792     * Thread-local storage used to carry caller permissions over through
793     * indirect content-provider access.
794     */
795    private class Identity {
796        public int pid;
797        public int uid;
798
799        Identity(int _pid, int _uid) {
800            pid = _pid;
801            uid = _uid;
802        }
803    }
804
805    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
806
807    /**
808     * All information we have collected about the runtime performance of
809     * any user id that can impact battery performance.
810     */
811    final BatteryStatsService mBatteryStatsService;
812
813    /**
814     * Information about component usage
815     */
816    final UsageStatsService mUsageStatsService;
817
818    /**
819     * Information about and control over application operations
820     */
821    final AppOpsService mAppOpsService;
822
823    /**
824     * Current configuration information.  HistoryRecord objects are given
825     * a reference to this object to indicate which configuration they are
826     * currently running in, so this object must be kept immutable.
827     */
828    Configuration mConfiguration = new Configuration();
829
830    /**
831     * Current sequencing integer of the configuration, for skipping old
832     * configurations.
833     */
834    int mConfigurationSeq = 0;
835
836    /**
837     * Hardware-reported OpenGLES version.
838     */
839    final int GL_ES_VERSION;
840
841    /**
842     * List of initialization arguments to pass to all processes when binding applications to them.
843     * For example, references to the commonly used services.
844     */
845    HashMap<String, IBinder> mAppBindArgs;
846
847    /**
848     * Temporary to avoid allocations.  Protected by main lock.
849     */
850    final StringBuilder mStringBuilder = new StringBuilder(256);
851
852    /**
853     * Used to control how we initialize the service.
854     */
855    ComponentName mTopComponent;
856    String mTopAction = Intent.ACTION_MAIN;
857    String mTopData;
858    boolean mProcessesReady = false;
859    boolean mSystemReady = false;
860    boolean mBooting = false;
861    boolean mWaitingUpdate = false;
862    boolean mDidUpdate = false;
863    boolean mOnBattery = false;
864    boolean mLaunchWarningShown = false;
865
866    Context mContext;
867
868    int mFactoryTest;
869
870    boolean mCheckedForSetup;
871
872    /**
873     * The time at which we will allow normal application switches again,
874     * after a call to {@link #stopAppSwitches()}.
875     */
876    long mAppSwitchesAllowedTime;
877
878    /**
879     * This is set to true after the first switch after mAppSwitchesAllowedTime
880     * is set; any switches after that will clear the time.
881     */
882    boolean mDidAppSwitch;
883
884    /**
885     * Last time (in realtime) at which we checked for power usage.
886     */
887    long mLastPowerCheckRealtime;
888
889    /**
890     * Last time (in uptime) at which we checked for power usage.
891     */
892    long mLastPowerCheckUptime;
893
894    /**
895     * Set while we are wanting to sleep, to prevent any
896     * activities from being started/resumed.
897     */
898    private boolean mSleeping = false;
899
900    /**
901     * Set while we are running a voice interaction.  This overrides
902     * sleeping while it is active.
903     */
904    private boolean mRunningVoice = false;
905
906    /**
907     * State of external calls telling us if the device is asleep.
908     */
909    private boolean mWentToSleep = false;
910
911    /**
912     * State of external call telling us if the lock screen is shown.
913     */
914    private boolean mLockScreenShown = false;
915
916    /**
917     * Set if we are shutting down the system, similar to sleeping.
918     */
919    boolean mShuttingDown = false;
920
921    /**
922     * Current sequence id for oom_adj computation traversal.
923     */
924    int mAdjSeq = 0;
925
926    /**
927     * Current sequence id for process LRU updating.
928     */
929    int mLruSeq = 0;
930
931    /**
932     * Keep track of the non-cached/empty process we last found, to help
933     * determine how to distribute cached/empty processes next time.
934     */
935    int mNumNonCachedProcs = 0;
936
937    /**
938     * Keep track of the number of cached hidden procs, to balance oom adj
939     * distribution between those and empty procs.
940     */
941    int mNumCachedHiddenProcs = 0;
942
943    /**
944     * Keep track of the number of service processes we last found, to
945     * determine on the next iteration which should be B services.
946     */
947    int mNumServiceProcs = 0;
948    int mNewNumAServiceProcs = 0;
949    int mNewNumServiceProcs = 0;
950
951    /**
952     * Allow the current computed overall memory level of the system to go down?
953     * This is set to false when we are killing processes for reasons other than
954     * memory management, so that the now smaller process list will not be taken as
955     * an indication that memory is tighter.
956     */
957    boolean mAllowLowerMemLevel = false;
958
959    /**
960     * The last computed memory level, for holding when we are in a state that
961     * processes are going away for other reasons.
962     */
963    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
964
965    /**
966     * The last total number of process we have, to determine if changes actually look
967     * like a shrinking number of process due to lower RAM.
968     */
969    int mLastNumProcesses;
970
971    /**
972     * The uptime of the last time we performed idle maintenance.
973     */
974    long mLastIdleTime = SystemClock.uptimeMillis();
975
976    /**
977     * Total time spent with RAM that has been added in the past since the last idle time.
978     */
979    long mLowRamTimeSinceLastIdle = 0;
980
981    /**
982     * If RAM is currently low, when that horrible situation started.
983     */
984    long mLowRamStartTime = 0;
985
986    /**
987     * For reporting to battery stats the current top application.
988     */
989    private String mCurResumedPackage = null;
990    private int mCurResumedUid = -1;
991
992    /**
993     * For reporting to battery stats the apps currently running foreground
994     * service.  The ProcessMap is package/uid tuples; each of these contain
995     * an array of the currently foreground processes.
996     */
997    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
998            = new ProcessMap<ArrayList<ProcessRecord>>();
999
1000    /**
1001     * This is set if we had to do a delayed dexopt of an app before launching
1002     * it, to increase the ANR timeouts in that case.
1003     */
1004    boolean mDidDexOpt;
1005
1006    /**
1007     * Set if the systemServer made a call to enterSafeMode.
1008     */
1009    boolean mSafeMode;
1010
1011    String mDebugApp = null;
1012    boolean mWaitForDebugger = false;
1013    boolean mDebugTransient = false;
1014    String mOrigDebugApp = null;
1015    boolean mOrigWaitForDebugger = false;
1016    boolean mAlwaysFinishActivities = false;
1017    IActivityController mController = null;
1018    String mProfileApp = null;
1019    ProcessRecord mProfileProc = null;
1020    String mProfileFile;
1021    ParcelFileDescriptor mProfileFd;
1022    int mProfileType = 0;
1023    boolean mAutoStopProfiler = false;
1024    String mOpenGlTraceApp = null;
1025
1026    static class ProcessChangeItem {
1027        static final int CHANGE_ACTIVITIES = 1<<0;
1028        static final int CHANGE_PROCESS_STATE = 1<<1;
1029        int changes;
1030        int uid;
1031        int pid;
1032        int processState;
1033        boolean foregroundActivities;
1034    }
1035
1036    final RemoteCallbackList<IProcessObserver> mProcessObservers
1037            = new RemoteCallbackList<IProcessObserver>();
1038    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1039
1040    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1041            = new ArrayList<ProcessChangeItem>();
1042    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1043            = new ArrayList<ProcessChangeItem>();
1044
1045    /**
1046     * Runtime CPU use collection thread.  This object's lock is used to
1047     * protect all related state.
1048     */
1049    final Thread mProcessCpuThread;
1050
1051    /**
1052     * Used to collect process stats when showing not responding dialog.
1053     * Protected by mProcessCpuThread.
1054     */
1055    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1056            MONITOR_THREAD_CPU_USAGE);
1057    final AtomicLong mLastCpuTime = new AtomicLong(0);
1058    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1059
1060    long mLastWriteTime = 0;
1061
1062    /**
1063     * Used to retain an update lock when the foreground activity is in
1064     * immersive mode.
1065     */
1066    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1067
1068    /**
1069     * Set to true after the system has finished booting.
1070     */
1071    boolean mBooted = false;
1072
1073    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1074    int mProcessLimitOverride = -1;
1075
1076    WindowManagerService mWindowManager;
1077
1078    final ActivityThread mSystemThread;
1079
1080    int mCurrentUserId = 0;
1081    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1082    private UserManagerService mUserManager;
1083
1084    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1085        final ProcessRecord mApp;
1086        final int mPid;
1087        final IApplicationThread mAppThread;
1088
1089        AppDeathRecipient(ProcessRecord app, int pid,
1090                IApplicationThread thread) {
1091            if (localLOGV) Slog.v(
1092                TAG, "New death recipient " + this
1093                + " for thread " + thread.asBinder());
1094            mApp = app;
1095            mPid = pid;
1096            mAppThread = thread;
1097        }
1098
1099        @Override
1100        public void binderDied() {
1101            if (localLOGV) Slog.v(
1102                TAG, "Death received in " + this
1103                + " for thread " + mAppThread.asBinder());
1104            synchronized(ActivityManagerService.this) {
1105                appDiedLocked(mApp, mPid, mAppThread);
1106            }
1107        }
1108    }
1109
1110    static final int SHOW_ERROR_MSG = 1;
1111    static final int SHOW_NOT_RESPONDING_MSG = 2;
1112    static final int SHOW_FACTORY_ERROR_MSG = 3;
1113    static final int UPDATE_CONFIGURATION_MSG = 4;
1114    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1115    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1116    static final int SERVICE_TIMEOUT_MSG = 12;
1117    static final int UPDATE_TIME_ZONE = 13;
1118    static final int SHOW_UID_ERROR_MSG = 14;
1119    static final int IM_FEELING_LUCKY_MSG = 15;
1120    static final int PROC_START_TIMEOUT_MSG = 20;
1121    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1122    static final int KILL_APPLICATION_MSG = 22;
1123    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1124    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1125    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1126    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1127    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1128    static final int CLEAR_DNS_CACHE_MSG = 28;
1129    static final int UPDATE_HTTP_PROXY_MSG = 29;
1130    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1131    static final int DISPATCH_PROCESSES_CHANGED = 31;
1132    static final int DISPATCH_PROCESS_DIED = 32;
1133    static final int REPORT_MEM_USAGE_MSG = 33;
1134    static final int REPORT_USER_SWITCH_MSG = 34;
1135    static final int CONTINUE_USER_SWITCH_MSG = 35;
1136    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1137    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1138    static final int PERSIST_URI_GRANTS_MSG = 38;
1139    static final int REQUEST_ALL_PSS_MSG = 39;
1140    static final int START_PROFILES_MSG = 40;
1141    static final int UPDATE_TIME = 41;
1142    static final int SYSTEM_USER_START_MSG = 42;
1143    static final int SYSTEM_USER_CURRENT_MSG = 43;
1144
1145    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1146    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1147    static final int FIRST_COMPAT_MODE_MSG = 300;
1148    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1149
1150    AlertDialog mUidAlert;
1151    CompatModeDialog mCompatModeDialog;
1152    long mLastMemUsageReportTime = 0;
1153
1154    /**
1155     * Flag whether the current user is a "monkey", i.e. whether
1156     * the UI is driven by a UI automation tool.
1157     */
1158    private boolean mUserIsMonkey;
1159
1160    final ServiceThread mHandlerThread;
1161    final MainHandler mHandler;
1162
1163    final class MainHandler extends Handler {
1164        public MainHandler(Looper looper) {
1165            super(looper, null, true);
1166        }
1167
1168        @Override
1169        public void handleMessage(Message msg) {
1170            switch (msg.what) {
1171            case SHOW_ERROR_MSG: {
1172                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1173                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1174                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1175                synchronized (ActivityManagerService.this) {
1176                    ProcessRecord proc = (ProcessRecord)data.get("app");
1177                    AppErrorResult res = (AppErrorResult) data.get("result");
1178                    if (proc != null && proc.crashDialog != null) {
1179                        Slog.e(TAG, "App already has crash dialog: " + proc);
1180                        if (res != null) {
1181                            res.set(0);
1182                        }
1183                        return;
1184                    }
1185                    if (!showBackground && UserHandle.getAppId(proc.uid)
1186                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1187                            && proc.pid != MY_PID) {
1188                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1189                        if (res != null) {
1190                            res.set(0);
1191                        }
1192                        return;
1193                    }
1194                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1195                        Dialog d = new AppErrorDialog(mContext,
1196                                ActivityManagerService.this, res, proc);
1197                        d.show();
1198                        proc.crashDialog = d;
1199                    } else {
1200                        // The device is asleep, so just pretend that the user
1201                        // saw a crash dialog and hit "force quit".
1202                        if (res != null) {
1203                            res.set(0);
1204                        }
1205                    }
1206                }
1207
1208                ensureBootCompleted();
1209            } break;
1210            case SHOW_NOT_RESPONDING_MSG: {
1211                synchronized (ActivityManagerService.this) {
1212                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1213                    ProcessRecord proc = (ProcessRecord)data.get("app");
1214                    if (proc != null && proc.anrDialog != null) {
1215                        Slog.e(TAG, "App already has anr dialog: " + proc);
1216                        return;
1217                    }
1218
1219                    Intent intent = new Intent("android.intent.action.ANR");
1220                    if (!mProcessesReady) {
1221                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1222                                | Intent.FLAG_RECEIVER_FOREGROUND);
1223                    }
1224                    broadcastIntentLocked(null, null, intent,
1225                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1226                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1227
1228                    if (mShowDialogs) {
1229                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1230                                mContext, proc, (ActivityRecord)data.get("activity"),
1231                                msg.arg1 != 0);
1232                        d.show();
1233                        proc.anrDialog = d;
1234                    } else {
1235                        // Just kill the app if there is no dialog to be shown.
1236                        killAppAtUsersRequest(proc, null);
1237                    }
1238                }
1239
1240                ensureBootCompleted();
1241            } break;
1242            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1243                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1244                synchronized (ActivityManagerService.this) {
1245                    ProcessRecord proc = (ProcessRecord) data.get("app");
1246                    if (proc == null) {
1247                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1248                        break;
1249                    }
1250                    if (proc.crashDialog != null) {
1251                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1252                        return;
1253                    }
1254                    AppErrorResult res = (AppErrorResult) data.get("result");
1255                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1256                        Dialog d = new StrictModeViolationDialog(mContext,
1257                                ActivityManagerService.this, res, proc);
1258                        d.show();
1259                        proc.crashDialog = d;
1260                    } else {
1261                        // The device is asleep, so just pretend that the user
1262                        // saw a crash dialog and hit "force quit".
1263                        res.set(0);
1264                    }
1265                }
1266                ensureBootCompleted();
1267            } break;
1268            case SHOW_FACTORY_ERROR_MSG: {
1269                Dialog d = new FactoryErrorDialog(
1270                    mContext, msg.getData().getCharSequence("msg"));
1271                d.show();
1272                ensureBootCompleted();
1273            } break;
1274            case UPDATE_CONFIGURATION_MSG: {
1275                final ContentResolver resolver = mContext.getContentResolver();
1276                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1277            } break;
1278            case GC_BACKGROUND_PROCESSES_MSG: {
1279                synchronized (ActivityManagerService.this) {
1280                    performAppGcsIfAppropriateLocked();
1281                }
1282            } break;
1283            case WAIT_FOR_DEBUGGER_MSG: {
1284                synchronized (ActivityManagerService.this) {
1285                    ProcessRecord app = (ProcessRecord)msg.obj;
1286                    if (msg.arg1 != 0) {
1287                        if (!app.waitedForDebugger) {
1288                            Dialog d = new AppWaitingForDebuggerDialog(
1289                                    ActivityManagerService.this,
1290                                    mContext, app);
1291                            app.waitDialog = d;
1292                            app.waitedForDebugger = true;
1293                            d.show();
1294                        }
1295                    } else {
1296                        if (app.waitDialog != null) {
1297                            app.waitDialog.dismiss();
1298                            app.waitDialog = null;
1299                        }
1300                    }
1301                }
1302            } break;
1303            case SERVICE_TIMEOUT_MSG: {
1304                if (mDidDexOpt) {
1305                    mDidDexOpt = false;
1306                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1307                    nmsg.obj = msg.obj;
1308                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1309                    return;
1310                }
1311                mServices.serviceTimeout((ProcessRecord)msg.obj);
1312            } break;
1313            case UPDATE_TIME_ZONE: {
1314                synchronized (ActivityManagerService.this) {
1315                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1316                        ProcessRecord r = mLruProcesses.get(i);
1317                        if (r.thread != null) {
1318                            try {
1319                                r.thread.updateTimeZone();
1320                            } catch (RemoteException ex) {
1321                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1322                            }
1323                        }
1324                    }
1325                }
1326            } break;
1327            case CLEAR_DNS_CACHE_MSG: {
1328                synchronized (ActivityManagerService.this) {
1329                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1330                        ProcessRecord r = mLruProcesses.get(i);
1331                        if (r.thread != null) {
1332                            try {
1333                                r.thread.clearDnsCache();
1334                            } catch (RemoteException ex) {
1335                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1336                            }
1337                        }
1338                    }
1339                }
1340            } break;
1341            case UPDATE_HTTP_PROXY_MSG: {
1342                ProxyInfo proxy = (ProxyInfo)msg.obj;
1343                String host = "";
1344                String port = "";
1345                String exclList = "";
1346                Uri pacFileUrl = Uri.EMPTY;
1347                if (proxy != null) {
1348                    host = proxy.getHost();
1349                    port = Integer.toString(proxy.getPort());
1350                    exclList = proxy.getExclusionListAsString();
1351                    pacFileUrl = proxy.getPacFileUrl();
1352                }
1353                synchronized (ActivityManagerService.this) {
1354                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1355                        ProcessRecord r = mLruProcesses.get(i);
1356                        if (r.thread != null) {
1357                            try {
1358                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1359                            } catch (RemoteException ex) {
1360                                Slog.w(TAG, "Failed to update http proxy for: " +
1361                                        r.info.processName);
1362                            }
1363                        }
1364                    }
1365                }
1366            } break;
1367            case SHOW_UID_ERROR_MSG: {
1368                String title = "System UIDs Inconsistent";
1369                String text = "UIDs on the system are inconsistent, you need to wipe your"
1370                        + " data partition or your device will be unstable.";
1371                Log.e(TAG, title + ": " + text);
1372                if (mShowDialogs) {
1373                    // XXX This is a temporary dialog, no need to localize.
1374                    AlertDialog d = new BaseErrorDialog(mContext);
1375                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1376                    d.setCancelable(false);
1377                    d.setTitle(title);
1378                    d.setMessage(text);
1379                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1380                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1381                    mUidAlert = d;
1382                    d.show();
1383                }
1384            } break;
1385            case IM_FEELING_LUCKY_MSG: {
1386                if (mUidAlert != null) {
1387                    mUidAlert.dismiss();
1388                    mUidAlert = null;
1389                }
1390            } break;
1391            case PROC_START_TIMEOUT_MSG: {
1392                if (mDidDexOpt) {
1393                    mDidDexOpt = false;
1394                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1395                    nmsg.obj = msg.obj;
1396                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1397                    return;
1398                }
1399                ProcessRecord app = (ProcessRecord)msg.obj;
1400                synchronized (ActivityManagerService.this) {
1401                    processStartTimedOutLocked(app);
1402                }
1403            } break;
1404            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1405                synchronized (ActivityManagerService.this) {
1406                    doPendingActivityLaunchesLocked(true);
1407                }
1408            } break;
1409            case KILL_APPLICATION_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    int appid = msg.arg1;
1412                    boolean restart = (msg.arg2 == 1);
1413                    Bundle bundle = (Bundle)msg.obj;
1414                    String pkg = bundle.getString("pkg");
1415                    String reason = bundle.getString("reason");
1416                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1417                            false, UserHandle.USER_ALL, reason);
1418                }
1419            } break;
1420            case FINALIZE_PENDING_INTENT_MSG: {
1421                ((PendingIntentRecord)msg.obj).completeFinalize();
1422            } break;
1423            case POST_HEAVY_NOTIFICATION_MSG: {
1424                INotificationManager inm = NotificationManager.getService();
1425                if (inm == null) {
1426                    return;
1427                }
1428
1429                ActivityRecord root = (ActivityRecord)msg.obj;
1430                ProcessRecord process = root.app;
1431                if (process == null) {
1432                    return;
1433                }
1434
1435                try {
1436                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1437                    String text = mContext.getString(R.string.heavy_weight_notification,
1438                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1439                    Notification notification = new Notification();
1440                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1441                    notification.when = 0;
1442                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1443                    notification.tickerText = text;
1444                    notification.defaults = 0; // please be quiet
1445                    notification.sound = null;
1446                    notification.vibrate = null;
1447                    notification.setLatestEventInfo(context, text,
1448                            mContext.getText(R.string.heavy_weight_notification_detail),
1449                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1450                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1451                                    new UserHandle(root.userId)));
1452
1453                    try {
1454                        int[] outId = new int[1];
1455                        inm.enqueueNotificationWithTag("android", "android", null,
1456                                R.string.heavy_weight_notification,
1457                                notification, outId, root.userId);
1458                    } catch (RuntimeException e) {
1459                        Slog.w(ActivityManagerService.TAG,
1460                                "Error showing notification for heavy-weight app", e);
1461                    } catch (RemoteException e) {
1462                    }
1463                } catch (NameNotFoundException e) {
1464                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1465                }
1466            } break;
1467            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1468                INotificationManager inm = NotificationManager.getService();
1469                if (inm == null) {
1470                    return;
1471                }
1472                try {
1473                    inm.cancelNotificationWithTag("android", null,
1474                            R.string.heavy_weight_notification,  msg.arg1);
1475                } catch (RuntimeException e) {
1476                    Slog.w(ActivityManagerService.TAG,
1477                            "Error canceling notification for service", e);
1478                } catch (RemoteException e) {
1479                }
1480            } break;
1481            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1482                synchronized (ActivityManagerService.this) {
1483                    checkExcessivePowerUsageLocked(true);
1484                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1485                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1486                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1487                }
1488            } break;
1489            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1490                synchronized (ActivityManagerService.this) {
1491                    ActivityRecord ar = (ActivityRecord)msg.obj;
1492                    if (mCompatModeDialog != null) {
1493                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1494                                ar.info.applicationInfo.packageName)) {
1495                            return;
1496                        }
1497                        mCompatModeDialog.dismiss();
1498                        mCompatModeDialog = null;
1499                    }
1500                    if (ar != null && false) {
1501                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1502                                ar.packageName)) {
1503                            int mode = mCompatModePackages.computeCompatModeLocked(
1504                                    ar.info.applicationInfo);
1505                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1506                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1507                                mCompatModeDialog = new CompatModeDialog(
1508                                        ActivityManagerService.this, mContext,
1509                                        ar.info.applicationInfo);
1510                                mCompatModeDialog.show();
1511                            }
1512                        }
1513                    }
1514                }
1515                break;
1516            }
1517            case DISPATCH_PROCESSES_CHANGED: {
1518                dispatchProcessesChanged();
1519                break;
1520            }
1521            case DISPATCH_PROCESS_DIED: {
1522                final int pid = msg.arg1;
1523                final int uid = msg.arg2;
1524                dispatchProcessDied(pid, uid);
1525                break;
1526            }
1527            case REPORT_MEM_USAGE_MSG: {
1528                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1529                Thread thread = new Thread() {
1530                    @Override public void run() {
1531                        final SparseArray<ProcessMemInfo> infoMap
1532                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1533                        for (int i=0, N=memInfos.size(); i<N; i++) {
1534                            ProcessMemInfo mi = memInfos.get(i);
1535                            infoMap.put(mi.pid, mi);
1536                        }
1537                        updateCpuStatsNow();
1538                        synchronized (mProcessCpuThread) {
1539                            final int N = mProcessCpuTracker.countStats();
1540                            for (int i=0; i<N; i++) {
1541                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1542                                if (st.vsize > 0) {
1543                                    long pss = Debug.getPss(st.pid, null);
1544                                    if (pss > 0) {
1545                                        if (infoMap.indexOfKey(st.pid) < 0) {
1546                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1547                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1548                                            mi.pss = pss;
1549                                            memInfos.add(mi);
1550                                        }
1551                                    }
1552                                }
1553                            }
1554                        }
1555
1556                        long totalPss = 0;
1557                        for (int i=0, N=memInfos.size(); i<N; i++) {
1558                            ProcessMemInfo mi = memInfos.get(i);
1559                            if (mi.pss == 0) {
1560                                mi.pss = Debug.getPss(mi.pid, null);
1561                            }
1562                            totalPss += mi.pss;
1563                        }
1564                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1565                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1566                                if (lhs.oomAdj != rhs.oomAdj) {
1567                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1568                                }
1569                                if (lhs.pss != rhs.pss) {
1570                                    return lhs.pss < rhs.pss ? 1 : -1;
1571                                }
1572                                return 0;
1573                            }
1574                        });
1575
1576                        StringBuilder tag = new StringBuilder(128);
1577                        StringBuilder stack = new StringBuilder(128);
1578                        tag.append("Low on memory -- ");
1579                        appendMemBucket(tag, totalPss, "total", false);
1580                        appendMemBucket(stack, totalPss, "total", true);
1581
1582                        StringBuilder logBuilder = new StringBuilder(1024);
1583                        logBuilder.append("Low on memory:\n");
1584
1585                        boolean firstLine = true;
1586                        int lastOomAdj = Integer.MIN_VALUE;
1587                        for (int i=0, N=memInfos.size(); i<N; i++) {
1588                            ProcessMemInfo mi = memInfos.get(i);
1589
1590                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1591                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1592                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1593                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1594                                if (lastOomAdj != mi.oomAdj) {
1595                                    lastOomAdj = mi.oomAdj;
1596                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1597                                        tag.append(" / ");
1598                                    }
1599                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1600                                        if (firstLine) {
1601                                            stack.append(":");
1602                                            firstLine = false;
1603                                        }
1604                                        stack.append("\n\t at ");
1605                                    } else {
1606                                        stack.append("$");
1607                                    }
1608                                } else {
1609                                    tag.append(" ");
1610                                    stack.append("$");
1611                                }
1612                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1613                                    appendMemBucket(tag, mi.pss, mi.name, false);
1614                                }
1615                                appendMemBucket(stack, mi.pss, mi.name, true);
1616                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1617                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1618                                    stack.append("(");
1619                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1620                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1621                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1622                                            stack.append(":");
1623                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1624                                        }
1625                                    }
1626                                    stack.append(")");
1627                                }
1628                            }
1629
1630                            logBuilder.append("  ");
1631                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1632                            logBuilder.append(' ');
1633                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1634                            logBuilder.append(' ');
1635                            ProcessList.appendRamKb(logBuilder, mi.pss);
1636                            logBuilder.append(" kB: ");
1637                            logBuilder.append(mi.name);
1638                            logBuilder.append(" (");
1639                            logBuilder.append(mi.pid);
1640                            logBuilder.append(") ");
1641                            logBuilder.append(mi.adjType);
1642                            logBuilder.append('\n');
1643                            if (mi.adjReason != null) {
1644                                logBuilder.append("                      ");
1645                                logBuilder.append(mi.adjReason);
1646                                logBuilder.append('\n');
1647                            }
1648                        }
1649
1650                        logBuilder.append("           ");
1651                        ProcessList.appendRamKb(logBuilder, totalPss);
1652                        logBuilder.append(" kB: TOTAL\n");
1653
1654                        long[] infos = new long[Debug.MEMINFO_COUNT];
1655                        Debug.getMemInfo(infos);
1656                        logBuilder.append("  MemInfo: ");
1657                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1658                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1659                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1660                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1661                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1662                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1663                            logBuilder.append("  ZRAM: ");
1664                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1665                            logBuilder.append(" kB RAM, ");
1666                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1667                            logBuilder.append(" kB swap total, ");
1668                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1669                            logBuilder.append(" kB swap free\n");
1670                        }
1671                        Slog.i(TAG, logBuilder.toString());
1672
1673                        StringBuilder dropBuilder = new StringBuilder(1024);
1674                        /*
1675                        StringWriter oomSw = new StringWriter();
1676                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1677                        StringWriter catSw = new StringWriter();
1678                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1679                        String[] emptyArgs = new String[] { };
1680                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1681                        oomPw.flush();
1682                        String oomString = oomSw.toString();
1683                        */
1684                        dropBuilder.append(stack);
1685                        dropBuilder.append('\n');
1686                        dropBuilder.append('\n');
1687                        dropBuilder.append(logBuilder);
1688                        dropBuilder.append('\n');
1689                        /*
1690                        dropBuilder.append(oomString);
1691                        dropBuilder.append('\n');
1692                        */
1693                        StringWriter catSw = new StringWriter();
1694                        synchronized (ActivityManagerService.this) {
1695                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1696                            String[] emptyArgs = new String[] { };
1697                            catPw.println();
1698                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1699                            catPw.println();
1700                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1701                                    false, false, null);
1702                            catPw.println();
1703                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1704                            catPw.flush();
1705                        }
1706                        dropBuilder.append(catSw.toString());
1707                        addErrorToDropBox("lowmem", null, "system_server", null,
1708                                null, tag.toString(), dropBuilder.toString(), null, null);
1709                        //Slog.i(TAG, "Sent to dropbox:");
1710                        //Slog.i(TAG, dropBuilder.toString());
1711                        synchronized (ActivityManagerService.this) {
1712                            long now = SystemClock.uptimeMillis();
1713                            if (mLastMemUsageReportTime < now) {
1714                                mLastMemUsageReportTime = now;
1715                            }
1716                        }
1717                    }
1718                };
1719                thread.start();
1720                break;
1721            }
1722            case REPORT_USER_SWITCH_MSG: {
1723                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1724                break;
1725            }
1726            case CONTINUE_USER_SWITCH_MSG: {
1727                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1728                break;
1729            }
1730            case USER_SWITCH_TIMEOUT_MSG: {
1731                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1732                break;
1733            }
1734            case IMMERSIVE_MODE_LOCK_MSG: {
1735                final boolean nextState = (msg.arg1 != 0);
1736                if (mUpdateLock.isHeld() != nextState) {
1737                    if (DEBUG_IMMERSIVE) {
1738                        final ActivityRecord r = (ActivityRecord) msg.obj;
1739                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1740                    }
1741                    if (nextState) {
1742                        mUpdateLock.acquire();
1743                    } else {
1744                        mUpdateLock.release();
1745                    }
1746                }
1747                break;
1748            }
1749            case PERSIST_URI_GRANTS_MSG: {
1750                writeGrantedUriPermissions();
1751                break;
1752            }
1753            case REQUEST_ALL_PSS_MSG: {
1754                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1755                break;
1756            }
1757            case START_PROFILES_MSG: {
1758                synchronized (ActivityManagerService.this) {
1759                    startProfilesLocked();
1760                }
1761                break;
1762            }
1763            case UPDATE_TIME: {
1764                synchronized (ActivityManagerService.this) {
1765                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1766                        ProcessRecord r = mLruProcesses.get(i);
1767                        if (r.thread != null) {
1768                            try {
1769                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1770                            } catch (RemoteException ex) {
1771                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1772                            }
1773                        }
1774                    }
1775                }
1776                break;
1777            }
1778            case SYSTEM_USER_START_MSG: {
1779                mSystemServiceManager.startUser(msg.arg1);
1780                break;
1781            }
1782            case SYSTEM_USER_CURRENT_MSG: {
1783                mSystemServiceManager.switchUser(msg.arg1);
1784                break;
1785            }
1786            }
1787        }
1788    };
1789
1790    static final int COLLECT_PSS_BG_MSG = 1;
1791
1792    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1793        @Override
1794        public void handleMessage(Message msg) {
1795            switch (msg.what) {
1796            case COLLECT_PSS_BG_MSG: {
1797                int i=0, num=0;
1798                long start = SystemClock.uptimeMillis();
1799                long[] tmp = new long[1];
1800                do {
1801                    ProcessRecord proc;
1802                    int procState;
1803                    int pid;
1804                    synchronized (ActivityManagerService.this) {
1805                        if (i >= mPendingPssProcesses.size()) {
1806                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1807                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1808                            mPendingPssProcesses.clear();
1809                            return;
1810                        }
1811                        proc = mPendingPssProcesses.get(i);
1812                        procState = proc.pssProcState;
1813                        if (proc.thread != null && procState == proc.setProcState) {
1814                            pid = proc.pid;
1815                        } else {
1816                            proc = null;
1817                            pid = 0;
1818                        }
1819                        i++;
1820                    }
1821                    if (proc != null) {
1822                        long pss = Debug.getPss(pid, tmp);
1823                        synchronized (ActivityManagerService.this) {
1824                            if (proc.thread != null && proc.setProcState == procState
1825                                    && proc.pid == pid) {
1826                                num++;
1827                                proc.lastPssTime = SystemClock.uptimeMillis();
1828                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1829                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1830                                        + ": " + pss + " lastPss=" + proc.lastPss
1831                                        + " state=" + ProcessList.makeProcStateString(procState));
1832                                if (proc.initialIdlePss == 0) {
1833                                    proc.initialIdlePss = pss;
1834                                }
1835                                proc.lastPss = pss;
1836                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1837                                    proc.lastCachedPss = pss;
1838                                }
1839                            }
1840                        }
1841                    }
1842                } while (true);
1843            }
1844            }
1845        }
1846    };
1847
1848    /**
1849     * Monitor for package changes and update our internal state.
1850     */
1851    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1852        @Override
1853        public void onPackageRemoved(String packageName, int uid) {
1854            // Remove all tasks with activities in the specified package from the list of recent tasks
1855            synchronized (ActivityManagerService.this) {
1856                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1857                    TaskRecord tr = mRecentTasks.get(i);
1858                    ComponentName cn = tr.intent.getComponent();
1859                    if (cn != null && cn.getPackageName().equals(packageName)) {
1860                        // If the package name matches, remove the task and kill the process
1861                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1862                    }
1863                }
1864            }
1865        }
1866
1867        @Override
1868        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1869            onPackageModified(packageName);
1870            return true;
1871        }
1872
1873        @Override
1874        public void onPackageModified(String packageName) {
1875            final PackageManager pm = mContext.getPackageManager();
1876            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1877                    new ArrayList<Pair<Intent, Integer>>();
1878            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1879            // Copy the list of recent tasks so that we don't hold onto the lock on
1880            // ActivityManagerService for long periods while checking if components exist.
1881            synchronized (ActivityManagerService.this) {
1882                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1883                    TaskRecord tr = mRecentTasks.get(i);
1884                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1885                }
1886            }
1887            // Check the recent tasks and filter out all tasks with components that no longer exist.
1888            Intent tmpI = new Intent();
1889            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1890                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1891                ComponentName cn = p.first.getComponent();
1892                if (cn != null && cn.getPackageName().equals(packageName)) {
1893                    try {
1894                        // Add the task to the list to remove if the component no longer exists
1895                        tmpI.setComponent(cn);
1896                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1897                            tasksToRemove.add(p.second);
1898                        }
1899                    } catch (Exception e) {}
1900                }
1901            }
1902            // Prune all the tasks with removed components from the list of recent tasks
1903            synchronized (ActivityManagerService.this) {
1904                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1905                    // Remove the task but don't kill the process (since other components in that
1906                    // package may still be running and in the background)
1907                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1908                }
1909            }
1910        }
1911
1912        @Override
1913        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1914            // Force stop the specified packages
1915            if (packages != null) {
1916                for (String pkg : packages) {
1917                    synchronized (ActivityManagerService.this) {
1918                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1919                                "finished booting")) {
1920                            return true;
1921                        }
1922                    }
1923                }
1924            }
1925            return false;
1926        }
1927    };
1928
1929    public void setSystemProcess() {
1930        try {
1931            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1932            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1933            ServiceManager.addService("meminfo", new MemBinder(this));
1934            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1935            ServiceManager.addService("dbinfo", new DbBinder(this));
1936            if (MONITOR_CPU_USAGE) {
1937                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1938            }
1939            ServiceManager.addService("permission", new PermissionController(this));
1940
1941            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1942                    "android", STOCK_PM_FLAGS);
1943            mSystemThread.installSystemApplicationInfo(info);
1944
1945            synchronized (this) {
1946                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1947                app.persistent = true;
1948                app.pid = MY_PID;
1949                app.maxAdj = ProcessList.SYSTEM_ADJ;
1950                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1951                mProcessNames.put(app.processName, app.uid, app);
1952                synchronized (mPidsSelfLocked) {
1953                    mPidsSelfLocked.put(app.pid, app);
1954                }
1955                updateLruProcessLocked(app, false, null);
1956                updateOomAdjLocked();
1957            }
1958        } catch (PackageManager.NameNotFoundException e) {
1959            throw new RuntimeException(
1960                    "Unable to find android system package", e);
1961        }
1962    }
1963
1964    public void setWindowManager(WindowManagerService wm) {
1965        mWindowManager = wm;
1966        mStackSupervisor.setWindowManager(wm);
1967    }
1968
1969    public void startObservingNativeCrashes() {
1970        final NativeCrashListener ncl = new NativeCrashListener(this);
1971        ncl.start();
1972    }
1973
1974    public IAppOpsService getAppOpsService() {
1975        return mAppOpsService;
1976    }
1977
1978    static class MemBinder extends Binder {
1979        ActivityManagerService mActivityManagerService;
1980        MemBinder(ActivityManagerService activityManagerService) {
1981            mActivityManagerService = activityManagerService;
1982        }
1983
1984        @Override
1985        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1986            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1987                    != PackageManager.PERMISSION_GRANTED) {
1988                pw.println("Permission Denial: can't dump meminfo from from pid="
1989                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1990                        + " without permission " + android.Manifest.permission.DUMP);
1991                return;
1992            }
1993
1994            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1995        }
1996    }
1997
1998    static class GraphicsBinder extends Binder {
1999        ActivityManagerService mActivityManagerService;
2000        GraphicsBinder(ActivityManagerService activityManagerService) {
2001            mActivityManagerService = activityManagerService;
2002        }
2003
2004        @Override
2005        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2006            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2007                    != PackageManager.PERMISSION_GRANTED) {
2008                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2009                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2010                        + " without permission " + android.Manifest.permission.DUMP);
2011                return;
2012            }
2013
2014            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2015        }
2016    }
2017
2018    static class DbBinder extends Binder {
2019        ActivityManagerService mActivityManagerService;
2020        DbBinder(ActivityManagerService activityManagerService) {
2021            mActivityManagerService = activityManagerService;
2022        }
2023
2024        @Override
2025        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2026            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2027                    != PackageManager.PERMISSION_GRANTED) {
2028                pw.println("Permission Denial: can't dump dbinfo from from pid="
2029                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2030                        + " without permission " + android.Manifest.permission.DUMP);
2031                return;
2032            }
2033
2034            mActivityManagerService.dumpDbInfo(fd, pw, args);
2035        }
2036    }
2037
2038    static class CpuBinder extends Binder {
2039        ActivityManagerService mActivityManagerService;
2040        CpuBinder(ActivityManagerService activityManagerService) {
2041            mActivityManagerService = activityManagerService;
2042        }
2043
2044        @Override
2045        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2046            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2047                    != PackageManager.PERMISSION_GRANTED) {
2048                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2049                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2050                        + " without permission " + android.Manifest.permission.DUMP);
2051                return;
2052            }
2053
2054            synchronized (mActivityManagerService.mProcessCpuThread) {
2055                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2056                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2057                        SystemClock.uptimeMillis()));
2058            }
2059        }
2060    }
2061
2062    public static final class Lifecycle extends SystemService {
2063        private final ActivityManagerService mService;
2064
2065        public Lifecycle(Context context) {
2066            super(context);
2067            mService = new ActivityManagerService(context);
2068        }
2069
2070        @Override
2071        public void onStart() {
2072            mService.start();
2073        }
2074
2075        public ActivityManagerService getService() {
2076            return mService;
2077        }
2078    }
2079
2080    // Note: This method is invoked on the main thread but may need to attach various
2081    // handlers to other threads.  So take care to be explicit about the looper.
2082    public ActivityManagerService(Context systemContext) {
2083        mContext = systemContext;
2084        mFactoryTest = FactoryTest.getMode();
2085        mSystemThread = ActivityThread.currentActivityThread();
2086
2087        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2088
2089        mHandlerThread = new ServiceThread(TAG,
2090                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2091        mHandlerThread.start();
2092        mHandler = new MainHandler(mHandlerThread.getLooper());
2093
2094        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2095                "foreground", BROADCAST_FG_TIMEOUT, false);
2096        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2097                "background", BROADCAST_BG_TIMEOUT, true);
2098        mBroadcastQueues[0] = mFgBroadcastQueue;
2099        mBroadcastQueues[1] = mBgBroadcastQueue;
2100
2101        mServices = new ActiveServices(this);
2102        mProviderMap = new ProviderMap(this);
2103
2104        // TODO: Move creation of battery stats service outside of activity manager service.
2105        File dataDir = Environment.getDataDirectory();
2106        File systemDir = new File(dataDir, "system");
2107        systemDir.mkdirs();
2108        mBatteryStatsService = new BatteryStatsService(new File(
2109                systemDir, "batterystats.bin").toString(), mHandler);
2110        mBatteryStatsService.getActiveStatistics().readLocked();
2111        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2112        mOnBattery = DEBUG_POWER ? true
2113                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2114        mBatteryStatsService.getActiveStatistics().setCallback(this);
2115
2116        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2117
2118        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2119        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2120
2121        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2122
2123        // User 0 is the first and only user that runs at boot.
2124        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2125        mUserLru.add(Integer.valueOf(0));
2126        updateStartedUserArrayLocked();
2127
2128        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2129            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2130
2131        mConfiguration.setToDefaults();
2132        mConfiguration.setLocale(Locale.getDefault());
2133
2134        mConfigurationSeq = mConfiguration.seq = 1;
2135        mProcessCpuTracker.init();
2136
2137        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2138        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2139        mStackSupervisor = new ActivityStackSupervisor(this);
2140
2141        mProcessCpuThread = new Thread("CpuTracker") {
2142            @Override
2143            public void run() {
2144                while (true) {
2145                    try {
2146                        try {
2147                            synchronized(this) {
2148                                final long now = SystemClock.uptimeMillis();
2149                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2150                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2151                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2152                                //        + ", write delay=" + nextWriteDelay);
2153                                if (nextWriteDelay < nextCpuDelay) {
2154                                    nextCpuDelay = nextWriteDelay;
2155                                }
2156                                if (nextCpuDelay > 0) {
2157                                    mProcessCpuMutexFree.set(true);
2158                                    this.wait(nextCpuDelay);
2159                                }
2160                            }
2161                        } catch (InterruptedException e) {
2162                        }
2163                        updateCpuStatsNow();
2164                    } catch (Exception e) {
2165                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2166                    }
2167                }
2168            }
2169        };
2170
2171        Watchdog.getInstance().addMonitor(this);
2172        Watchdog.getInstance().addThread(mHandler);
2173    }
2174
2175    public void setSystemServiceManager(SystemServiceManager mgr) {
2176        mSystemServiceManager = mgr;
2177    }
2178
2179    private void start() {
2180        mProcessCpuThread.start();
2181
2182        mBatteryStatsService.publish(mContext);
2183        mUsageStatsService.publish(mContext);
2184        mAppOpsService.publish(mContext);
2185
2186        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2187    }
2188
2189    @Override
2190    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2191            throws RemoteException {
2192        if (code == SYSPROPS_TRANSACTION) {
2193            // We need to tell all apps about the system property change.
2194            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2195            synchronized(this) {
2196                final int NP = mProcessNames.getMap().size();
2197                for (int ip=0; ip<NP; ip++) {
2198                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2199                    final int NA = apps.size();
2200                    for (int ia=0; ia<NA; ia++) {
2201                        ProcessRecord app = apps.valueAt(ia);
2202                        if (app.thread != null) {
2203                            procs.add(app.thread.asBinder());
2204                        }
2205                    }
2206                }
2207            }
2208
2209            int N = procs.size();
2210            for (int i=0; i<N; i++) {
2211                Parcel data2 = Parcel.obtain();
2212                try {
2213                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2214                } catch (RemoteException e) {
2215                }
2216                data2.recycle();
2217            }
2218        }
2219        try {
2220            return super.onTransact(code, data, reply, flags);
2221        } catch (RuntimeException e) {
2222            // The activity manager only throws security exceptions, so let's
2223            // log all others.
2224            if (!(e instanceof SecurityException)) {
2225                Slog.wtf(TAG, "Activity Manager Crash", e);
2226            }
2227            throw e;
2228        }
2229    }
2230
2231    void updateCpuStats() {
2232        final long now = SystemClock.uptimeMillis();
2233        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2234            return;
2235        }
2236        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2237            synchronized (mProcessCpuThread) {
2238                mProcessCpuThread.notify();
2239            }
2240        }
2241    }
2242
2243    void updateCpuStatsNow() {
2244        synchronized (mProcessCpuThread) {
2245            mProcessCpuMutexFree.set(false);
2246            final long now = SystemClock.uptimeMillis();
2247            boolean haveNewCpuStats = false;
2248
2249            if (MONITOR_CPU_USAGE &&
2250                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2251                mLastCpuTime.set(now);
2252                haveNewCpuStats = true;
2253                mProcessCpuTracker.update();
2254                //Slog.i(TAG, mProcessCpu.printCurrentState());
2255                //Slog.i(TAG, "Total CPU usage: "
2256                //        + mProcessCpu.getTotalCpuPercent() + "%");
2257
2258                // Slog the cpu usage if the property is set.
2259                if ("true".equals(SystemProperties.get("events.cpu"))) {
2260                    int user = mProcessCpuTracker.getLastUserTime();
2261                    int system = mProcessCpuTracker.getLastSystemTime();
2262                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2263                    int irq = mProcessCpuTracker.getLastIrqTime();
2264                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2265                    int idle = mProcessCpuTracker.getLastIdleTime();
2266
2267                    int total = user + system + iowait + irq + softIrq + idle;
2268                    if (total == 0) total = 1;
2269
2270                    EventLog.writeEvent(EventLogTags.CPU,
2271                            ((user+system+iowait+irq+softIrq) * 100) / total,
2272                            (user * 100) / total,
2273                            (system * 100) / total,
2274                            (iowait * 100) / total,
2275                            (irq * 100) / total,
2276                            (softIrq * 100) / total);
2277                }
2278            }
2279
2280            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2281            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2282            synchronized(bstats) {
2283                synchronized(mPidsSelfLocked) {
2284                    if (haveNewCpuStats) {
2285                        if (mOnBattery) {
2286                            int perc = bstats.startAddingCpuLocked();
2287                            int totalUTime = 0;
2288                            int totalSTime = 0;
2289                            final int N = mProcessCpuTracker.countStats();
2290                            for (int i=0; i<N; i++) {
2291                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2292                                if (!st.working) {
2293                                    continue;
2294                                }
2295                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2296                                int otherUTime = (st.rel_utime*perc)/100;
2297                                int otherSTime = (st.rel_stime*perc)/100;
2298                                totalUTime += otherUTime;
2299                                totalSTime += otherSTime;
2300                                if (pr != null) {
2301                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2302                                    if (ps == null || !ps.isActive()) {
2303                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2304                                                pr.info.uid, pr.processName);
2305                                    }
2306                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2307                                            st.rel_stime-otherSTime);
2308                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2309                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2310                                } else {
2311                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2312                                    if (ps == null || !ps.isActive()) {
2313                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2314                                                bstats.mapUid(st.uid), st.name);
2315                                    }
2316                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2317                                            st.rel_stime-otherSTime);
2318                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2319                                }
2320                            }
2321                            bstats.finishAddingCpuLocked(perc, totalUTime,
2322                                    totalSTime, cpuSpeedTimes);
2323                        }
2324                    }
2325                }
2326
2327                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2328                    mLastWriteTime = now;
2329                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2330                }
2331            }
2332        }
2333    }
2334
2335    @Override
2336    public void batteryNeedsCpuUpdate() {
2337        updateCpuStatsNow();
2338    }
2339
2340    @Override
2341    public void batteryPowerChanged(boolean onBattery) {
2342        // When plugging in, update the CPU stats first before changing
2343        // the plug state.
2344        updateCpuStatsNow();
2345        synchronized (this) {
2346            synchronized(mPidsSelfLocked) {
2347                mOnBattery = DEBUG_POWER ? true : onBattery;
2348            }
2349        }
2350    }
2351
2352    /**
2353     * Initialize the application bind args. These are passed to each
2354     * process when the bindApplication() IPC is sent to the process. They're
2355     * lazily setup to make sure the services are running when they're asked for.
2356     */
2357    private HashMap<String, IBinder> getCommonServicesLocked() {
2358        if (mAppBindArgs == null) {
2359            mAppBindArgs = new HashMap<String, IBinder>();
2360
2361            // Setup the application init args
2362            mAppBindArgs.put("package", ServiceManager.getService("package"));
2363            mAppBindArgs.put("window", ServiceManager.getService("window"));
2364            mAppBindArgs.put(Context.ALARM_SERVICE,
2365                    ServiceManager.getService(Context.ALARM_SERVICE));
2366        }
2367        return mAppBindArgs;
2368    }
2369
2370    final void setFocusedActivityLocked(ActivityRecord r) {
2371        if (mFocusedActivity != r) {
2372            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2373            mFocusedActivity = r;
2374            if (r.task != null && r.task.voiceInteractor != null) {
2375                startRunningVoiceLocked();
2376            } else {
2377                finishRunningVoiceLocked();
2378            }
2379            mStackSupervisor.setFocusedStack(r);
2380            if (r != null) {
2381                mWindowManager.setFocusedApp(r.appToken, true);
2382            }
2383            applyUpdateLockStateLocked(r);
2384        }
2385    }
2386
2387    final void clearFocusedActivity(ActivityRecord r) {
2388        if (mFocusedActivity == r) {
2389            mFocusedActivity = null;
2390        }
2391    }
2392
2393    @Override
2394    public void setFocusedStack(int stackId) {
2395        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2396        synchronized (ActivityManagerService.this) {
2397            ActivityStack stack = mStackSupervisor.getStack(stackId);
2398            if (stack != null) {
2399                ActivityRecord r = stack.topRunningActivityLocked(null);
2400                if (r != null) {
2401                    setFocusedActivityLocked(r);
2402                }
2403            }
2404        }
2405    }
2406
2407    @Override
2408    public void notifyActivityDrawn(IBinder token) {
2409        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2410        synchronized (this) {
2411            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2412            if (r != null) {
2413                r.task.stack.notifyActivityDrawnLocked(r);
2414            }
2415        }
2416    }
2417
2418    final void applyUpdateLockStateLocked(ActivityRecord r) {
2419        // Modifications to the UpdateLock state are done on our handler, outside
2420        // the activity manager's locks.  The new state is determined based on the
2421        // state *now* of the relevant activity record.  The object is passed to
2422        // the handler solely for logging detail, not to be consulted/modified.
2423        final boolean nextState = r != null && r.immersive;
2424        mHandler.sendMessage(
2425                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2426    }
2427
2428    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2429        Message msg = Message.obtain();
2430        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2431        msg.obj = r.task.askedCompatMode ? null : r;
2432        mHandler.sendMessage(msg);
2433    }
2434
2435    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2436            String what, Object obj, ProcessRecord srcApp) {
2437        app.lastActivityTime = now;
2438
2439        if (app.activities.size() > 0) {
2440            // Don't want to touch dependent processes that are hosting activities.
2441            return index;
2442        }
2443
2444        int lrui = mLruProcesses.lastIndexOf(app);
2445        if (lrui < 0) {
2446            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2447                    + what + " " + obj + " from " + srcApp);
2448            return index;
2449        }
2450
2451        if (lrui >= index) {
2452            // Don't want to cause this to move dependent processes *back* in the
2453            // list as if they were less frequently used.
2454            return index;
2455        }
2456
2457        if (lrui >= mLruProcessActivityStart) {
2458            // Don't want to touch dependent processes that are hosting activities.
2459            return index;
2460        }
2461
2462        mLruProcesses.remove(lrui);
2463        if (index > 0) {
2464            index--;
2465        }
2466        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2467                + " in LRU list: " + app);
2468        mLruProcesses.add(index, app);
2469        return index;
2470    }
2471
2472    final void removeLruProcessLocked(ProcessRecord app) {
2473        int lrui = mLruProcesses.lastIndexOf(app);
2474        if (lrui >= 0) {
2475            if (lrui <= mLruProcessActivityStart) {
2476                mLruProcessActivityStart--;
2477            }
2478            if (lrui <= mLruProcessServiceStart) {
2479                mLruProcessServiceStart--;
2480            }
2481            mLruProcesses.remove(lrui);
2482        }
2483    }
2484
2485    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2486            ProcessRecord client) {
2487        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2488                || app.treatLikeActivity;
2489        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2490        if (!activityChange && hasActivity) {
2491            // The process has activities, so we are only allowing activity-based adjustments
2492            // to move it.  It should be kept in the front of the list with other
2493            // processes that have activities, and we don't want those to change their
2494            // order except due to activity operations.
2495            return;
2496        }
2497
2498        mLruSeq++;
2499        final long now = SystemClock.uptimeMillis();
2500        app.lastActivityTime = now;
2501
2502        // First a quick reject: if the app is already at the position we will
2503        // put it, then there is nothing to do.
2504        if (hasActivity) {
2505            final int N = mLruProcesses.size();
2506            if (N > 0 && mLruProcesses.get(N-1) == app) {
2507                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2508                return;
2509            }
2510        } else {
2511            if (mLruProcessServiceStart > 0
2512                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2513                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2514                return;
2515            }
2516        }
2517
2518        int lrui = mLruProcesses.lastIndexOf(app);
2519
2520        if (app.persistent && lrui >= 0) {
2521            // We don't care about the position of persistent processes, as long as
2522            // they are in the list.
2523            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2524            return;
2525        }
2526
2527        /* In progress: compute new position first, so we can avoid doing work
2528           if the process is not actually going to move.  Not yet working.
2529        int addIndex;
2530        int nextIndex;
2531        boolean inActivity = false, inService = false;
2532        if (hasActivity) {
2533            // Process has activities, put it at the very tipsy-top.
2534            addIndex = mLruProcesses.size();
2535            nextIndex = mLruProcessServiceStart;
2536            inActivity = true;
2537        } else if (hasService) {
2538            // Process has services, put it at the top of the service list.
2539            addIndex = mLruProcessActivityStart;
2540            nextIndex = mLruProcessServiceStart;
2541            inActivity = true;
2542            inService = true;
2543        } else  {
2544            // Process not otherwise of interest, it goes to the top of the non-service area.
2545            addIndex = mLruProcessServiceStart;
2546            if (client != null) {
2547                int clientIndex = mLruProcesses.lastIndexOf(client);
2548                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2549                        + app);
2550                if (clientIndex >= 0 && addIndex > clientIndex) {
2551                    addIndex = clientIndex;
2552                }
2553            }
2554            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2555        }
2556
2557        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2558                + mLruProcessActivityStart + "): " + app);
2559        */
2560
2561        if (lrui >= 0) {
2562            if (lrui < mLruProcessActivityStart) {
2563                mLruProcessActivityStart--;
2564            }
2565            if (lrui < mLruProcessServiceStart) {
2566                mLruProcessServiceStart--;
2567            }
2568            /*
2569            if (addIndex > lrui) {
2570                addIndex--;
2571            }
2572            if (nextIndex > lrui) {
2573                nextIndex--;
2574            }
2575            */
2576            mLruProcesses.remove(lrui);
2577        }
2578
2579        /*
2580        mLruProcesses.add(addIndex, app);
2581        if (inActivity) {
2582            mLruProcessActivityStart++;
2583        }
2584        if (inService) {
2585            mLruProcessActivityStart++;
2586        }
2587        */
2588
2589        int nextIndex;
2590        if (hasActivity) {
2591            final int N = mLruProcesses.size();
2592            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2593                // Process doesn't have activities, but has clients with
2594                // activities...  move it up, but one below the top (the top
2595                // should always have a real activity).
2596                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2597                mLruProcesses.add(N-1, app);
2598                // To keep it from spamming the LRU list (by making a bunch of clients),
2599                // we will push down any other entries owned by the app.
2600                final int uid = app.info.uid;
2601                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2602                    ProcessRecord subProc = mLruProcesses.get(i);
2603                    if (subProc.info.uid == uid) {
2604                        // We want to push this one down the list.  If the process after
2605                        // it is for the same uid, however, don't do so, because we don't
2606                        // want them internally to be re-ordered.
2607                        if (mLruProcesses.get(i-1).info.uid != uid) {
2608                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2609                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2610                            ProcessRecord tmp = mLruProcesses.get(i);
2611                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2612                            mLruProcesses.set(i-1, tmp);
2613                            i--;
2614                        }
2615                    } else {
2616                        // A gap, we can stop here.
2617                        break;
2618                    }
2619                }
2620            } else {
2621                // Process has activities, put it at the very tipsy-top.
2622                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2623                mLruProcesses.add(app);
2624            }
2625            nextIndex = mLruProcessServiceStart;
2626        } else if (hasService) {
2627            // Process has services, put it at the top of the service list.
2628            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2629            mLruProcesses.add(mLruProcessActivityStart, app);
2630            nextIndex = mLruProcessServiceStart;
2631            mLruProcessActivityStart++;
2632        } else  {
2633            // Process not otherwise of interest, it goes to the top of the non-service area.
2634            int index = mLruProcessServiceStart;
2635            if (client != null) {
2636                // If there is a client, don't allow the process to be moved up higher
2637                // in the list than that client.
2638                int clientIndex = mLruProcesses.lastIndexOf(client);
2639                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2640                        + " when updating " + app);
2641                if (clientIndex <= lrui) {
2642                    // Don't allow the client index restriction to push it down farther in the
2643                    // list than it already is.
2644                    clientIndex = lrui;
2645                }
2646                if (clientIndex >= 0 && index > clientIndex) {
2647                    index = clientIndex;
2648                }
2649            }
2650            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2651            mLruProcesses.add(index, app);
2652            nextIndex = index-1;
2653            mLruProcessActivityStart++;
2654            mLruProcessServiceStart++;
2655        }
2656
2657        // If the app is currently using a content provider or service,
2658        // bump those processes as well.
2659        for (int j=app.connections.size()-1; j>=0; j--) {
2660            ConnectionRecord cr = app.connections.valueAt(j);
2661            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2662                    && cr.binding.service.app != null
2663                    && cr.binding.service.app.lruSeq != mLruSeq
2664                    && !cr.binding.service.app.persistent) {
2665                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2666                        "service connection", cr, app);
2667            }
2668        }
2669        for (int j=app.conProviders.size()-1; j>=0; j--) {
2670            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2671            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2672                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2673                        "provider reference", cpr, app);
2674            }
2675        }
2676    }
2677
2678    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2679        if (uid == Process.SYSTEM_UID) {
2680            // The system gets to run in any process.  If there are multiple
2681            // processes with the same uid, just pick the first (this
2682            // should never happen).
2683            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2684            if (procs == null) return null;
2685            final int N = procs.size();
2686            for (int i = 0; i < N; i++) {
2687                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2688            }
2689        }
2690        ProcessRecord proc = mProcessNames.get(processName, uid);
2691        if (false && proc != null && !keepIfLarge
2692                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2693                && proc.lastCachedPss >= 4000) {
2694            // Turn this condition on to cause killing to happen regularly, for testing.
2695            if (proc.baseProcessTracker != null) {
2696                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2697            }
2698            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2699                    + "k from cached");
2700        } else if (proc != null && !keepIfLarge
2701                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2702                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2703            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2704            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2705                if (proc.baseProcessTracker != null) {
2706                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2707                }
2708                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2709                        + "k from cached");
2710            }
2711        }
2712        return proc;
2713    }
2714
2715    void ensurePackageDexOpt(String packageName) {
2716        IPackageManager pm = AppGlobals.getPackageManager();
2717        try {
2718            if (pm.performDexOpt(packageName)) {
2719                mDidDexOpt = true;
2720            }
2721        } catch (RemoteException e) {
2722        }
2723    }
2724
2725    boolean isNextTransitionForward() {
2726        int transit = mWindowManager.getPendingAppTransition();
2727        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2728                || transit == AppTransition.TRANSIT_TASK_OPEN
2729                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2730    }
2731
2732    final ProcessRecord startProcessLocked(String processName,
2733            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2734            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2735            boolean isolated, boolean keepIfLarge) {
2736        ProcessRecord app;
2737        if (!isolated) {
2738            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2739        } else {
2740            // If this is an isolated process, it can't re-use an existing process.
2741            app = null;
2742        }
2743        // We don't have to do anything more if:
2744        // (1) There is an existing application record; and
2745        // (2) The caller doesn't think it is dead, OR there is no thread
2746        //     object attached to it so we know it couldn't have crashed; and
2747        // (3) There is a pid assigned to it, so it is either starting or
2748        //     already running.
2749        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2750                + " app=" + app + " knownToBeDead=" + knownToBeDead
2751                + " thread=" + (app != null ? app.thread : null)
2752                + " pid=" + (app != null ? app.pid : -1));
2753        if (app != null && app.pid > 0) {
2754            if (!knownToBeDead || app.thread == null) {
2755                // We already have the app running, or are waiting for it to
2756                // come up (we have a pid but not yet its thread), so keep it.
2757                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2758                // If this is a new package in the process, add the package to the list
2759                app.addPackage(info.packageName, mProcessStats);
2760                return app;
2761            }
2762
2763            // An application record is attached to a previous process,
2764            // clean it up now.
2765            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2766            handleAppDiedLocked(app, true, true);
2767        }
2768
2769        String hostingNameStr = hostingName != null
2770                ? hostingName.flattenToShortString() : null;
2771
2772        if (!isolated) {
2773            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2774                // If we are in the background, then check to see if this process
2775                // is bad.  If so, we will just silently fail.
2776                if (mBadProcesses.get(info.processName, info.uid) != null) {
2777                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2778                            + "/" + info.processName);
2779                    return null;
2780                }
2781            } else {
2782                // When the user is explicitly starting a process, then clear its
2783                // crash count so that we won't make it bad until they see at
2784                // least one crash dialog again, and make the process good again
2785                // if it had been bad.
2786                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2787                        + "/" + info.processName);
2788                mProcessCrashTimes.remove(info.processName, info.uid);
2789                if (mBadProcesses.get(info.processName, info.uid) != null) {
2790                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2791                            UserHandle.getUserId(info.uid), info.uid,
2792                            info.processName);
2793                    mBadProcesses.remove(info.processName, info.uid);
2794                    if (app != null) {
2795                        app.bad = false;
2796                    }
2797                }
2798            }
2799        }
2800
2801        if (app == null) {
2802            app = newProcessRecordLocked(info, processName, isolated);
2803            if (app == null) {
2804                Slog.w(TAG, "Failed making new process record for "
2805                        + processName + "/" + info.uid + " isolated=" + isolated);
2806                return null;
2807            }
2808            mProcessNames.put(processName, app.uid, app);
2809            if (isolated) {
2810                mIsolatedProcesses.put(app.uid, app);
2811            }
2812        } else {
2813            // If this is a new package in the process, add the package to the list
2814            app.addPackage(info.packageName, mProcessStats);
2815        }
2816
2817        // If the system is not ready yet, then hold off on starting this
2818        // process until it is.
2819        if (!mProcessesReady
2820                && !isAllowedWhileBooting(info)
2821                && !allowWhileBooting) {
2822            if (!mProcessesOnHold.contains(app)) {
2823                mProcessesOnHold.add(app);
2824            }
2825            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2826            return app;
2827        }
2828
2829        startProcessLocked(app, hostingType, hostingNameStr);
2830        return (app.pid != 0) ? app : null;
2831    }
2832
2833    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2834        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2835    }
2836
2837    private final void startProcessLocked(ProcessRecord app,
2838            String hostingType, String hostingNameStr) {
2839        if (app.pid > 0 && app.pid != MY_PID) {
2840            synchronized (mPidsSelfLocked) {
2841                mPidsSelfLocked.remove(app.pid);
2842                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2843            }
2844            app.setPid(0);
2845        }
2846
2847        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2848                "startProcessLocked removing on hold: " + app);
2849        mProcessesOnHold.remove(app);
2850
2851        updateCpuStats();
2852
2853        try {
2854            int uid = app.uid;
2855
2856            int[] gids = null;
2857            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2858            if (!app.isolated) {
2859                int[] permGids = null;
2860                try {
2861                    final PackageManager pm = mContext.getPackageManager();
2862                    permGids = pm.getPackageGids(app.info.packageName);
2863
2864                    if (Environment.isExternalStorageEmulated()) {
2865                        if (pm.checkPermission(
2866                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2867                                app.info.packageName) == PERMISSION_GRANTED) {
2868                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2869                        } else {
2870                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2871                        }
2872                    }
2873                } catch (PackageManager.NameNotFoundException e) {
2874                    Slog.w(TAG, "Unable to retrieve gids", e);
2875                }
2876
2877                /*
2878                 * Add shared application GID so applications can share some
2879                 * resources like shared libraries
2880                 */
2881                if (permGids == null) {
2882                    gids = new int[1];
2883                } else {
2884                    gids = new int[permGids.length + 1];
2885                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2886                }
2887                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2888            }
2889            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2890                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2891                        && mTopComponent != null
2892                        && app.processName.equals(mTopComponent.getPackageName())) {
2893                    uid = 0;
2894                }
2895                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2896                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2897                    uid = 0;
2898                }
2899            }
2900            int debugFlags = 0;
2901            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2902                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2903                // Also turn on CheckJNI for debuggable apps. It's quite
2904                // awkward to turn on otherwise.
2905                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2906            }
2907            // Run the app in safe mode if its manifest requests so or the
2908            // system is booted in safe mode.
2909            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2910                mSafeMode == true) {
2911                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2912            }
2913            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2914                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2915            }
2916            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2917                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2918            }
2919            if ("1".equals(SystemProperties.get("debug.assert"))) {
2920                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2921            }
2922
2923            String requiredAbi = app.info.cpuAbi;
2924            if (requiredAbi == null) {
2925                requiredAbi = Build.SUPPORTED_ABIS[0];
2926            }
2927
2928            // Start the process.  It will either succeed and return a result containing
2929            // the PID of the new process, or else throw a RuntimeException.
2930            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2931                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2932                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2933
2934            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2935            synchronized (bs) {
2936                if (bs.isOnBattery()) {
2937                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2938                }
2939            }
2940
2941            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2942                    UserHandle.getUserId(uid), startResult.pid, uid,
2943                    app.processName, hostingType,
2944                    hostingNameStr != null ? hostingNameStr : "");
2945
2946            if (app.persistent) {
2947                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2948            }
2949
2950            StringBuilder buf = mStringBuilder;
2951            buf.setLength(0);
2952            buf.append("Start proc ");
2953            buf.append(app.processName);
2954            buf.append(" for ");
2955            buf.append(hostingType);
2956            if (hostingNameStr != null) {
2957                buf.append(" ");
2958                buf.append(hostingNameStr);
2959            }
2960            buf.append(": pid=");
2961            buf.append(startResult.pid);
2962            buf.append(" uid=");
2963            buf.append(uid);
2964            buf.append(" gids={");
2965            if (gids != null) {
2966                for (int gi=0; gi<gids.length; gi++) {
2967                    if (gi != 0) buf.append(", ");
2968                    buf.append(gids[gi]);
2969
2970                }
2971            }
2972            buf.append("}");
2973            Slog.i(TAG, buf.toString());
2974            app.setPid(startResult.pid);
2975            app.usingWrapper = startResult.usingWrapper;
2976            app.removed = false;
2977            synchronized (mPidsSelfLocked) {
2978                this.mPidsSelfLocked.put(startResult.pid, app);
2979                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2980                msg.obj = app;
2981                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2982                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2983            }
2984            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2985                    app.processName, app.info.uid);
2986            if (app.isolated) {
2987                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2988            }
2989        } catch (RuntimeException e) {
2990            // XXX do better error recovery.
2991            app.setPid(0);
2992            Slog.e(TAG, "Failure starting process " + app.processName, e);
2993        }
2994    }
2995
2996    void updateUsageStats(ActivityRecord component, boolean resumed) {
2997        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2998        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2999        if (resumed) {
3000            mUsageStatsService.noteResumeComponent(component.realActivity);
3001            synchronized (stats) {
3002                stats.noteActivityResumedLocked(component.app.uid);
3003            }
3004        } else {
3005            mUsageStatsService.notePauseComponent(component.realActivity);
3006            synchronized (stats) {
3007                stats.noteActivityPausedLocked(component.app.uid);
3008            }
3009        }
3010    }
3011
3012    Intent getHomeIntent() {
3013        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3014        intent.setComponent(mTopComponent);
3015        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3016            intent.addCategory(Intent.CATEGORY_HOME);
3017        }
3018        return intent;
3019    }
3020
3021    boolean startHomeActivityLocked(int userId) {
3022        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3023                && mTopAction == null) {
3024            // We are running in factory test mode, but unable to find
3025            // the factory test app, so just sit around displaying the
3026            // error message and don't try to start anything.
3027            return false;
3028        }
3029        Intent intent = getHomeIntent();
3030        ActivityInfo aInfo =
3031            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3032        if (aInfo != null) {
3033            intent.setComponent(new ComponentName(
3034                    aInfo.applicationInfo.packageName, aInfo.name));
3035            // Don't do this if the home app is currently being
3036            // instrumented.
3037            aInfo = new ActivityInfo(aInfo);
3038            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3039            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3040                    aInfo.applicationInfo.uid, true);
3041            if (app == null || app.instrumentationClass == null) {
3042                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3043                mStackSupervisor.startHomeActivity(intent, aInfo);
3044            }
3045        }
3046
3047        return true;
3048    }
3049
3050    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3051        ActivityInfo ai = null;
3052        ComponentName comp = intent.getComponent();
3053        try {
3054            if (comp != null) {
3055                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3056            } else {
3057                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3058                        intent,
3059                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3060                            flags, userId);
3061
3062                if (info != null) {
3063                    ai = info.activityInfo;
3064                }
3065            }
3066        } catch (RemoteException e) {
3067            // ignore
3068        }
3069
3070        return ai;
3071    }
3072
3073    /**
3074     * Starts the "new version setup screen" if appropriate.
3075     */
3076    void startSetupActivityLocked() {
3077        // Only do this once per boot.
3078        if (mCheckedForSetup) {
3079            return;
3080        }
3081
3082        // We will show this screen if the current one is a different
3083        // version than the last one shown, and we are not running in
3084        // low-level factory test mode.
3085        final ContentResolver resolver = mContext.getContentResolver();
3086        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3087                Settings.Global.getInt(resolver,
3088                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3089            mCheckedForSetup = true;
3090
3091            // See if we should be showing the platform update setup UI.
3092            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3093            List<ResolveInfo> ris = mContext.getPackageManager()
3094                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3095
3096            // We don't allow third party apps to replace this.
3097            ResolveInfo ri = null;
3098            for (int i=0; ris != null && i<ris.size(); i++) {
3099                if ((ris.get(i).activityInfo.applicationInfo.flags
3100                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3101                    ri = ris.get(i);
3102                    break;
3103                }
3104            }
3105
3106            if (ri != null) {
3107                String vers = ri.activityInfo.metaData != null
3108                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3109                        : null;
3110                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3111                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3112                            Intent.METADATA_SETUP_VERSION);
3113                }
3114                String lastVers = Settings.Secure.getString(
3115                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3116                if (vers != null && !vers.equals(lastVers)) {
3117                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3118                    intent.setComponent(new ComponentName(
3119                            ri.activityInfo.packageName, ri.activityInfo.name));
3120                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3121                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3122                }
3123            }
3124        }
3125    }
3126
3127    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3128        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3129    }
3130
3131    void enforceNotIsolatedCaller(String caller) {
3132        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3133            throw new SecurityException("Isolated process not allowed to call " + caller);
3134        }
3135    }
3136
3137    @Override
3138    public int getFrontActivityScreenCompatMode() {
3139        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3140        synchronized (this) {
3141            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3142        }
3143    }
3144
3145    @Override
3146    public void setFrontActivityScreenCompatMode(int mode) {
3147        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3148                "setFrontActivityScreenCompatMode");
3149        synchronized (this) {
3150            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3151        }
3152    }
3153
3154    @Override
3155    public int getPackageScreenCompatMode(String packageName) {
3156        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3157        synchronized (this) {
3158            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3159        }
3160    }
3161
3162    @Override
3163    public void setPackageScreenCompatMode(String packageName, int mode) {
3164        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3165                "setPackageScreenCompatMode");
3166        synchronized (this) {
3167            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3168        }
3169    }
3170
3171    @Override
3172    public boolean getPackageAskScreenCompat(String packageName) {
3173        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3174        synchronized (this) {
3175            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3176        }
3177    }
3178
3179    @Override
3180    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3181        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3182                "setPackageAskScreenCompat");
3183        synchronized (this) {
3184            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3185        }
3186    }
3187
3188    private void dispatchProcessesChanged() {
3189        int N;
3190        synchronized (this) {
3191            N = mPendingProcessChanges.size();
3192            if (mActiveProcessChanges.length < N) {
3193                mActiveProcessChanges = new ProcessChangeItem[N];
3194            }
3195            mPendingProcessChanges.toArray(mActiveProcessChanges);
3196            mAvailProcessChanges.addAll(mPendingProcessChanges);
3197            mPendingProcessChanges.clear();
3198            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3199        }
3200
3201        int i = mProcessObservers.beginBroadcast();
3202        while (i > 0) {
3203            i--;
3204            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3205            if (observer != null) {
3206                try {
3207                    for (int j=0; j<N; j++) {
3208                        ProcessChangeItem item = mActiveProcessChanges[j];
3209                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3210                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3211                                    + item.pid + " uid=" + item.uid + ": "
3212                                    + item.foregroundActivities);
3213                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3214                                    item.foregroundActivities);
3215                        }
3216                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3217                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3218                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3219                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3220                        }
3221                    }
3222                } catch (RemoteException e) {
3223                }
3224            }
3225        }
3226        mProcessObservers.finishBroadcast();
3227    }
3228
3229    private void dispatchProcessDied(int pid, int uid) {
3230        int i = mProcessObservers.beginBroadcast();
3231        while (i > 0) {
3232            i--;
3233            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3234            if (observer != null) {
3235                try {
3236                    observer.onProcessDied(pid, uid);
3237                } catch (RemoteException e) {
3238                }
3239            }
3240        }
3241        mProcessObservers.finishBroadcast();
3242    }
3243
3244    final void doPendingActivityLaunchesLocked(boolean doResume) {
3245        final int N = mPendingActivityLaunches.size();
3246        if (N <= 0) {
3247            return;
3248        }
3249        for (int i=0; i<N; i++) {
3250            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3251            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3252                    doResume && i == (N-1), null);
3253        }
3254        mPendingActivityLaunches.clear();
3255    }
3256
3257    @Override
3258    public final int startActivity(IApplicationThread caller, String callingPackage,
3259            Intent intent, String resolvedType, IBinder resultTo,
3260            String resultWho, int requestCode, int startFlags,
3261            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3262        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3263                resultWho, requestCode,
3264                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3265    }
3266
3267    @Override
3268    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3269            Intent intent, String resolvedType, IBinder resultTo,
3270            String resultWho, int requestCode, int startFlags,
3271            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3272        enforceNotIsolatedCaller("startActivity");
3273        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3274                false, true, "startActivity", null);
3275        // TODO: Switch to user app stacks here.
3276        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3277                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3278                null, null, options, userId, null);
3279    }
3280
3281    @Override
3282    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3283            Intent intent, String resolvedType, IBinder resultTo,
3284            String resultWho, int requestCode, int startFlags, String profileFile,
3285            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3286        enforceNotIsolatedCaller("startActivityAndWait");
3287        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3288                false, true, "startActivityAndWait", null);
3289        WaitResult res = new WaitResult();
3290        // TODO: Switch to user app stacks here.
3291        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3292                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3293                res, null, options, UserHandle.getCallingUserId(), null);
3294        return res;
3295    }
3296
3297    @Override
3298    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3299            Intent intent, String resolvedType, IBinder resultTo,
3300            String resultWho, int requestCode, int startFlags, Configuration config,
3301            Bundle options, int userId) {
3302        enforceNotIsolatedCaller("startActivityWithConfig");
3303        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3304                false, true, "startActivityWithConfig", null);
3305        // TODO: Switch to user app stacks here.
3306        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3307                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3308                null, null, null, config, options, userId, null);
3309        return ret;
3310    }
3311
3312    @Override
3313    public int startActivityIntentSender(IApplicationThread caller,
3314            IntentSender intent, Intent fillInIntent, String resolvedType,
3315            IBinder resultTo, String resultWho, int requestCode,
3316            int flagsMask, int flagsValues, Bundle options) {
3317        enforceNotIsolatedCaller("startActivityIntentSender");
3318        // Refuse possible leaked file descriptors
3319        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3320            throw new IllegalArgumentException("File descriptors passed in Intent");
3321        }
3322
3323        IIntentSender sender = intent.getTarget();
3324        if (!(sender instanceof PendingIntentRecord)) {
3325            throw new IllegalArgumentException("Bad PendingIntent object");
3326        }
3327
3328        PendingIntentRecord pir = (PendingIntentRecord)sender;
3329
3330        synchronized (this) {
3331            // If this is coming from the currently resumed activity, it is
3332            // effectively saying that app switches are allowed at this point.
3333            final ActivityStack stack = getFocusedStack();
3334            if (stack.mResumedActivity != null &&
3335                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3336                mAppSwitchesAllowedTime = 0;
3337            }
3338        }
3339        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3340                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3341        return ret;
3342    }
3343
3344    @Override
3345    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3346            Intent intent, String resolvedType, IVoiceInteractionSession session,
3347            IVoiceInteractor interactor, int startFlags, String profileFile,
3348            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3349        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3350                != PackageManager.PERMISSION_GRANTED) {
3351            String msg = "Permission Denial: startVoiceActivity() from pid="
3352                    + Binder.getCallingPid()
3353                    + ", uid=" + Binder.getCallingUid()
3354                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3355            Slog.w(TAG, msg);
3356            throw new SecurityException(msg);
3357        }
3358        if (session == null || interactor == null) {
3359            throw new NullPointerException("null session or interactor");
3360        }
3361        userId = handleIncomingUser(callingPid, callingUid, userId,
3362                false, true, "startVoiceActivity", null);
3363        // TODO: Switch to user app stacks here.
3364        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3365                resolvedType, session, interactor, null, null, 0, startFlags,
3366                profileFile, profileFd, null, null, options, userId, null);
3367    }
3368
3369    @Override
3370    public boolean startNextMatchingActivity(IBinder callingActivity,
3371            Intent intent, Bundle options) {
3372        // Refuse possible leaked file descriptors
3373        if (intent != null && intent.hasFileDescriptors() == true) {
3374            throw new IllegalArgumentException("File descriptors passed in Intent");
3375        }
3376
3377        synchronized (this) {
3378            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3379            if (r == null) {
3380                ActivityOptions.abort(options);
3381                return false;
3382            }
3383            if (r.app == null || r.app.thread == null) {
3384                // The caller is not running...  d'oh!
3385                ActivityOptions.abort(options);
3386                return false;
3387            }
3388            intent = new Intent(intent);
3389            // The caller is not allowed to change the data.
3390            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3391            // And we are resetting to find the next component...
3392            intent.setComponent(null);
3393
3394            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3395
3396            ActivityInfo aInfo = null;
3397            try {
3398                List<ResolveInfo> resolves =
3399                    AppGlobals.getPackageManager().queryIntentActivities(
3400                            intent, r.resolvedType,
3401                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3402                            UserHandle.getCallingUserId());
3403
3404                // Look for the original activity in the list...
3405                final int N = resolves != null ? resolves.size() : 0;
3406                for (int i=0; i<N; i++) {
3407                    ResolveInfo rInfo = resolves.get(i);
3408                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3409                            && rInfo.activityInfo.name.equals(r.info.name)) {
3410                        // We found the current one...  the next matching is
3411                        // after it.
3412                        i++;
3413                        if (i<N) {
3414                            aInfo = resolves.get(i).activityInfo;
3415                        }
3416                        if (debug) {
3417                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3418                                    + "/" + r.info.name);
3419                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3420                                    + "/" + aInfo.name);
3421                        }
3422                        break;
3423                    }
3424                }
3425            } catch (RemoteException e) {
3426            }
3427
3428            if (aInfo == null) {
3429                // Nobody who is next!
3430                ActivityOptions.abort(options);
3431                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3432                return false;
3433            }
3434
3435            intent.setComponent(new ComponentName(
3436                    aInfo.applicationInfo.packageName, aInfo.name));
3437            intent.setFlags(intent.getFlags()&~(
3438                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3439                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3440                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3441                    Intent.FLAG_ACTIVITY_NEW_TASK));
3442
3443            // Okay now we need to start the new activity, replacing the
3444            // currently running activity.  This is a little tricky because
3445            // we want to start the new one as if the current one is finished,
3446            // but not finish the current one first so that there is no flicker.
3447            // And thus...
3448            final boolean wasFinishing = r.finishing;
3449            r.finishing = true;
3450
3451            // Propagate reply information over to the new activity.
3452            final ActivityRecord resultTo = r.resultTo;
3453            final String resultWho = r.resultWho;
3454            final int requestCode = r.requestCode;
3455            r.resultTo = null;
3456            if (resultTo != null) {
3457                resultTo.removeResultsLocked(r, resultWho, requestCode);
3458            }
3459
3460            final long origId = Binder.clearCallingIdentity();
3461            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3462                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3463                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3464                    options, false, null, null);
3465            Binder.restoreCallingIdentity(origId);
3466
3467            r.finishing = wasFinishing;
3468            if (res != ActivityManager.START_SUCCESS) {
3469                return false;
3470            }
3471            return true;
3472        }
3473    }
3474
3475    final int startActivityInPackage(int uid, String callingPackage,
3476            Intent intent, String resolvedType, IBinder resultTo,
3477            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3478                    IActivityContainer container) {
3479
3480        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3481                false, true, "startActivityInPackage", null);
3482
3483        // TODO: Switch to user app stacks here.
3484        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3485                null, null, resultTo, resultWho, requestCode, startFlags,
3486                null, null, null, null, options, userId, container);
3487        return ret;
3488    }
3489
3490    @Override
3491    public final int startActivities(IApplicationThread caller, String callingPackage,
3492            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3493            int userId) {
3494        enforceNotIsolatedCaller("startActivities");
3495        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3496                false, true, "startActivity", null);
3497        // TODO: Switch to user app stacks here.
3498        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3499                resolvedTypes, resultTo, options, userId);
3500        return ret;
3501    }
3502
3503    final int startActivitiesInPackage(int uid, String callingPackage,
3504            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3505            Bundle options, int userId) {
3506
3507        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3508                false, true, "startActivityInPackage", null);
3509        // TODO: Switch to user app stacks here.
3510        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3511                resultTo, options, userId);
3512        return ret;
3513    }
3514
3515    final void addRecentTaskLocked(TaskRecord task) {
3516        int N = mRecentTasks.size();
3517        // Quick case: check if the top-most recent task is the same.
3518        if (N > 0 && mRecentTasks.get(0) == task) {
3519            return;
3520        }
3521        // Another quick case: never add voice sessions.
3522        if (task.voiceSession != null) {
3523            return;
3524        }
3525        // Remove any existing entries that are the same kind of task.
3526        final Intent intent = task.intent;
3527        final boolean document = intent != null && intent.isDocument();
3528        for (int i=0; i<N; i++) {
3529            TaskRecord tr = mRecentTasks.get(i);
3530            if (task != tr) {
3531                if (task.userId != tr.userId) {
3532                    continue;
3533                }
3534                final Intent trIntent = tr.intent;
3535                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3536                    (intent == null || !intent.filterEquals(trIntent))) {
3537                    continue;
3538                }
3539                if (document || trIntent != null && trIntent.isDocument()) {
3540                    // Document tasks do not match other tasks.
3541                    continue;
3542                }
3543            }
3544
3545            // Either task and tr are the same or, their affinities match or their intents match
3546            // and neither of them is a document.
3547            tr.disposeThumbnail();
3548            mRecentTasks.remove(i);
3549            i--;
3550            N--;
3551            if (task.intent == null) {
3552                // If the new recent task we are adding is not fully
3553                // specified, then replace it with the existing recent task.
3554                task = tr;
3555            }
3556        }
3557        if (N >= MAX_RECENT_TASKS) {
3558            mRecentTasks.remove(N-1).disposeThumbnail();
3559        }
3560        mRecentTasks.add(0, task);
3561    }
3562
3563    @Override
3564    public void reportActivityFullyDrawn(IBinder token) {
3565        synchronized (this) {
3566            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3567            if (r == null) {
3568                return;
3569            }
3570            r.reportFullyDrawnLocked();
3571        }
3572    }
3573
3574    @Override
3575    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3576        synchronized (this) {
3577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3578            if (r == null) {
3579                return;
3580            }
3581            final long origId = Binder.clearCallingIdentity();
3582            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3583            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3584                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3585            if (config != null) {
3586                r.frozenBeforeDestroy = true;
3587                if (!updateConfigurationLocked(config, r, false, false)) {
3588                    mStackSupervisor.resumeTopActivitiesLocked();
3589                }
3590            }
3591            Binder.restoreCallingIdentity(origId);
3592        }
3593    }
3594
3595    @Override
3596    public int getRequestedOrientation(IBinder token) {
3597        synchronized (this) {
3598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3599            if (r == null) {
3600                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3601            }
3602            return mWindowManager.getAppOrientation(r.appToken);
3603        }
3604    }
3605
3606    /**
3607     * This is the internal entry point for handling Activity.finish().
3608     *
3609     * @param token The Binder token referencing the Activity we want to finish.
3610     * @param resultCode Result code, if any, from this Activity.
3611     * @param resultData Result data (Intent), if any, from this Activity.
3612     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3613     *            the root Activity in the task.
3614     *
3615     * @return Returns true if the activity successfully finished, or false if it is still running.
3616     */
3617    @Override
3618    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3619            boolean finishTask) {
3620        // Refuse possible leaked file descriptors
3621        if (resultData != null && resultData.hasFileDescriptors() == true) {
3622            throw new IllegalArgumentException("File descriptors passed in Intent");
3623        }
3624
3625        synchronized(this) {
3626            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3627            if (r == null) {
3628                return true;
3629            }
3630            // Keep track of the root activity of the task before we finish it
3631            TaskRecord tr = r.task;
3632            ActivityRecord rootR = tr.getRootActivity();
3633            if (mController != null) {
3634                // Find the first activity that is not finishing.
3635                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3636                if (next != null) {
3637                    // ask watcher if this is allowed
3638                    boolean resumeOK = true;
3639                    try {
3640                        resumeOK = mController.activityResuming(next.packageName);
3641                    } catch (RemoteException e) {
3642                        mController = null;
3643                        Watchdog.getInstance().setActivityController(null);
3644                    }
3645
3646                    if (!resumeOK) {
3647                        return false;
3648                    }
3649                }
3650            }
3651            final long origId = Binder.clearCallingIdentity();
3652            try {
3653                boolean res;
3654                if (finishTask && r == rootR) {
3655                    // If requested, remove the task that is associated to this activity only if it
3656                    // was the root activity in the task.  The result code and data is ignored because
3657                    // we don't support returning them across task boundaries.
3658                    res = removeTaskByIdLocked(tr.taskId, 0);
3659                } else {
3660                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3661                            resultData, "app-request", true);
3662                }
3663                return res;
3664            } finally {
3665                Binder.restoreCallingIdentity(origId);
3666            }
3667        }
3668    }
3669
3670    @Override
3671    public final void finishHeavyWeightApp() {
3672        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3673                != PackageManager.PERMISSION_GRANTED) {
3674            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3675                    + Binder.getCallingPid()
3676                    + ", uid=" + Binder.getCallingUid()
3677                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3678            Slog.w(TAG, msg);
3679            throw new SecurityException(msg);
3680        }
3681
3682        synchronized(this) {
3683            if (mHeavyWeightProcess == null) {
3684                return;
3685            }
3686
3687            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3688                    mHeavyWeightProcess.activities);
3689            for (int i=0; i<activities.size(); i++) {
3690                ActivityRecord r = activities.get(i);
3691                if (!r.finishing) {
3692                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3693                            null, "finish-heavy", true);
3694                }
3695            }
3696
3697            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3698                    mHeavyWeightProcess.userId, 0));
3699            mHeavyWeightProcess = null;
3700        }
3701    }
3702
3703    @Override
3704    public void crashApplication(int uid, int initialPid, String packageName,
3705            String message) {
3706        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3707                != PackageManager.PERMISSION_GRANTED) {
3708            String msg = "Permission Denial: crashApplication() from pid="
3709                    + Binder.getCallingPid()
3710                    + ", uid=" + Binder.getCallingUid()
3711                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3712            Slog.w(TAG, msg);
3713            throw new SecurityException(msg);
3714        }
3715
3716        synchronized(this) {
3717            ProcessRecord proc = null;
3718
3719            // Figure out which process to kill.  We don't trust that initialPid
3720            // still has any relation to current pids, so must scan through the
3721            // list.
3722            synchronized (mPidsSelfLocked) {
3723                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3724                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3725                    if (p.uid != uid) {
3726                        continue;
3727                    }
3728                    if (p.pid == initialPid) {
3729                        proc = p;
3730                        break;
3731                    }
3732                    if (p.pkgList.containsKey(packageName)) {
3733                        proc = p;
3734                    }
3735                }
3736            }
3737
3738            if (proc == null) {
3739                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3740                        + " initialPid=" + initialPid
3741                        + " packageName=" + packageName);
3742                return;
3743            }
3744
3745            if (proc.thread != null) {
3746                if (proc.pid == Process.myPid()) {
3747                    Log.w(TAG, "crashApplication: trying to crash self!");
3748                    return;
3749                }
3750                long ident = Binder.clearCallingIdentity();
3751                try {
3752                    proc.thread.scheduleCrash(message);
3753                } catch (RemoteException e) {
3754                }
3755                Binder.restoreCallingIdentity(ident);
3756            }
3757        }
3758    }
3759
3760    @Override
3761    public final void finishSubActivity(IBinder token, String resultWho,
3762            int requestCode) {
3763        synchronized(this) {
3764            final long origId = Binder.clearCallingIdentity();
3765            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3766            if (r != null) {
3767                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3768            }
3769            Binder.restoreCallingIdentity(origId);
3770        }
3771    }
3772
3773    @Override
3774    public boolean finishActivityAffinity(IBinder token) {
3775        synchronized(this) {
3776            final long origId = Binder.clearCallingIdentity();
3777            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3778            boolean res = false;
3779            if (r != null) {
3780                res = r.task.stack.finishActivityAffinityLocked(r);
3781            }
3782            Binder.restoreCallingIdentity(origId);
3783            return res;
3784        }
3785    }
3786
3787    @Override
3788    public boolean willActivityBeVisible(IBinder token) {
3789        synchronized(this) {
3790            ActivityStack stack = ActivityRecord.getStackLocked(token);
3791            if (stack != null) {
3792                return stack.willActivityBeVisibleLocked(token);
3793            }
3794            return false;
3795        }
3796    }
3797
3798    @Override
3799    public void overridePendingTransition(IBinder token, String packageName,
3800            int enterAnim, int exitAnim) {
3801        synchronized(this) {
3802            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3803            if (self == null) {
3804                return;
3805            }
3806
3807            final long origId = Binder.clearCallingIdentity();
3808
3809            if (self.state == ActivityState.RESUMED
3810                    || self.state == ActivityState.PAUSING) {
3811                mWindowManager.overridePendingAppTransition(packageName,
3812                        enterAnim, exitAnim, null);
3813            }
3814
3815            Binder.restoreCallingIdentity(origId);
3816        }
3817    }
3818
3819    /**
3820     * Main function for removing an existing process from the activity manager
3821     * as a result of that process going away.  Clears out all connections
3822     * to the process.
3823     */
3824    private final void handleAppDiedLocked(ProcessRecord app,
3825            boolean restarting, boolean allowRestart) {
3826        int pid = app.pid;
3827        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3828        if (!restarting) {
3829            removeLruProcessLocked(app);
3830            if (pid > 0) {
3831                ProcessList.remove(pid);
3832            }
3833        }
3834
3835        if (mProfileProc == app) {
3836            clearProfilerLocked();
3837        }
3838
3839        // Remove this application's activities from active lists.
3840        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3841
3842        app.activities.clear();
3843
3844        if (app.instrumentationClass != null) {
3845            Slog.w(TAG, "Crash of app " + app.processName
3846                  + " running instrumentation " + app.instrumentationClass);
3847            Bundle info = new Bundle();
3848            info.putString("shortMsg", "Process crashed.");
3849            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3850        }
3851
3852        if (!restarting) {
3853            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3854                // If there was nothing to resume, and we are not already
3855                // restarting this process, but there is a visible activity that
3856                // is hosted by the process...  then make sure all visible
3857                // activities are running, taking care of restarting this
3858                // process.
3859                if (hasVisibleActivities) {
3860                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3861                }
3862            }
3863        }
3864    }
3865
3866    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3867        IBinder threadBinder = thread.asBinder();
3868        // Find the application record.
3869        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3870            ProcessRecord rec = mLruProcesses.get(i);
3871            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3872                return i;
3873            }
3874        }
3875        return -1;
3876    }
3877
3878    final ProcessRecord getRecordForAppLocked(
3879            IApplicationThread thread) {
3880        if (thread == null) {
3881            return null;
3882        }
3883
3884        int appIndex = getLRURecordIndexForAppLocked(thread);
3885        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3886    }
3887
3888    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3889        // If there are no longer any background processes running,
3890        // and the app that died was not running instrumentation,
3891        // then tell everyone we are now low on memory.
3892        boolean haveBg = false;
3893        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3894            ProcessRecord rec = mLruProcesses.get(i);
3895            if (rec.thread != null
3896                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3897                haveBg = true;
3898                break;
3899            }
3900        }
3901
3902        if (!haveBg) {
3903            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3904            if (doReport) {
3905                long now = SystemClock.uptimeMillis();
3906                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3907                    doReport = false;
3908                } else {
3909                    mLastMemUsageReportTime = now;
3910                }
3911            }
3912            final ArrayList<ProcessMemInfo> memInfos
3913                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3914            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3915            long now = SystemClock.uptimeMillis();
3916            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3917                ProcessRecord rec = mLruProcesses.get(i);
3918                if (rec == dyingProc || rec.thread == null) {
3919                    continue;
3920                }
3921                if (doReport) {
3922                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3923                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3924                }
3925                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3926                    // The low memory report is overriding any current
3927                    // state for a GC request.  Make sure to do
3928                    // heavy/important/visible/foreground processes first.
3929                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3930                        rec.lastRequestedGc = 0;
3931                    } else {
3932                        rec.lastRequestedGc = rec.lastLowMemory;
3933                    }
3934                    rec.reportLowMemory = true;
3935                    rec.lastLowMemory = now;
3936                    mProcessesToGc.remove(rec);
3937                    addProcessToGcListLocked(rec);
3938                }
3939            }
3940            if (doReport) {
3941                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3942                mHandler.sendMessage(msg);
3943            }
3944            scheduleAppGcsLocked();
3945        }
3946    }
3947
3948    final void appDiedLocked(ProcessRecord app, int pid,
3949            IApplicationThread thread) {
3950
3951        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3952        synchronized (stats) {
3953            stats.noteProcessDiedLocked(app.info.uid, pid);
3954        }
3955
3956        // Clean up already done if the process has been re-started.
3957        if (app.pid == pid && app.thread != null &&
3958                app.thread.asBinder() == thread.asBinder()) {
3959            boolean doLowMem = app.instrumentationClass == null;
3960            boolean doOomAdj = doLowMem;
3961            if (!app.killedByAm) {
3962                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3963                        + ") has died.");
3964                mAllowLowerMemLevel = true;
3965            } else {
3966                // Note that we always want to do oom adj to update our state with the
3967                // new number of procs.
3968                mAllowLowerMemLevel = false;
3969                doLowMem = false;
3970            }
3971            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3972            if (DEBUG_CLEANUP) Slog.v(
3973                TAG, "Dying app: " + app + ", pid: " + pid
3974                + ", thread: " + thread.asBinder());
3975            handleAppDiedLocked(app, false, true);
3976
3977            if (doOomAdj) {
3978                updateOomAdjLocked();
3979            }
3980            if (doLowMem) {
3981                doLowMemReportIfNeededLocked(app);
3982            }
3983        } else if (app.pid != pid) {
3984            // A new process has already been started.
3985            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3986                    + ") has died and restarted (pid " + app.pid + ").");
3987            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3988        } else if (DEBUG_PROCESSES) {
3989            Slog.d(TAG, "Received spurious death notification for thread "
3990                    + thread.asBinder());
3991        }
3992    }
3993
3994    /**
3995     * If a stack trace dump file is configured, dump process stack traces.
3996     * @param clearTraces causes the dump file to be erased prior to the new
3997     *    traces being written, if true; when false, the new traces will be
3998     *    appended to any existing file content.
3999     * @param firstPids of dalvik VM processes to dump stack traces for first
4000     * @param lastPids of dalvik VM processes to dump stack traces for last
4001     * @param nativeProcs optional list of native process names to dump stack crawls
4002     * @return file containing stack traces, or null if no dump file is configured
4003     */
4004    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4005            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4006        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4007        if (tracesPath == null || tracesPath.length() == 0) {
4008            return null;
4009        }
4010
4011        File tracesFile = new File(tracesPath);
4012        try {
4013            File tracesDir = tracesFile.getParentFile();
4014            if (!tracesDir.exists()) {
4015                tracesFile.mkdirs();
4016                if (!SELinux.restorecon(tracesDir)) {
4017                    return null;
4018                }
4019            }
4020            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4021
4022            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4023            tracesFile.createNewFile();
4024            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4025        } catch (IOException e) {
4026            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4027            return null;
4028        }
4029
4030        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4031        return tracesFile;
4032    }
4033
4034    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4035            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4036        // Use a FileObserver to detect when traces finish writing.
4037        // The order of traces is considered important to maintain for legibility.
4038        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4039            @Override
4040            public synchronized void onEvent(int event, String path) { notify(); }
4041        };
4042
4043        try {
4044            observer.startWatching();
4045
4046            // First collect all of the stacks of the most important pids.
4047            if (firstPids != null) {
4048                try {
4049                    int num = firstPids.size();
4050                    for (int i = 0; i < num; i++) {
4051                        synchronized (observer) {
4052                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4053                            observer.wait(200);  // Wait for write-close, give up after 200msec
4054                        }
4055                    }
4056                } catch (InterruptedException e) {
4057                    Log.wtf(TAG, e);
4058                }
4059            }
4060
4061            // Next collect the stacks of the native pids
4062            if (nativeProcs != null) {
4063                int[] pids = Process.getPidsForCommands(nativeProcs);
4064                if (pids != null) {
4065                    for (int pid : pids) {
4066                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4067                    }
4068                }
4069            }
4070
4071            // Lastly, measure CPU usage.
4072            if (processCpuTracker != null) {
4073                processCpuTracker.init();
4074                System.gc();
4075                processCpuTracker.update();
4076                try {
4077                    synchronized (processCpuTracker) {
4078                        processCpuTracker.wait(500); // measure over 1/2 second.
4079                    }
4080                } catch (InterruptedException e) {
4081                }
4082                processCpuTracker.update();
4083
4084                // We'll take the stack crawls of just the top apps using CPU.
4085                final int N = processCpuTracker.countWorkingStats();
4086                int numProcs = 0;
4087                for (int i=0; i<N && numProcs<5; i++) {
4088                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4089                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4090                        numProcs++;
4091                        try {
4092                            synchronized (observer) {
4093                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4094                                observer.wait(200);  // Wait for write-close, give up after 200msec
4095                            }
4096                        } catch (InterruptedException e) {
4097                            Log.wtf(TAG, e);
4098                        }
4099
4100                    }
4101                }
4102            }
4103        } finally {
4104            observer.stopWatching();
4105        }
4106    }
4107
4108    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4109        if (true || IS_USER_BUILD) {
4110            return;
4111        }
4112        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4113        if (tracesPath == null || tracesPath.length() == 0) {
4114            return;
4115        }
4116
4117        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4118        StrictMode.allowThreadDiskWrites();
4119        try {
4120            final File tracesFile = new File(tracesPath);
4121            final File tracesDir = tracesFile.getParentFile();
4122            final File tracesTmp = new File(tracesDir, "__tmp__");
4123            try {
4124                if (!tracesDir.exists()) {
4125                    tracesFile.mkdirs();
4126                    if (!SELinux.restorecon(tracesDir.getPath())) {
4127                        return;
4128                    }
4129                }
4130                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4131
4132                if (tracesFile.exists()) {
4133                    tracesTmp.delete();
4134                    tracesFile.renameTo(tracesTmp);
4135                }
4136                StringBuilder sb = new StringBuilder();
4137                Time tobj = new Time();
4138                tobj.set(System.currentTimeMillis());
4139                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4140                sb.append(": ");
4141                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4142                sb.append(" since ");
4143                sb.append(msg);
4144                FileOutputStream fos = new FileOutputStream(tracesFile);
4145                fos.write(sb.toString().getBytes());
4146                if (app == null) {
4147                    fos.write("\n*** No application process!".getBytes());
4148                }
4149                fos.close();
4150                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4151            } catch (IOException e) {
4152                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4153                return;
4154            }
4155
4156            if (app != null) {
4157                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4158                firstPids.add(app.pid);
4159                dumpStackTraces(tracesPath, firstPids, null, null, null);
4160            }
4161
4162            File lastTracesFile = null;
4163            File curTracesFile = null;
4164            for (int i=9; i>=0; i--) {
4165                String name = String.format(Locale.US, "slow%02d.txt", i);
4166                curTracesFile = new File(tracesDir, name);
4167                if (curTracesFile.exists()) {
4168                    if (lastTracesFile != null) {
4169                        curTracesFile.renameTo(lastTracesFile);
4170                    } else {
4171                        curTracesFile.delete();
4172                    }
4173                }
4174                lastTracesFile = curTracesFile;
4175            }
4176            tracesFile.renameTo(curTracesFile);
4177            if (tracesTmp.exists()) {
4178                tracesTmp.renameTo(tracesFile);
4179            }
4180        } finally {
4181            StrictMode.setThreadPolicy(oldPolicy);
4182        }
4183    }
4184
4185    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4186            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4187        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4188        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4189
4190        if (mController != null) {
4191            try {
4192                // 0 == continue, -1 = kill process immediately
4193                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4194                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4195            } catch (RemoteException e) {
4196                mController = null;
4197                Watchdog.getInstance().setActivityController(null);
4198            }
4199        }
4200
4201        long anrTime = SystemClock.uptimeMillis();
4202        if (MONITOR_CPU_USAGE) {
4203            updateCpuStatsNow();
4204        }
4205
4206        synchronized (this) {
4207            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4208            if (mShuttingDown) {
4209                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4210                return;
4211            } else if (app.notResponding) {
4212                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4213                return;
4214            } else if (app.crashing) {
4215                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4216                return;
4217            }
4218
4219            // In case we come through here for the same app before completing
4220            // this one, mark as anring now so we will bail out.
4221            app.notResponding = true;
4222
4223            // Log the ANR to the event log.
4224            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4225                    app.processName, app.info.flags, annotation);
4226
4227            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4228            firstPids.add(app.pid);
4229
4230            int parentPid = app.pid;
4231            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4232            if (parentPid != app.pid) firstPids.add(parentPid);
4233
4234            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4235
4236            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4237                ProcessRecord r = mLruProcesses.get(i);
4238                if (r != null && r.thread != null) {
4239                    int pid = r.pid;
4240                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4241                        if (r.persistent) {
4242                            firstPids.add(pid);
4243                        } else {
4244                            lastPids.put(pid, Boolean.TRUE);
4245                        }
4246                    }
4247                }
4248            }
4249        }
4250
4251        // Log the ANR to the main log.
4252        StringBuilder info = new StringBuilder();
4253        info.setLength(0);
4254        info.append("ANR in ").append(app.processName);
4255        if (activity != null && activity.shortComponentName != null) {
4256            info.append(" (").append(activity.shortComponentName).append(")");
4257        }
4258        info.append("\n");
4259        info.append("PID: ").append(app.pid).append("\n");
4260        if (annotation != null) {
4261            info.append("Reason: ").append(annotation).append("\n");
4262        }
4263        if (parent != null && parent != activity) {
4264            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4265        }
4266
4267        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4268
4269        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4270                NATIVE_STACKS_OF_INTEREST);
4271
4272        String cpuInfo = null;
4273        if (MONITOR_CPU_USAGE) {
4274            updateCpuStatsNow();
4275            synchronized (mProcessCpuThread) {
4276                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4277            }
4278            info.append(processCpuTracker.printCurrentLoad());
4279            info.append(cpuInfo);
4280        }
4281
4282        info.append(processCpuTracker.printCurrentState(anrTime));
4283
4284        Slog.e(TAG, info.toString());
4285        if (tracesFile == null) {
4286            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4287            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4288        }
4289
4290        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4291                cpuInfo, tracesFile, null);
4292
4293        if (mController != null) {
4294            try {
4295                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4296                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4297                if (res != 0) {
4298                    if (res < 0 && app.pid != MY_PID) {
4299                        Process.killProcess(app.pid);
4300                    } else {
4301                        synchronized (this) {
4302                            mServices.scheduleServiceTimeoutLocked(app);
4303                        }
4304                    }
4305                    return;
4306                }
4307            } catch (RemoteException e) {
4308                mController = null;
4309                Watchdog.getInstance().setActivityController(null);
4310            }
4311        }
4312
4313        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4314        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4315                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4316
4317        synchronized (this) {
4318            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4319                killUnneededProcessLocked(app, "background ANR");
4320                return;
4321            }
4322
4323            // Set the app's notResponding state, and look up the errorReportReceiver
4324            makeAppNotRespondingLocked(app,
4325                    activity != null ? activity.shortComponentName : null,
4326                    annotation != null ? "ANR " + annotation : "ANR",
4327                    info.toString());
4328
4329            // Bring up the infamous App Not Responding dialog
4330            Message msg = Message.obtain();
4331            HashMap<String, Object> map = new HashMap<String, Object>();
4332            msg.what = SHOW_NOT_RESPONDING_MSG;
4333            msg.obj = map;
4334            msg.arg1 = aboveSystem ? 1 : 0;
4335            map.put("app", app);
4336            if (activity != null) {
4337                map.put("activity", activity);
4338            }
4339
4340            mHandler.sendMessage(msg);
4341        }
4342    }
4343
4344    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4345        if (!mLaunchWarningShown) {
4346            mLaunchWarningShown = true;
4347            mHandler.post(new Runnable() {
4348                @Override
4349                public void run() {
4350                    synchronized (ActivityManagerService.this) {
4351                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4352                        d.show();
4353                        mHandler.postDelayed(new Runnable() {
4354                            @Override
4355                            public void run() {
4356                                synchronized (ActivityManagerService.this) {
4357                                    d.dismiss();
4358                                    mLaunchWarningShown = false;
4359                                }
4360                            }
4361                        }, 4000);
4362                    }
4363                }
4364            });
4365        }
4366    }
4367
4368    @Override
4369    public boolean clearApplicationUserData(final String packageName,
4370            final IPackageDataObserver observer, int userId) {
4371        enforceNotIsolatedCaller("clearApplicationUserData");
4372        int uid = Binder.getCallingUid();
4373        int pid = Binder.getCallingPid();
4374        userId = handleIncomingUser(pid, uid,
4375                userId, false, true, "clearApplicationUserData", null);
4376        long callingId = Binder.clearCallingIdentity();
4377        try {
4378            IPackageManager pm = AppGlobals.getPackageManager();
4379            int pkgUid = -1;
4380            synchronized(this) {
4381                try {
4382                    pkgUid = pm.getPackageUid(packageName, userId);
4383                } catch (RemoteException e) {
4384                }
4385                if (pkgUid == -1) {
4386                    Slog.w(TAG, "Invalid packageName: " + packageName);
4387                    if (observer != null) {
4388                        try {
4389                            observer.onRemoveCompleted(packageName, false);
4390                        } catch (RemoteException e) {
4391                            Slog.i(TAG, "Observer no longer exists.");
4392                        }
4393                    }
4394                    return false;
4395                }
4396                if (uid == pkgUid || checkComponentPermission(
4397                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4398                        pid, uid, -1, true)
4399                        == PackageManager.PERMISSION_GRANTED) {
4400                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4401                } else {
4402                    throw new SecurityException("PID " + pid + " does not have permission "
4403                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4404                                    + " of package " + packageName);
4405                }
4406            }
4407
4408            try {
4409                // Clear application user data
4410                pm.clearApplicationUserData(packageName, observer, userId);
4411
4412                // Remove all permissions granted from/to this package
4413                removeUriPermissionsForPackageLocked(packageName, userId, true);
4414
4415                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4416                        Uri.fromParts("package", packageName, null));
4417                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4418                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4419                        null, null, 0, null, null, null, false, false, userId);
4420            } catch (RemoteException e) {
4421            }
4422        } finally {
4423            Binder.restoreCallingIdentity(callingId);
4424        }
4425        return true;
4426    }
4427
4428    @Override
4429    public void killBackgroundProcesses(final String packageName, int userId) {
4430        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4431                != PackageManager.PERMISSION_GRANTED &&
4432                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4433                        != PackageManager.PERMISSION_GRANTED) {
4434            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4435                    + Binder.getCallingPid()
4436                    + ", uid=" + Binder.getCallingUid()
4437                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4438            Slog.w(TAG, msg);
4439            throw new SecurityException(msg);
4440        }
4441
4442        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4443                userId, true, true, "killBackgroundProcesses", null);
4444        long callingId = Binder.clearCallingIdentity();
4445        try {
4446            IPackageManager pm = AppGlobals.getPackageManager();
4447            synchronized(this) {
4448                int appId = -1;
4449                try {
4450                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4451                } catch (RemoteException e) {
4452                }
4453                if (appId == -1) {
4454                    Slog.w(TAG, "Invalid packageName: " + packageName);
4455                    return;
4456                }
4457                killPackageProcessesLocked(packageName, appId, userId,
4458                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4459            }
4460        } finally {
4461            Binder.restoreCallingIdentity(callingId);
4462        }
4463    }
4464
4465    @Override
4466    public void killAllBackgroundProcesses() {
4467        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4468                != PackageManager.PERMISSION_GRANTED) {
4469            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4470                    + Binder.getCallingPid()
4471                    + ", uid=" + Binder.getCallingUid()
4472                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4473            Slog.w(TAG, msg);
4474            throw new SecurityException(msg);
4475        }
4476
4477        long callingId = Binder.clearCallingIdentity();
4478        try {
4479            synchronized(this) {
4480                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4481                final int NP = mProcessNames.getMap().size();
4482                for (int ip=0; ip<NP; ip++) {
4483                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4484                    final int NA = apps.size();
4485                    for (int ia=0; ia<NA; ia++) {
4486                        ProcessRecord app = apps.valueAt(ia);
4487                        if (app.persistent) {
4488                            // we don't kill persistent processes
4489                            continue;
4490                        }
4491                        if (app.removed) {
4492                            procs.add(app);
4493                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4494                            app.removed = true;
4495                            procs.add(app);
4496                        }
4497                    }
4498                }
4499
4500                int N = procs.size();
4501                for (int i=0; i<N; i++) {
4502                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4503                }
4504                mAllowLowerMemLevel = true;
4505                updateOomAdjLocked();
4506                doLowMemReportIfNeededLocked(null);
4507            }
4508        } finally {
4509            Binder.restoreCallingIdentity(callingId);
4510        }
4511    }
4512
4513    @Override
4514    public void forceStopPackage(final String packageName, int userId) {
4515        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4516                != PackageManager.PERMISSION_GRANTED) {
4517            String msg = "Permission Denial: forceStopPackage() from pid="
4518                    + Binder.getCallingPid()
4519                    + ", uid=" + Binder.getCallingUid()
4520                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4521            Slog.w(TAG, msg);
4522            throw new SecurityException(msg);
4523        }
4524        final int callingPid = Binder.getCallingPid();
4525        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4526                userId, true, true, "forceStopPackage", null);
4527        long callingId = Binder.clearCallingIdentity();
4528        try {
4529            IPackageManager pm = AppGlobals.getPackageManager();
4530            synchronized(this) {
4531                int[] users = userId == UserHandle.USER_ALL
4532                        ? getUsersLocked() : new int[] { userId };
4533                for (int user : users) {
4534                    int pkgUid = -1;
4535                    try {
4536                        pkgUid = pm.getPackageUid(packageName, user);
4537                    } catch (RemoteException e) {
4538                    }
4539                    if (pkgUid == -1) {
4540                        Slog.w(TAG, "Invalid packageName: " + packageName);
4541                        continue;
4542                    }
4543                    try {
4544                        pm.setPackageStoppedState(packageName, true, user);
4545                    } catch (RemoteException e) {
4546                    } catch (IllegalArgumentException e) {
4547                        Slog.w(TAG, "Failed trying to unstop package "
4548                                + packageName + ": " + e);
4549                    }
4550                    if (isUserRunningLocked(user, false)) {
4551                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4552                    }
4553                }
4554            }
4555        } finally {
4556            Binder.restoreCallingIdentity(callingId);
4557        }
4558    }
4559
4560    /*
4561     * The pkg name and app id have to be specified.
4562     */
4563    @Override
4564    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4565        if (pkg == null) {
4566            return;
4567        }
4568        // Make sure the uid is valid.
4569        if (appid < 0) {
4570            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4571            return;
4572        }
4573        int callerUid = Binder.getCallingUid();
4574        // Only the system server can kill an application
4575        if (callerUid == Process.SYSTEM_UID) {
4576            // Post an aysnc message to kill the application
4577            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4578            msg.arg1 = appid;
4579            msg.arg2 = 0;
4580            Bundle bundle = new Bundle();
4581            bundle.putString("pkg", pkg);
4582            bundle.putString("reason", reason);
4583            msg.obj = bundle;
4584            mHandler.sendMessage(msg);
4585        } else {
4586            throw new SecurityException(callerUid + " cannot kill pkg: " +
4587                    pkg);
4588        }
4589    }
4590
4591    @Override
4592    public void closeSystemDialogs(String reason) {
4593        enforceNotIsolatedCaller("closeSystemDialogs");
4594
4595        final int pid = Binder.getCallingPid();
4596        final int uid = Binder.getCallingUid();
4597        final long origId = Binder.clearCallingIdentity();
4598        try {
4599            synchronized (this) {
4600                // Only allow this from foreground processes, so that background
4601                // applications can't abuse it to prevent system UI from being shown.
4602                if (uid >= Process.FIRST_APPLICATION_UID) {
4603                    ProcessRecord proc;
4604                    synchronized (mPidsSelfLocked) {
4605                        proc = mPidsSelfLocked.get(pid);
4606                    }
4607                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4608                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4609                                + " from background process " + proc);
4610                        return;
4611                    }
4612                }
4613                closeSystemDialogsLocked(reason);
4614            }
4615        } finally {
4616            Binder.restoreCallingIdentity(origId);
4617        }
4618    }
4619
4620    void closeSystemDialogsLocked(String reason) {
4621        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4622        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4623                | Intent.FLAG_RECEIVER_FOREGROUND);
4624        if (reason != null) {
4625            intent.putExtra("reason", reason);
4626        }
4627        mWindowManager.closeSystemDialogs(reason);
4628
4629        mStackSupervisor.closeSystemDialogsLocked();
4630
4631        broadcastIntentLocked(null, null, intent, null,
4632                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4633                Process.SYSTEM_UID, UserHandle.USER_ALL);
4634    }
4635
4636    @Override
4637    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4638        enforceNotIsolatedCaller("getProcessMemoryInfo");
4639        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4640        for (int i=pids.length-1; i>=0; i--) {
4641            ProcessRecord proc;
4642            int oomAdj;
4643            synchronized (this) {
4644                synchronized (mPidsSelfLocked) {
4645                    proc = mPidsSelfLocked.get(pids[i]);
4646                    oomAdj = proc != null ? proc.setAdj : 0;
4647                }
4648            }
4649            infos[i] = new Debug.MemoryInfo();
4650            Debug.getMemoryInfo(pids[i], infos[i]);
4651            if (proc != null) {
4652                synchronized (this) {
4653                    if (proc.thread != null && proc.setAdj == oomAdj) {
4654                        // Record this for posterity if the process has been stable.
4655                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4656                                infos[i].getTotalUss(), false, proc.pkgList);
4657                    }
4658                }
4659            }
4660        }
4661        return infos;
4662    }
4663
4664    @Override
4665    public long[] getProcessPss(int[] pids) {
4666        enforceNotIsolatedCaller("getProcessPss");
4667        long[] pss = new long[pids.length];
4668        for (int i=pids.length-1; i>=0; i--) {
4669            ProcessRecord proc;
4670            int oomAdj;
4671            synchronized (this) {
4672                synchronized (mPidsSelfLocked) {
4673                    proc = mPidsSelfLocked.get(pids[i]);
4674                    oomAdj = proc != null ? proc.setAdj : 0;
4675                }
4676            }
4677            long[] tmpUss = new long[1];
4678            pss[i] = Debug.getPss(pids[i], tmpUss);
4679            if (proc != null) {
4680                synchronized (this) {
4681                    if (proc.thread != null && proc.setAdj == oomAdj) {
4682                        // Record this for posterity if the process has been stable.
4683                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4684                    }
4685                }
4686            }
4687        }
4688        return pss;
4689    }
4690
4691    @Override
4692    public void killApplicationProcess(String processName, int uid) {
4693        if (processName == null) {
4694            return;
4695        }
4696
4697        int callerUid = Binder.getCallingUid();
4698        // Only the system server can kill an application
4699        if (callerUid == Process.SYSTEM_UID) {
4700            synchronized (this) {
4701                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4702                if (app != null && app.thread != null) {
4703                    try {
4704                        app.thread.scheduleSuicide();
4705                    } catch (RemoteException e) {
4706                        // If the other end already died, then our work here is done.
4707                    }
4708                } else {
4709                    Slog.w(TAG, "Process/uid not found attempting kill of "
4710                            + processName + " / " + uid);
4711                }
4712            }
4713        } else {
4714            throw new SecurityException(callerUid + " cannot kill app process: " +
4715                    processName);
4716        }
4717    }
4718
4719    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4720        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4721                false, true, false, false, UserHandle.getUserId(uid), reason);
4722        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4723                Uri.fromParts("package", packageName, null));
4724        if (!mProcessesReady) {
4725            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4726                    | Intent.FLAG_RECEIVER_FOREGROUND);
4727        }
4728        intent.putExtra(Intent.EXTRA_UID, uid);
4729        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4730        broadcastIntentLocked(null, null, intent,
4731                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4732                false, false,
4733                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4734    }
4735
4736    private void forceStopUserLocked(int userId, String reason) {
4737        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4738        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4739        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4740                | Intent.FLAG_RECEIVER_FOREGROUND);
4741        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4742        broadcastIntentLocked(null, null, intent,
4743                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4744                false, false,
4745                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4746    }
4747
4748    private final boolean killPackageProcessesLocked(String packageName, int appId,
4749            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4750            boolean doit, boolean evenPersistent, String reason) {
4751        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4752
4753        // Remove all processes this package may have touched: all with the
4754        // same UID (except for the system or root user), and all whose name
4755        // matches the package name.
4756        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4757        final int NP = mProcessNames.getMap().size();
4758        for (int ip=0; ip<NP; ip++) {
4759            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4760            final int NA = apps.size();
4761            for (int ia=0; ia<NA; ia++) {
4762                ProcessRecord app = apps.valueAt(ia);
4763                if (app.persistent && !evenPersistent) {
4764                    // we don't kill persistent processes
4765                    continue;
4766                }
4767                if (app.removed) {
4768                    if (doit) {
4769                        procs.add(app);
4770                    }
4771                    continue;
4772                }
4773
4774                // Skip process if it doesn't meet our oom adj requirement.
4775                if (app.setAdj < minOomAdj) {
4776                    continue;
4777                }
4778
4779                // If no package is specified, we call all processes under the
4780                // give user id.
4781                if (packageName == null) {
4782                    if (app.userId != userId) {
4783                        continue;
4784                    }
4785                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4786                        continue;
4787                    }
4788                // Package has been specified, we want to hit all processes
4789                // that match it.  We need to qualify this by the processes
4790                // that are running under the specified app and user ID.
4791                } else {
4792                    if (UserHandle.getAppId(app.uid) != appId) {
4793                        continue;
4794                    }
4795                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4796                        continue;
4797                    }
4798                    if (!app.pkgList.containsKey(packageName)) {
4799                        continue;
4800                    }
4801                }
4802
4803                // Process has passed all conditions, kill it!
4804                if (!doit) {
4805                    return true;
4806                }
4807                app.removed = true;
4808                procs.add(app);
4809            }
4810        }
4811
4812        int N = procs.size();
4813        for (int i=0; i<N; i++) {
4814            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4815        }
4816        updateOomAdjLocked();
4817        return N > 0;
4818    }
4819
4820    private final boolean forceStopPackageLocked(String name, int appId,
4821            boolean callerWillRestart, boolean purgeCache, boolean doit,
4822            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4823        int i;
4824        int N;
4825
4826        if (userId == UserHandle.USER_ALL && name == null) {
4827            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4828        }
4829
4830        if (appId < 0 && name != null) {
4831            try {
4832                appId = UserHandle.getAppId(
4833                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4834            } catch (RemoteException e) {
4835            }
4836        }
4837
4838        if (doit) {
4839            if (name != null) {
4840                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4841                        + " user=" + userId + ": " + reason);
4842            } else {
4843                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4844            }
4845
4846            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4847            for (int ip=pmap.size()-1; ip>=0; ip--) {
4848                SparseArray<Long> ba = pmap.valueAt(ip);
4849                for (i=ba.size()-1; i>=0; i--) {
4850                    boolean remove = false;
4851                    final int entUid = ba.keyAt(i);
4852                    if (name != null) {
4853                        if (userId == UserHandle.USER_ALL) {
4854                            if (UserHandle.getAppId(entUid) == appId) {
4855                                remove = true;
4856                            }
4857                        } else {
4858                            if (entUid == UserHandle.getUid(userId, appId)) {
4859                                remove = true;
4860                            }
4861                        }
4862                    } else if (UserHandle.getUserId(entUid) == userId) {
4863                        remove = true;
4864                    }
4865                    if (remove) {
4866                        ba.removeAt(i);
4867                    }
4868                }
4869                if (ba.size() == 0) {
4870                    pmap.removeAt(ip);
4871                }
4872            }
4873        }
4874
4875        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4876                -100, callerWillRestart, true, doit, evenPersistent,
4877                name == null ? ("stop user " + userId) : ("stop " + name));
4878
4879        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4880            if (!doit) {
4881                return true;
4882            }
4883            didSomething = true;
4884        }
4885
4886        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4887            if (!doit) {
4888                return true;
4889            }
4890            didSomething = true;
4891        }
4892
4893        if (name == null) {
4894            // Remove all sticky broadcasts from this user.
4895            mStickyBroadcasts.remove(userId);
4896        }
4897
4898        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4899        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4900                userId, providers)) {
4901            if (!doit) {
4902                return true;
4903            }
4904            didSomething = true;
4905        }
4906        N = providers.size();
4907        for (i=0; i<N; i++) {
4908            removeDyingProviderLocked(null, providers.get(i), true);
4909        }
4910
4911        // Remove transient permissions granted from/to this package/user
4912        removeUriPermissionsForPackageLocked(name, userId, false);
4913
4914        if (name == null || uninstalling) {
4915            // Remove pending intents.  For now we only do this when force
4916            // stopping users, because we have some problems when doing this
4917            // for packages -- app widgets are not currently cleaned up for
4918            // such packages, so they can be left with bad pending intents.
4919            if (mIntentSenderRecords.size() > 0) {
4920                Iterator<WeakReference<PendingIntentRecord>> it
4921                        = mIntentSenderRecords.values().iterator();
4922                while (it.hasNext()) {
4923                    WeakReference<PendingIntentRecord> wpir = it.next();
4924                    if (wpir == null) {
4925                        it.remove();
4926                        continue;
4927                    }
4928                    PendingIntentRecord pir = wpir.get();
4929                    if (pir == null) {
4930                        it.remove();
4931                        continue;
4932                    }
4933                    if (name == null) {
4934                        // Stopping user, remove all objects for the user.
4935                        if (pir.key.userId != userId) {
4936                            // Not the same user, skip it.
4937                            continue;
4938                        }
4939                    } else {
4940                        if (UserHandle.getAppId(pir.uid) != appId) {
4941                            // Different app id, skip it.
4942                            continue;
4943                        }
4944                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4945                            // Different user, skip it.
4946                            continue;
4947                        }
4948                        if (!pir.key.packageName.equals(name)) {
4949                            // Different package, skip it.
4950                            continue;
4951                        }
4952                    }
4953                    if (!doit) {
4954                        return true;
4955                    }
4956                    didSomething = true;
4957                    it.remove();
4958                    pir.canceled = true;
4959                    if (pir.key.activity != null) {
4960                        pir.key.activity.pendingResults.remove(pir.ref);
4961                    }
4962                }
4963            }
4964        }
4965
4966        if (doit) {
4967            if (purgeCache && name != null) {
4968                AttributeCache ac = AttributeCache.instance();
4969                if (ac != null) {
4970                    ac.removePackage(name);
4971                }
4972            }
4973            if (mBooted) {
4974                mStackSupervisor.resumeTopActivitiesLocked();
4975                mStackSupervisor.scheduleIdleLocked();
4976            }
4977        }
4978
4979        return didSomething;
4980    }
4981
4982    private final boolean removeProcessLocked(ProcessRecord app,
4983            boolean callerWillRestart, boolean allowRestart, String reason) {
4984        final String name = app.processName;
4985        final int uid = app.uid;
4986        if (DEBUG_PROCESSES) Slog.d(
4987            TAG, "Force removing proc " + app.toShortString() + " (" + name
4988            + "/" + uid + ")");
4989
4990        mProcessNames.remove(name, uid);
4991        mIsolatedProcesses.remove(app.uid);
4992        if (mHeavyWeightProcess == app) {
4993            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4994                    mHeavyWeightProcess.userId, 0));
4995            mHeavyWeightProcess = null;
4996        }
4997        boolean needRestart = false;
4998        if (app.pid > 0 && app.pid != MY_PID) {
4999            int pid = app.pid;
5000            synchronized (mPidsSelfLocked) {
5001                mPidsSelfLocked.remove(pid);
5002                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5003            }
5004            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5005                    app.processName, app.info.uid);
5006            if (app.isolated) {
5007                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5008            }
5009            killUnneededProcessLocked(app, reason);
5010            handleAppDiedLocked(app, true, allowRestart);
5011            removeLruProcessLocked(app);
5012
5013            if (app.persistent && !app.isolated) {
5014                if (!callerWillRestart) {
5015                    addAppLocked(app.info, false);
5016                } else {
5017                    needRestart = true;
5018                }
5019            }
5020        } else {
5021            mRemovedProcesses.add(app);
5022        }
5023
5024        return needRestart;
5025    }
5026
5027    private final void processStartTimedOutLocked(ProcessRecord app) {
5028        final int pid = app.pid;
5029        boolean gone = false;
5030        synchronized (mPidsSelfLocked) {
5031            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5032            if (knownApp != null && knownApp.thread == null) {
5033                mPidsSelfLocked.remove(pid);
5034                gone = true;
5035            }
5036        }
5037
5038        if (gone) {
5039            Slog.w(TAG, "Process " + app + " failed to attach");
5040            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5041                    pid, app.uid, app.processName);
5042            mProcessNames.remove(app.processName, app.uid);
5043            mIsolatedProcesses.remove(app.uid);
5044            if (mHeavyWeightProcess == app) {
5045                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5046                        mHeavyWeightProcess.userId, 0));
5047                mHeavyWeightProcess = null;
5048            }
5049            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5050                    app.processName, app.info.uid);
5051            if (app.isolated) {
5052                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5053            }
5054            // Take care of any launching providers waiting for this process.
5055            checkAppInLaunchingProvidersLocked(app, true);
5056            // Take care of any services that are waiting for the process.
5057            mServices.processStartTimedOutLocked(app);
5058            killUnneededProcessLocked(app, "start timeout");
5059            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5060                Slog.w(TAG, "Unattached app died before backup, skipping");
5061                try {
5062                    IBackupManager bm = IBackupManager.Stub.asInterface(
5063                            ServiceManager.getService(Context.BACKUP_SERVICE));
5064                    bm.agentDisconnected(app.info.packageName);
5065                } catch (RemoteException e) {
5066                    // Can't happen; the backup manager is local
5067                }
5068            }
5069            if (isPendingBroadcastProcessLocked(pid)) {
5070                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5071                skipPendingBroadcastLocked(pid);
5072            }
5073        } else {
5074            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5075        }
5076    }
5077
5078    private final boolean attachApplicationLocked(IApplicationThread thread,
5079            int pid) {
5080
5081        // Find the application record that is being attached...  either via
5082        // the pid if we are running in multiple processes, or just pull the
5083        // next app record if we are emulating process with anonymous threads.
5084        ProcessRecord app;
5085        if (pid != MY_PID && pid >= 0) {
5086            synchronized (mPidsSelfLocked) {
5087                app = mPidsSelfLocked.get(pid);
5088            }
5089        } else {
5090            app = null;
5091        }
5092
5093        if (app == null) {
5094            Slog.w(TAG, "No pending application record for pid " + pid
5095                    + " (IApplicationThread " + thread + "); dropping process");
5096            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5097            if (pid > 0 && pid != MY_PID) {
5098                Process.killProcessQuiet(pid);
5099            } else {
5100                try {
5101                    thread.scheduleExit();
5102                } catch (Exception e) {
5103                    // Ignore exceptions.
5104                }
5105            }
5106            return false;
5107        }
5108
5109        // If this application record is still attached to a previous
5110        // process, clean it up now.
5111        if (app.thread != null) {
5112            handleAppDiedLocked(app, true, true);
5113        }
5114
5115        // Tell the process all about itself.
5116
5117        if (localLOGV) Slog.v(
5118                TAG, "Binding process pid " + pid + " to record " + app);
5119
5120        final String processName = app.processName;
5121        try {
5122            AppDeathRecipient adr = new AppDeathRecipient(
5123                    app, pid, thread);
5124            thread.asBinder().linkToDeath(adr, 0);
5125            app.deathRecipient = adr;
5126        } catch (RemoteException e) {
5127            app.resetPackageList(mProcessStats);
5128            startProcessLocked(app, "link fail", processName);
5129            return false;
5130        }
5131
5132        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5133
5134        app.makeActive(thread, mProcessStats);
5135        app.curAdj = app.setAdj = -100;
5136        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5137        app.forcingToForeground = null;
5138        updateProcessForegroundLocked(app, false, false);
5139        app.hasShownUi = false;
5140        app.debugging = false;
5141        app.cached = false;
5142
5143        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5144
5145        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5146        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5147
5148        if (!normalMode) {
5149            Slog.i(TAG, "Launching preboot mode app: " + app);
5150        }
5151
5152        if (localLOGV) Slog.v(
5153            TAG, "New app record " + app
5154            + " thread=" + thread.asBinder() + " pid=" + pid);
5155        try {
5156            int testMode = IApplicationThread.DEBUG_OFF;
5157            if (mDebugApp != null && mDebugApp.equals(processName)) {
5158                testMode = mWaitForDebugger
5159                    ? IApplicationThread.DEBUG_WAIT
5160                    : IApplicationThread.DEBUG_ON;
5161                app.debugging = true;
5162                if (mDebugTransient) {
5163                    mDebugApp = mOrigDebugApp;
5164                    mWaitForDebugger = mOrigWaitForDebugger;
5165                }
5166            }
5167            String profileFile = app.instrumentationProfileFile;
5168            ParcelFileDescriptor profileFd = null;
5169            boolean profileAutoStop = false;
5170            if (mProfileApp != null && mProfileApp.equals(processName)) {
5171                mProfileProc = app;
5172                profileFile = mProfileFile;
5173                profileFd = mProfileFd;
5174                profileAutoStop = mAutoStopProfiler;
5175            }
5176            boolean enableOpenGlTrace = false;
5177            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5178                enableOpenGlTrace = true;
5179                mOpenGlTraceApp = null;
5180            }
5181
5182            // If the app is being launched for restore or full backup, set it up specially
5183            boolean isRestrictedBackupMode = false;
5184            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5185                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5186                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5187                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5188            }
5189
5190            ensurePackageDexOpt(app.instrumentationInfo != null
5191                    ? app.instrumentationInfo.packageName
5192                    : app.info.packageName);
5193            if (app.instrumentationClass != null) {
5194                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5195            }
5196            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5197                    + processName + " with config " + mConfiguration);
5198            ApplicationInfo appInfo = app.instrumentationInfo != null
5199                    ? app.instrumentationInfo : app.info;
5200            app.compat = compatibilityInfoForPackageLocked(appInfo);
5201            if (profileFd != null) {
5202                profileFd = profileFd.dup();
5203            }
5204            thread.bindApplication(processName, appInfo, providers,
5205                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5206                    app.instrumentationArguments, app.instrumentationWatcher,
5207                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5208                    isRestrictedBackupMode || !normalMode, app.persistent,
5209                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5210                    mCoreSettingsObserver.getCoreSettingsLocked());
5211            updateLruProcessLocked(app, false, null);
5212            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5213        } catch (Exception e) {
5214            // todo: Yikes!  What should we do?  For now we will try to
5215            // start another process, but that could easily get us in
5216            // an infinite loop of restarting processes...
5217            Slog.w(TAG, "Exception thrown during bind!", e);
5218
5219            app.resetPackageList(mProcessStats);
5220            app.unlinkDeathRecipient();
5221            startProcessLocked(app, "bind fail", processName);
5222            return false;
5223        }
5224
5225        // Remove this record from the list of starting applications.
5226        mPersistentStartingProcesses.remove(app);
5227        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5228                "Attach application locked removing on hold: " + app);
5229        mProcessesOnHold.remove(app);
5230
5231        boolean badApp = false;
5232        boolean didSomething = false;
5233
5234        // See if the top visible activity is waiting to run in this process...
5235        if (normalMode) {
5236            try {
5237                if (mStackSupervisor.attachApplicationLocked(app)) {
5238                    didSomething = true;
5239                }
5240            } catch (Exception e) {
5241                badApp = true;
5242            }
5243        }
5244
5245        // Find any services that should be running in this process...
5246        if (!badApp) {
5247            try {
5248                didSomething |= mServices.attachApplicationLocked(app, processName);
5249            } catch (Exception e) {
5250                badApp = true;
5251            }
5252        }
5253
5254        // Check if a next-broadcast receiver is in this process...
5255        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5256            try {
5257                didSomething |= sendPendingBroadcastsLocked(app);
5258            } catch (Exception e) {
5259                // If the app died trying to launch the receiver we declare it 'bad'
5260                badApp = true;
5261            }
5262        }
5263
5264        // Check whether the next backup agent is in this process...
5265        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5266            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5267            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5268            try {
5269                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5270                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5271                        mBackupTarget.backupMode);
5272            } catch (Exception e) {
5273                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5274                e.printStackTrace();
5275            }
5276        }
5277
5278        if (badApp) {
5279            // todo: Also need to kill application to deal with all
5280            // kinds of exceptions.
5281            handleAppDiedLocked(app, false, true);
5282            return false;
5283        }
5284
5285        if (!didSomething) {
5286            updateOomAdjLocked();
5287        }
5288
5289        return true;
5290    }
5291
5292    @Override
5293    public final void attachApplication(IApplicationThread thread) {
5294        synchronized (this) {
5295            int callingPid = Binder.getCallingPid();
5296            final long origId = Binder.clearCallingIdentity();
5297            attachApplicationLocked(thread, callingPid);
5298            Binder.restoreCallingIdentity(origId);
5299        }
5300    }
5301
5302    @Override
5303    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5304        final long origId = Binder.clearCallingIdentity();
5305        synchronized (this) {
5306            ActivityStack stack = ActivityRecord.getStackLocked(token);
5307            if (stack != null) {
5308                ActivityRecord r =
5309                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5310                if (stopProfiling) {
5311                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5312                        try {
5313                            mProfileFd.close();
5314                        } catch (IOException e) {
5315                        }
5316                        clearProfilerLocked();
5317                    }
5318                }
5319            }
5320        }
5321        Binder.restoreCallingIdentity(origId);
5322    }
5323
5324    void enableScreenAfterBoot() {
5325        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5326                SystemClock.uptimeMillis());
5327        mWindowManager.enableScreenAfterBoot();
5328
5329        synchronized (this) {
5330            updateEventDispatchingLocked();
5331        }
5332    }
5333
5334    @Override
5335    public void showBootMessage(final CharSequence msg, final boolean always) {
5336        enforceNotIsolatedCaller("showBootMessage");
5337        mWindowManager.showBootMessage(msg, always);
5338    }
5339
5340    @Override
5341    public void dismissKeyguardOnNextActivity() {
5342        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5343        final long token = Binder.clearCallingIdentity();
5344        try {
5345            synchronized (this) {
5346                if (DEBUG_LOCKSCREEN) logLockScreen("");
5347                if (mLockScreenShown) {
5348                    mLockScreenShown = false;
5349                    comeOutOfSleepIfNeededLocked();
5350                }
5351                mStackSupervisor.setDismissKeyguard(true);
5352            }
5353        } finally {
5354            Binder.restoreCallingIdentity(token);
5355        }
5356    }
5357
5358    final void finishBooting() {
5359        // Register receivers to handle package update events
5360        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5361
5362        synchronized (this) {
5363            // Ensure that any processes we had put on hold are now started
5364            // up.
5365            final int NP = mProcessesOnHold.size();
5366            if (NP > 0) {
5367                ArrayList<ProcessRecord> procs =
5368                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5369                for (int ip=0; ip<NP; ip++) {
5370                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5371                            + procs.get(ip));
5372                    startProcessLocked(procs.get(ip), "on-hold", null);
5373                }
5374            }
5375
5376            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5377                // Start looking for apps that are abusing wake locks.
5378                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5379                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5380                // Tell anyone interested that we are done booting!
5381                SystemProperties.set("sys.boot_completed", "1");
5382                SystemProperties.set("dev.bootcomplete", "1");
5383                for (int i=0; i<mStartedUsers.size(); i++) {
5384                    UserStartedState uss = mStartedUsers.valueAt(i);
5385                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5386                        uss.mState = UserStartedState.STATE_RUNNING;
5387                        final int userId = mStartedUsers.keyAt(i);
5388                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5389                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5390                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5391                        broadcastIntentLocked(null, null, intent, null,
5392                                new IIntentReceiver.Stub() {
5393                                    @Override
5394                                    public void performReceive(Intent intent, int resultCode,
5395                                            String data, Bundle extras, boolean ordered,
5396                                            boolean sticky, int sendingUser) {
5397                                        synchronized (ActivityManagerService.this) {
5398                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5399                                                    true, false);
5400                                        }
5401                                    }
5402                                },
5403                                0, null, null,
5404                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5405                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5406                                userId);
5407                    }
5408                }
5409                scheduleStartProfilesLocked();
5410            }
5411        }
5412    }
5413
5414    final void ensureBootCompleted() {
5415        boolean booting;
5416        boolean enableScreen;
5417        synchronized (this) {
5418            booting = mBooting;
5419            mBooting = false;
5420            enableScreen = !mBooted;
5421            mBooted = true;
5422        }
5423
5424        if (booting) {
5425            finishBooting();
5426        }
5427
5428        if (enableScreen) {
5429            enableScreenAfterBoot();
5430        }
5431    }
5432
5433    @Override
5434    public final void activityResumed(IBinder token) {
5435        final long origId = Binder.clearCallingIdentity();
5436        synchronized(this) {
5437            ActivityStack stack = ActivityRecord.getStackLocked(token);
5438            if (stack != null) {
5439                ActivityRecord.activityResumedLocked(token);
5440            }
5441        }
5442        Binder.restoreCallingIdentity(origId);
5443    }
5444
5445    @Override
5446    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5447        final long origId = Binder.clearCallingIdentity();
5448        synchronized(this) {
5449            ActivityStack stack = ActivityRecord.getStackLocked(token);
5450            if (stack != null) {
5451                stack.activityPausedLocked(token, false, persistentState);
5452            }
5453        }
5454        Binder.restoreCallingIdentity(origId);
5455    }
5456
5457    @Override
5458    public final void activityStopped(IBinder token, Bundle icicle,
5459            PersistableBundle persistentState, CharSequence description) {
5460        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5461
5462        // Refuse possible leaked file descriptors
5463        if (icicle != null && icicle.hasFileDescriptors()) {
5464            throw new IllegalArgumentException("File descriptors passed in Bundle");
5465        }
5466
5467        final long origId = Binder.clearCallingIdentity();
5468
5469        synchronized (this) {
5470            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5471            if (r != null) {
5472                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5473            }
5474        }
5475
5476        trimApplications();
5477
5478        Binder.restoreCallingIdentity(origId);
5479    }
5480
5481    @Override
5482    public final void activityDestroyed(IBinder token) {
5483        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5484        synchronized (this) {
5485            ActivityStack stack = ActivityRecord.getStackLocked(token);
5486            if (stack != null) {
5487                stack.activityDestroyedLocked(token);
5488            }
5489        }
5490    }
5491
5492    @Override
5493    public String getCallingPackage(IBinder token) {
5494        synchronized (this) {
5495            ActivityRecord r = getCallingRecordLocked(token);
5496            return r != null ? r.info.packageName : null;
5497        }
5498    }
5499
5500    @Override
5501    public ComponentName getCallingActivity(IBinder token) {
5502        synchronized (this) {
5503            ActivityRecord r = getCallingRecordLocked(token);
5504            return r != null ? r.intent.getComponent() : null;
5505        }
5506    }
5507
5508    private ActivityRecord getCallingRecordLocked(IBinder token) {
5509        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5510        if (r == null) {
5511            return null;
5512        }
5513        return r.resultTo;
5514    }
5515
5516    @Override
5517    public ComponentName getActivityClassForToken(IBinder token) {
5518        synchronized(this) {
5519            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5520            if (r == null) {
5521                return null;
5522            }
5523            return r.intent.getComponent();
5524        }
5525    }
5526
5527    @Override
5528    public String getPackageForToken(IBinder token) {
5529        synchronized(this) {
5530            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5531            if (r == null) {
5532                return null;
5533            }
5534            return r.packageName;
5535        }
5536    }
5537
5538    @Override
5539    public IIntentSender getIntentSender(int type,
5540            String packageName, IBinder token, String resultWho,
5541            int requestCode, Intent[] intents, String[] resolvedTypes,
5542            int flags, Bundle options, int userId) {
5543        enforceNotIsolatedCaller("getIntentSender");
5544        // Refuse possible leaked file descriptors
5545        if (intents != null) {
5546            if (intents.length < 1) {
5547                throw new IllegalArgumentException("Intents array length must be >= 1");
5548            }
5549            for (int i=0; i<intents.length; i++) {
5550                Intent intent = intents[i];
5551                if (intent != null) {
5552                    if (intent.hasFileDescriptors()) {
5553                        throw new IllegalArgumentException("File descriptors passed in Intent");
5554                    }
5555                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5556                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5557                        throw new IllegalArgumentException(
5558                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5559                    }
5560                    intents[i] = new Intent(intent);
5561                }
5562            }
5563            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5564                throw new IllegalArgumentException(
5565                        "Intent array length does not match resolvedTypes length");
5566            }
5567        }
5568        if (options != null) {
5569            if (options.hasFileDescriptors()) {
5570                throw new IllegalArgumentException("File descriptors passed in options");
5571            }
5572        }
5573
5574        synchronized(this) {
5575            int callingUid = Binder.getCallingUid();
5576            int origUserId = userId;
5577            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5578                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5579                    "getIntentSender", null);
5580            if (origUserId == UserHandle.USER_CURRENT) {
5581                // We don't want to evaluate this until the pending intent is
5582                // actually executed.  However, we do want to always do the
5583                // security checking for it above.
5584                userId = UserHandle.USER_CURRENT;
5585            }
5586            try {
5587                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5588                    int uid = AppGlobals.getPackageManager()
5589                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5590                    if (!UserHandle.isSameApp(callingUid, uid)) {
5591                        String msg = "Permission Denial: getIntentSender() from pid="
5592                            + Binder.getCallingPid()
5593                            + ", uid=" + Binder.getCallingUid()
5594                            + ", (need uid=" + uid + ")"
5595                            + " is not allowed to send as package " + packageName;
5596                        Slog.w(TAG, msg);
5597                        throw new SecurityException(msg);
5598                    }
5599                }
5600
5601                return getIntentSenderLocked(type, packageName, callingUid, userId,
5602                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5603
5604            } catch (RemoteException e) {
5605                throw new SecurityException(e);
5606            }
5607        }
5608    }
5609
5610    IIntentSender getIntentSenderLocked(int type, String packageName,
5611            int callingUid, int userId, IBinder token, String resultWho,
5612            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5613            Bundle options) {
5614        if (DEBUG_MU)
5615            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5616        ActivityRecord activity = null;
5617        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5618            activity = ActivityRecord.isInStackLocked(token);
5619            if (activity == null) {
5620                return null;
5621            }
5622            if (activity.finishing) {
5623                return null;
5624            }
5625        }
5626
5627        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5628        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5629        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5630        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5631                |PendingIntent.FLAG_UPDATE_CURRENT);
5632
5633        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5634                type, packageName, activity, resultWho,
5635                requestCode, intents, resolvedTypes, flags, options, userId);
5636        WeakReference<PendingIntentRecord> ref;
5637        ref = mIntentSenderRecords.get(key);
5638        PendingIntentRecord rec = ref != null ? ref.get() : null;
5639        if (rec != null) {
5640            if (!cancelCurrent) {
5641                if (updateCurrent) {
5642                    if (rec.key.requestIntent != null) {
5643                        rec.key.requestIntent.replaceExtras(intents != null ?
5644                                intents[intents.length - 1] : null);
5645                    }
5646                    if (intents != null) {
5647                        intents[intents.length-1] = rec.key.requestIntent;
5648                        rec.key.allIntents = intents;
5649                        rec.key.allResolvedTypes = resolvedTypes;
5650                    } else {
5651                        rec.key.allIntents = null;
5652                        rec.key.allResolvedTypes = null;
5653                    }
5654                }
5655                return rec;
5656            }
5657            rec.canceled = true;
5658            mIntentSenderRecords.remove(key);
5659        }
5660        if (noCreate) {
5661            return rec;
5662        }
5663        rec = new PendingIntentRecord(this, key, callingUid);
5664        mIntentSenderRecords.put(key, rec.ref);
5665        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5666            if (activity.pendingResults == null) {
5667                activity.pendingResults
5668                        = new HashSet<WeakReference<PendingIntentRecord>>();
5669            }
5670            activity.pendingResults.add(rec.ref);
5671        }
5672        return rec;
5673    }
5674
5675    @Override
5676    public void cancelIntentSender(IIntentSender sender) {
5677        if (!(sender instanceof PendingIntentRecord)) {
5678            return;
5679        }
5680        synchronized(this) {
5681            PendingIntentRecord rec = (PendingIntentRecord)sender;
5682            try {
5683                int uid = AppGlobals.getPackageManager()
5684                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5685                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5686                    String msg = "Permission Denial: cancelIntentSender() from pid="
5687                        + Binder.getCallingPid()
5688                        + ", uid=" + Binder.getCallingUid()
5689                        + " is not allowed to cancel packges "
5690                        + rec.key.packageName;
5691                    Slog.w(TAG, msg);
5692                    throw new SecurityException(msg);
5693                }
5694            } catch (RemoteException e) {
5695                throw new SecurityException(e);
5696            }
5697            cancelIntentSenderLocked(rec, true);
5698        }
5699    }
5700
5701    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5702        rec.canceled = true;
5703        mIntentSenderRecords.remove(rec.key);
5704        if (cleanActivity && rec.key.activity != null) {
5705            rec.key.activity.pendingResults.remove(rec.ref);
5706        }
5707    }
5708
5709    @Override
5710    public String getPackageForIntentSender(IIntentSender pendingResult) {
5711        if (!(pendingResult instanceof PendingIntentRecord)) {
5712            return null;
5713        }
5714        try {
5715            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5716            return res.key.packageName;
5717        } catch (ClassCastException e) {
5718        }
5719        return null;
5720    }
5721
5722    @Override
5723    public int getUidForIntentSender(IIntentSender sender) {
5724        if (sender instanceof PendingIntentRecord) {
5725            try {
5726                PendingIntentRecord res = (PendingIntentRecord)sender;
5727                return res.uid;
5728            } catch (ClassCastException e) {
5729            }
5730        }
5731        return -1;
5732    }
5733
5734    @Override
5735    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5736        if (!(pendingResult instanceof PendingIntentRecord)) {
5737            return false;
5738        }
5739        try {
5740            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5741            if (res.key.allIntents == null) {
5742                return false;
5743            }
5744            for (int i=0; i<res.key.allIntents.length; i++) {
5745                Intent intent = res.key.allIntents[i];
5746                if (intent.getPackage() != null && intent.getComponent() != null) {
5747                    return false;
5748                }
5749            }
5750            return true;
5751        } catch (ClassCastException e) {
5752        }
5753        return false;
5754    }
5755
5756    @Override
5757    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5758        if (!(pendingResult instanceof PendingIntentRecord)) {
5759            return false;
5760        }
5761        try {
5762            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5763            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5764                return true;
5765            }
5766            return false;
5767        } catch (ClassCastException e) {
5768        }
5769        return false;
5770    }
5771
5772    @Override
5773    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5774        if (!(pendingResult instanceof PendingIntentRecord)) {
5775            return null;
5776        }
5777        try {
5778            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5779            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5780        } catch (ClassCastException e) {
5781        }
5782        return null;
5783    }
5784
5785    @Override
5786    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5787        if (!(pendingResult instanceof PendingIntentRecord)) {
5788            return null;
5789        }
5790        try {
5791            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5792            Intent intent = res.key.requestIntent;
5793            if (intent != null) {
5794                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5795                        || res.lastTagPrefix.equals(prefix))) {
5796                    return res.lastTag;
5797                }
5798                res.lastTagPrefix = prefix;
5799                StringBuilder sb = new StringBuilder(128);
5800                if (prefix != null) {
5801                    sb.append(prefix);
5802                }
5803                if (intent.getAction() != null) {
5804                    sb.append(intent.getAction());
5805                } else if (intent.getComponent() != null) {
5806                    intent.getComponent().appendShortString(sb);
5807                } else {
5808                    sb.append("?");
5809                }
5810                return res.lastTag = sb.toString();
5811            }
5812        } catch (ClassCastException e) {
5813        }
5814        return null;
5815    }
5816
5817    @Override
5818    public void setProcessLimit(int max) {
5819        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5820                "setProcessLimit()");
5821        synchronized (this) {
5822            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5823            mProcessLimitOverride = max;
5824        }
5825        trimApplications();
5826    }
5827
5828    @Override
5829    public int getProcessLimit() {
5830        synchronized (this) {
5831            return mProcessLimitOverride;
5832        }
5833    }
5834
5835    void foregroundTokenDied(ForegroundToken token) {
5836        synchronized (ActivityManagerService.this) {
5837            synchronized (mPidsSelfLocked) {
5838                ForegroundToken cur
5839                    = mForegroundProcesses.get(token.pid);
5840                if (cur != token) {
5841                    return;
5842                }
5843                mForegroundProcesses.remove(token.pid);
5844                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5845                if (pr == null) {
5846                    return;
5847                }
5848                pr.forcingToForeground = null;
5849                updateProcessForegroundLocked(pr, false, false);
5850            }
5851            updateOomAdjLocked();
5852        }
5853    }
5854
5855    @Override
5856    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5857        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5858                "setProcessForeground()");
5859        synchronized(this) {
5860            boolean changed = false;
5861
5862            synchronized (mPidsSelfLocked) {
5863                ProcessRecord pr = mPidsSelfLocked.get(pid);
5864                if (pr == null && isForeground) {
5865                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5866                    return;
5867                }
5868                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5869                if (oldToken != null) {
5870                    oldToken.token.unlinkToDeath(oldToken, 0);
5871                    mForegroundProcesses.remove(pid);
5872                    if (pr != null) {
5873                        pr.forcingToForeground = null;
5874                    }
5875                    changed = true;
5876                }
5877                if (isForeground && token != null) {
5878                    ForegroundToken newToken = new ForegroundToken() {
5879                        @Override
5880                        public void binderDied() {
5881                            foregroundTokenDied(this);
5882                        }
5883                    };
5884                    newToken.pid = pid;
5885                    newToken.token = token;
5886                    try {
5887                        token.linkToDeath(newToken, 0);
5888                        mForegroundProcesses.put(pid, newToken);
5889                        pr.forcingToForeground = token;
5890                        changed = true;
5891                    } catch (RemoteException e) {
5892                        // If the process died while doing this, we will later
5893                        // do the cleanup with the process death link.
5894                    }
5895                }
5896            }
5897
5898            if (changed) {
5899                updateOomAdjLocked();
5900            }
5901        }
5902    }
5903
5904    // =========================================================
5905    // PERMISSIONS
5906    // =========================================================
5907
5908    static class PermissionController extends IPermissionController.Stub {
5909        ActivityManagerService mActivityManagerService;
5910        PermissionController(ActivityManagerService activityManagerService) {
5911            mActivityManagerService = activityManagerService;
5912        }
5913
5914        @Override
5915        public boolean checkPermission(String permission, int pid, int uid) {
5916            return mActivityManagerService.checkPermission(permission, pid,
5917                    uid) == PackageManager.PERMISSION_GRANTED;
5918        }
5919    }
5920
5921    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5922        @Override
5923        public int checkComponentPermission(String permission, int pid, int uid,
5924                int owningUid, boolean exported) {
5925            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5926                    owningUid, exported);
5927        }
5928
5929        @Override
5930        public Object getAMSLock() {
5931            return ActivityManagerService.this;
5932        }
5933    }
5934
5935    /**
5936     * This can be called with or without the global lock held.
5937     */
5938    int checkComponentPermission(String permission, int pid, int uid,
5939            int owningUid, boolean exported) {
5940        // We might be performing an operation on behalf of an indirect binder
5941        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5942        // client identity accordingly before proceeding.
5943        Identity tlsIdentity = sCallerIdentity.get();
5944        if (tlsIdentity != null) {
5945            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5946                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5947            uid = tlsIdentity.uid;
5948            pid = tlsIdentity.pid;
5949        }
5950
5951        if (pid == MY_PID) {
5952            return PackageManager.PERMISSION_GRANTED;
5953        }
5954
5955        return ActivityManager.checkComponentPermission(permission, uid,
5956                owningUid, exported);
5957    }
5958
5959    /**
5960     * As the only public entry point for permissions checking, this method
5961     * can enforce the semantic that requesting a check on a null global
5962     * permission is automatically denied.  (Internally a null permission
5963     * string is used when calling {@link #checkComponentPermission} in cases
5964     * when only uid-based security is needed.)
5965     *
5966     * This can be called with or without the global lock held.
5967     */
5968    @Override
5969    public int checkPermission(String permission, int pid, int uid) {
5970        if (permission == null) {
5971            return PackageManager.PERMISSION_DENIED;
5972        }
5973        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5974    }
5975
5976    /**
5977     * Binder IPC calls go through the public entry point.
5978     * This can be called with or without the global lock held.
5979     */
5980    int checkCallingPermission(String permission) {
5981        return checkPermission(permission,
5982                Binder.getCallingPid(),
5983                UserHandle.getAppId(Binder.getCallingUid()));
5984    }
5985
5986    /**
5987     * This can be called with or without the global lock held.
5988     */
5989    void enforceCallingPermission(String permission, String func) {
5990        if (checkCallingPermission(permission)
5991                == PackageManager.PERMISSION_GRANTED) {
5992            return;
5993        }
5994
5995        String msg = "Permission Denial: " + func + " from pid="
5996                + Binder.getCallingPid()
5997                + ", uid=" + Binder.getCallingUid()
5998                + " requires " + permission;
5999        Slog.w(TAG, msg);
6000        throw new SecurityException(msg);
6001    }
6002
6003    /**
6004     * Determine if UID is holding permissions required to access {@link Uri} in
6005     * the given {@link ProviderInfo}. Final permission checking is always done
6006     * in {@link ContentProvider}.
6007     */
6008    private final boolean checkHoldingPermissionsLocked(
6009            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6010        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6011                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6012
6013        if (pi.applicationInfo.uid == uid) {
6014            return true;
6015        } else if (!pi.exported) {
6016            return false;
6017        }
6018
6019        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6020        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6021        try {
6022            // check if target holds top-level <provider> permissions
6023            if (!readMet && pi.readPermission != null
6024                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6025                readMet = true;
6026            }
6027            if (!writeMet && pi.writePermission != null
6028                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6029                writeMet = true;
6030            }
6031
6032            // track if unprotected read/write is allowed; any denied
6033            // <path-permission> below removes this ability
6034            boolean allowDefaultRead = pi.readPermission == null;
6035            boolean allowDefaultWrite = pi.writePermission == null;
6036
6037            // check if target holds any <path-permission> that match uri
6038            final PathPermission[] pps = pi.pathPermissions;
6039            if (pps != null) {
6040                final String path = grantUri.uri.getPath();
6041                int i = pps.length;
6042                while (i > 0 && (!readMet || !writeMet)) {
6043                    i--;
6044                    PathPermission pp = pps[i];
6045                    if (pp.match(path)) {
6046                        if (!readMet) {
6047                            final String pprperm = pp.getReadPermission();
6048                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6049                                    + pprperm + " for " + pp.getPath()
6050                                    + ": match=" + pp.match(path)
6051                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6052                            if (pprperm != null) {
6053                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6054                                    readMet = true;
6055                                } else {
6056                                    allowDefaultRead = false;
6057                                }
6058                            }
6059                        }
6060                        if (!writeMet) {
6061                            final String ppwperm = pp.getWritePermission();
6062                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6063                                    + ppwperm + " for " + pp.getPath()
6064                                    + ": match=" + pp.match(path)
6065                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6066                            if (ppwperm != null) {
6067                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6068                                    writeMet = true;
6069                                } else {
6070                                    allowDefaultWrite = false;
6071                                }
6072                            }
6073                        }
6074                    }
6075                }
6076            }
6077
6078            // grant unprotected <provider> read/write, if not blocked by
6079            // <path-permission> above
6080            if (allowDefaultRead) readMet = true;
6081            if (allowDefaultWrite) writeMet = true;
6082
6083        } catch (RemoteException e) {
6084            return false;
6085        }
6086
6087        return readMet && writeMet;
6088    }
6089
6090    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6091        ProviderInfo pi = null;
6092        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6093        if (cpr != null) {
6094            pi = cpr.info;
6095        } else {
6096            try {
6097                pi = AppGlobals.getPackageManager().resolveContentProvider(
6098                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6099            } catch (RemoteException ex) {
6100            }
6101        }
6102        return pi;
6103    }
6104
6105    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6106        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6107        if (targetUris != null) {
6108            return targetUris.get(grantUri);
6109        }
6110        return null;
6111    }
6112
6113    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6114            String targetPkg, int targetUid, GrantUri grantUri) {
6115        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6116        if (targetUris == null) {
6117            targetUris = Maps.newArrayMap();
6118            mGrantedUriPermissions.put(targetUid, targetUris);
6119        }
6120
6121        UriPermission perm = targetUris.get(grantUri);
6122        if (perm == null) {
6123            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6124            targetUris.put(grantUri, perm);
6125        }
6126
6127        return perm;
6128    }
6129
6130    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6131            final int modeFlags) {
6132        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6133        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6134                : UriPermission.STRENGTH_OWNED;
6135
6136        // Root gets to do everything.
6137        if (uid == 0) {
6138            return true;
6139        }
6140
6141        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6142        if (perms == null) return false;
6143
6144        // First look for exact match
6145        final UriPermission exactPerm = perms.get(grantUri);
6146        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6147            return true;
6148        }
6149
6150        // No exact match, look for prefixes
6151        final int N = perms.size();
6152        for (int i = 0; i < N; i++) {
6153            final UriPermission perm = perms.valueAt(i);
6154            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6155                    && perm.getStrength(modeFlags) >= minStrength) {
6156                return true;
6157            }
6158        }
6159
6160        return false;
6161    }
6162
6163    @Override
6164    public int checkUriPermission(Uri uri, int pid, int uid,
6165            final int modeFlags, int userId) {
6166        enforceNotIsolatedCaller("checkUriPermission");
6167
6168        // Another redirected-binder-call permissions check as in
6169        // {@link checkComponentPermission}.
6170        Identity tlsIdentity = sCallerIdentity.get();
6171        if (tlsIdentity != null) {
6172            uid = tlsIdentity.uid;
6173            pid = tlsIdentity.pid;
6174        }
6175
6176        // Our own process gets to do everything.
6177        if (pid == MY_PID) {
6178            return PackageManager.PERMISSION_GRANTED;
6179        }
6180        synchronized (this) {
6181            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6182                    ? PackageManager.PERMISSION_GRANTED
6183                    : PackageManager.PERMISSION_DENIED;
6184        }
6185    }
6186
6187    /**
6188     * Check if the targetPkg can be granted permission to access uri by
6189     * the callingUid using the given modeFlags.  Throws a security exception
6190     * if callingUid is not allowed to do this.  Returns the uid of the target
6191     * if the URI permission grant should be performed; returns -1 if it is not
6192     * needed (for example targetPkg already has permission to access the URI).
6193     * If you already know the uid of the target, you can supply it in
6194     * lastTargetUid else set that to -1.
6195     */
6196    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6197            final int modeFlags, int lastTargetUid) {
6198        if (!Intent.isAccessUriMode(modeFlags)) {
6199            return -1;
6200        }
6201
6202        if (targetPkg != null) {
6203            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6204                    "Checking grant " + targetPkg + " permission to " + grantUri);
6205        }
6206
6207        final IPackageManager pm = AppGlobals.getPackageManager();
6208
6209        // If this is not a content: uri, we can't do anything with it.
6210        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6211            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6212                    "Can't grant URI permission for non-content URI: " + grantUri);
6213            return -1;
6214        }
6215
6216        final String authority = grantUri.uri.getAuthority();
6217        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6218        if (pi == null) {
6219            Slog.w(TAG, "No content provider found for permission check: " +
6220                    grantUri.uri.toSafeString());
6221            return -1;
6222        }
6223
6224        int targetUid = lastTargetUid;
6225        if (targetUid < 0 && targetPkg != null) {
6226            try {
6227                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6228                if (targetUid < 0) {
6229                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6230                            "Can't grant URI permission no uid for: " + targetPkg);
6231                    return -1;
6232                }
6233            } catch (RemoteException ex) {
6234                return -1;
6235            }
6236        }
6237
6238        if (targetUid >= 0) {
6239            // First...  does the target actually need this permission?
6240            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6241                // No need to grant the target this permission.
6242                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6243                        "Target " + targetPkg + " already has full permission to " + grantUri);
6244                return -1;
6245            }
6246        } else {
6247            // First...  there is no target package, so can anyone access it?
6248            boolean allowed = pi.exported;
6249            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6250                if (pi.readPermission != null) {
6251                    allowed = false;
6252                }
6253            }
6254            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6255                if (pi.writePermission != null) {
6256                    allowed = false;
6257                }
6258            }
6259            if (allowed) {
6260                return -1;
6261            }
6262        }
6263
6264        // Second...  is the provider allowing granting of URI permissions?
6265        if (!pi.grantUriPermissions) {
6266            throw new SecurityException("Provider " + pi.packageName
6267                    + "/" + pi.name
6268                    + " does not allow granting of Uri permissions (uri "
6269                    + grantUri + ")");
6270        }
6271        if (pi.uriPermissionPatterns != null) {
6272            final int N = pi.uriPermissionPatterns.length;
6273            boolean allowed = false;
6274            for (int i=0; i<N; i++) {
6275                if (pi.uriPermissionPatterns[i] != null
6276                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6277                    allowed = true;
6278                    break;
6279                }
6280            }
6281            if (!allowed) {
6282                throw new SecurityException("Provider " + pi.packageName
6283                        + "/" + pi.name
6284                        + " does not allow granting of permission to path of Uri "
6285                        + grantUri);
6286            }
6287        }
6288
6289        // Third...  does the caller itself have permission to access
6290        // this uri?
6291        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6292            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6293                // Require they hold a strong enough Uri permission
6294                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6295                    throw new SecurityException("Uid " + callingUid
6296                            + " does not have permission to uri " + grantUri);
6297                }
6298            }
6299        }
6300        return targetUid;
6301    }
6302
6303    @Override
6304    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6305            final int modeFlags, int userId) {
6306        enforceNotIsolatedCaller("checkGrantUriPermission");
6307        synchronized(this) {
6308            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6309                    new GrantUri(userId, uri, false), modeFlags, -1);
6310        }
6311    }
6312
6313    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6314            final int modeFlags, UriPermissionOwner owner) {
6315        if (!Intent.isAccessUriMode(modeFlags)) {
6316            return;
6317        }
6318
6319        // So here we are: the caller has the assumed permission
6320        // to the uri, and the target doesn't.  Let's now give this to
6321        // the target.
6322
6323        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6324                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6325
6326        final String authority = grantUri.uri.getAuthority();
6327        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6328        if (pi == null) {
6329            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6330            return;
6331        }
6332
6333        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6334            grantUri.prefix = true;
6335        }
6336        final UriPermission perm = findOrCreateUriPermissionLocked(
6337                pi.packageName, targetPkg, targetUid, grantUri);
6338        perm.grantModes(modeFlags, owner);
6339    }
6340
6341    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6342            final int modeFlags, UriPermissionOwner owner) {
6343        if (targetPkg == null) {
6344            throw new NullPointerException("targetPkg");
6345        }
6346
6347        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6348                -1);
6349        if (targetUid < 0) {
6350            return;
6351        }
6352
6353        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6354                owner);
6355    }
6356
6357    static class NeededUriGrants extends ArrayList<GrantUri> {
6358        final String targetPkg;
6359        final int targetUid;
6360        final int flags;
6361
6362        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6363            this.targetPkg = targetPkg;
6364            this.targetUid = targetUid;
6365            this.flags = flags;
6366        }
6367    }
6368
6369    /**
6370     * Like checkGrantUriPermissionLocked, but takes an Intent.
6371     */
6372    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6373            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6374        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6375                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6376                + " clip=" + (intent != null ? intent.getClipData() : null)
6377                + " from " + intent + "; flags=0x"
6378                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6379
6380        if (targetPkg == null) {
6381            throw new NullPointerException("targetPkg");
6382        }
6383
6384        if (intent == null) {
6385            return null;
6386        }
6387        Uri data = intent.getData();
6388        ClipData clip = intent.getClipData();
6389        if (data == null && clip == null) {
6390            return null;
6391        }
6392
6393        if (data != null) {
6394            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6395            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6396                    needed != null ? needed.targetUid : -1);
6397            if (targetUid > 0) {
6398                if (needed == null) {
6399                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6400                }
6401                needed.add(grantUri);
6402            }
6403        }
6404        if (clip != null) {
6405            for (int i=0; i<clip.getItemCount(); i++) {
6406                Uri uri = clip.getItemAt(i).getUri();
6407                if (uri != null) {
6408                    int targetUid = -1;
6409                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6410                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6411                            needed != null ? needed.targetUid : -1);
6412                    if (targetUid > 0) {
6413                        if (needed == null) {
6414                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6415                        }
6416                        needed.add(grantUri);
6417                    }
6418                } else {
6419                    Intent clipIntent = clip.getItemAt(i).getIntent();
6420                    if (clipIntent != null) {
6421                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6422                                callingUid, targetPkg, clipIntent, mode, needed);
6423                        if (newNeeded != null) {
6424                            needed = newNeeded;
6425                        }
6426                    }
6427                }
6428            }
6429        }
6430
6431        return needed;
6432    }
6433
6434    /**
6435     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6436     */
6437    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6438            UriPermissionOwner owner) {
6439        if (needed != null) {
6440            for (int i=0; i<needed.size(); i++) {
6441                GrantUri grantUri = needed.get(i);
6442                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6443                        grantUri, needed.flags, owner);
6444            }
6445        }
6446    }
6447
6448    void grantUriPermissionFromIntentLocked(int callingUid,
6449            String targetPkg, Intent intent, UriPermissionOwner owner) {
6450        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6451                intent, intent != null ? intent.getFlags() : 0, null);
6452        if (needed == null) {
6453            return;
6454        }
6455
6456        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6457    }
6458
6459    @Override
6460    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6461            final int modeFlags, int userId) {
6462        enforceNotIsolatedCaller("grantUriPermission");
6463        GrantUri grantUri = new GrantUri(userId, uri, false);
6464        synchronized(this) {
6465            final ProcessRecord r = getRecordForAppLocked(caller);
6466            if (r == null) {
6467                throw new SecurityException("Unable to find app for caller "
6468                        + caller
6469                        + " when granting permission to uri " + grantUri);
6470            }
6471            if (targetPkg == null) {
6472                throw new IllegalArgumentException("null target");
6473            }
6474            if (grantUri == null) {
6475                throw new IllegalArgumentException("null uri");
6476            }
6477
6478            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6479                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6480                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6481                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6482
6483            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6484        }
6485    }
6486
6487    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6488        if (perm.modeFlags == 0) {
6489            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6490                    perm.targetUid);
6491            if (perms != null) {
6492                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6493                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6494
6495                perms.remove(perm.uri);
6496                if (perms.isEmpty()) {
6497                    mGrantedUriPermissions.remove(perm.targetUid);
6498                }
6499            }
6500        }
6501    }
6502
6503    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6504        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6505
6506        final IPackageManager pm = AppGlobals.getPackageManager();
6507        final String authority = grantUri.uri.getAuthority();
6508        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6509        if (pi == null) {
6510            Slog.w(TAG, "No content provider found for permission revoke: "
6511                    + grantUri.toSafeString());
6512            return;
6513        }
6514
6515        // Does the caller have this permission on the URI?
6516        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6517            // Right now, if you are not the original owner of the permission,
6518            // you are not allowed to revoke it.
6519            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6520                throw new SecurityException("Uid " + callingUid
6521                        + " does not have permission to uri " + grantUri);
6522            //}
6523        }
6524
6525        boolean persistChanged = false;
6526
6527        // Go through all of the permissions and remove any that match.
6528        int N = mGrantedUriPermissions.size();
6529        for (int i = 0; i < N; i++) {
6530            final int targetUid = mGrantedUriPermissions.keyAt(i);
6531            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6532
6533            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6534                final UriPermission perm = it.next();
6535                if (perm.uri.sourceUserId == grantUri.sourceUserId
6536                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6537                    if (DEBUG_URI_PERMISSION)
6538                        Slog.v(TAG,
6539                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6540                    persistChanged |= perm.revokeModes(
6541                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6542                    if (perm.modeFlags == 0) {
6543                        it.remove();
6544                    }
6545                }
6546            }
6547
6548            if (perms.isEmpty()) {
6549                mGrantedUriPermissions.remove(targetUid);
6550                N--;
6551                i--;
6552            }
6553        }
6554
6555        if (persistChanged) {
6556            schedulePersistUriGrants();
6557        }
6558    }
6559
6560    @Override
6561    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6562            int userId) {
6563        enforceNotIsolatedCaller("revokeUriPermission");
6564        synchronized(this) {
6565            final ProcessRecord r = getRecordForAppLocked(caller);
6566            if (r == null) {
6567                throw new SecurityException("Unable to find app for caller "
6568                        + caller
6569                        + " when revoking permission to uri " + uri);
6570            }
6571            if (uri == null) {
6572                Slog.w(TAG, "revokeUriPermission: null uri");
6573                return;
6574            }
6575
6576            if (!Intent.isAccessUriMode(modeFlags)) {
6577                return;
6578            }
6579
6580            final IPackageManager pm = AppGlobals.getPackageManager();
6581            final String authority = uri.getAuthority();
6582            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6583            if (pi == null) {
6584                Slog.w(TAG, "No content provider found for permission revoke: "
6585                        + uri.toSafeString());
6586                return;
6587            }
6588
6589            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6590        }
6591    }
6592
6593    /**
6594     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6595     * given package.
6596     *
6597     * @param packageName Package name to match, or {@code null} to apply to all
6598     *            packages.
6599     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6600     *            to all users.
6601     * @param persistable If persistable grants should be removed.
6602     */
6603    private void removeUriPermissionsForPackageLocked(
6604            String packageName, int userHandle, boolean persistable) {
6605        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6606            throw new IllegalArgumentException("Must narrow by either package or user");
6607        }
6608
6609        boolean persistChanged = false;
6610
6611        int N = mGrantedUriPermissions.size();
6612        for (int i = 0; i < N; i++) {
6613            final int targetUid = mGrantedUriPermissions.keyAt(i);
6614            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6615
6616            // Only inspect grants matching user
6617            if (userHandle == UserHandle.USER_ALL
6618                    || userHandle == UserHandle.getUserId(targetUid)) {
6619                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6620                    final UriPermission perm = it.next();
6621
6622                    // Only inspect grants matching package
6623                    if (packageName == null || perm.sourcePkg.equals(packageName)
6624                            || perm.targetPkg.equals(packageName)) {
6625                        persistChanged |= perm.revokeModes(
6626                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6627
6628                        // Only remove when no modes remain; any persisted grants
6629                        // will keep this alive.
6630                        if (perm.modeFlags == 0) {
6631                            it.remove();
6632                        }
6633                    }
6634                }
6635
6636                if (perms.isEmpty()) {
6637                    mGrantedUriPermissions.remove(targetUid);
6638                    N--;
6639                    i--;
6640                }
6641            }
6642        }
6643
6644        if (persistChanged) {
6645            schedulePersistUriGrants();
6646        }
6647    }
6648
6649    @Override
6650    public IBinder newUriPermissionOwner(String name) {
6651        enforceNotIsolatedCaller("newUriPermissionOwner");
6652        synchronized(this) {
6653            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6654            return owner.getExternalTokenLocked();
6655        }
6656    }
6657
6658    @Override
6659    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6660            final int modeFlags, int userId) {
6661        synchronized(this) {
6662            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6663            if (owner == null) {
6664                throw new IllegalArgumentException("Unknown owner: " + token);
6665            }
6666            if (fromUid != Binder.getCallingUid()) {
6667                if (Binder.getCallingUid() != Process.myUid()) {
6668                    // Only system code can grant URI permissions on behalf
6669                    // of other users.
6670                    throw new SecurityException("nice try");
6671                }
6672            }
6673            if (targetPkg == null) {
6674                throw new IllegalArgumentException("null target");
6675            }
6676            if (uri == null) {
6677                throw new IllegalArgumentException("null uri");
6678            }
6679
6680            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6681                    modeFlags, owner);
6682        }
6683    }
6684
6685    @Override
6686    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6687        synchronized(this) {
6688            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6689            if (owner == null) {
6690                throw new IllegalArgumentException("Unknown owner: " + token);
6691            }
6692
6693            if (uri == null) {
6694                owner.removeUriPermissionsLocked(mode);
6695            } else {
6696                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6697            }
6698        }
6699    }
6700
6701    private void schedulePersistUriGrants() {
6702        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6703            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6704                    10 * DateUtils.SECOND_IN_MILLIS);
6705        }
6706    }
6707
6708    private void writeGrantedUriPermissions() {
6709        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6710
6711        // Snapshot permissions so we can persist without lock
6712        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6713        synchronized (this) {
6714            final int size = mGrantedUriPermissions.size();
6715            for (int i = 0; i < size; i++) {
6716                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6717                for (UriPermission perm : perms.values()) {
6718                    if (perm.persistedModeFlags != 0) {
6719                        persist.add(perm.snapshot());
6720                    }
6721                }
6722            }
6723        }
6724
6725        FileOutputStream fos = null;
6726        try {
6727            fos = mGrantFile.startWrite();
6728
6729            XmlSerializer out = new FastXmlSerializer();
6730            out.setOutput(fos, "utf-8");
6731            out.startDocument(null, true);
6732            out.startTag(null, TAG_URI_GRANTS);
6733            for (UriPermission.Snapshot perm : persist) {
6734                out.startTag(null, TAG_URI_GRANT);
6735                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6736                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6737                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6738                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6739                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6740                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6741                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6742                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6743                out.endTag(null, TAG_URI_GRANT);
6744            }
6745            out.endTag(null, TAG_URI_GRANTS);
6746            out.endDocument();
6747
6748            mGrantFile.finishWrite(fos);
6749        } catch (IOException e) {
6750            if (fos != null) {
6751                mGrantFile.failWrite(fos);
6752            }
6753        }
6754    }
6755
6756    private void readGrantedUriPermissionsLocked() {
6757        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6758
6759        final long now = System.currentTimeMillis();
6760
6761        FileInputStream fis = null;
6762        try {
6763            fis = mGrantFile.openRead();
6764            final XmlPullParser in = Xml.newPullParser();
6765            in.setInput(fis, null);
6766
6767            int type;
6768            while ((type = in.next()) != END_DOCUMENT) {
6769                final String tag = in.getName();
6770                if (type == START_TAG) {
6771                    if (TAG_URI_GRANT.equals(tag)) {
6772                        final int sourceUserId;
6773                        final int targetUserId;
6774                        final int userHandle = readIntAttribute(in,
6775                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6776                        if (userHandle != UserHandle.USER_NULL) {
6777                            // For backwards compatibility.
6778                            sourceUserId = userHandle;
6779                            targetUserId = userHandle;
6780                        } else {
6781                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6782                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6783                        }
6784                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6785                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6786                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6787                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6788                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6789                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6790
6791                        // Sanity check that provider still belongs to source package
6792                        final ProviderInfo pi = getProviderInfoLocked(
6793                                uri.getAuthority(), sourceUserId);
6794                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6795                            int targetUid = -1;
6796                            try {
6797                                targetUid = AppGlobals.getPackageManager()
6798                                        .getPackageUid(targetPkg, targetUserId);
6799                            } catch (RemoteException e) {
6800                            }
6801                            if (targetUid != -1) {
6802                                final UriPermission perm = findOrCreateUriPermissionLocked(
6803                                        sourcePkg, targetPkg, targetUid,
6804                                        new GrantUri(sourceUserId, uri, prefix));
6805                                perm.initPersistedModes(modeFlags, createdTime);
6806                            }
6807                        } else {
6808                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6809                                    + " but instead found " + pi);
6810                        }
6811                    }
6812                }
6813            }
6814        } catch (FileNotFoundException e) {
6815            // Missing grants is okay
6816        } catch (IOException e) {
6817            Log.wtf(TAG, "Failed reading Uri grants", e);
6818        } catch (XmlPullParserException e) {
6819            Log.wtf(TAG, "Failed reading Uri grants", e);
6820        } finally {
6821            IoUtils.closeQuietly(fis);
6822        }
6823    }
6824
6825    @Override
6826    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6827        enforceNotIsolatedCaller("takePersistableUriPermission");
6828
6829        Preconditions.checkFlagsArgument(modeFlags,
6830                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6831
6832        synchronized (this) {
6833            final int callingUid = Binder.getCallingUid();
6834            boolean persistChanged = false;
6835            GrantUri grantUri = new GrantUri(userId, uri, false);
6836
6837            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6838                    new GrantUri(userId, uri, false));
6839            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6840                    new GrantUri(userId, uri, true));
6841
6842            final boolean exactValid = (exactPerm != null)
6843                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6844            final boolean prefixValid = (prefixPerm != null)
6845                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6846
6847            if (!(exactValid || prefixValid)) {
6848                throw new SecurityException("No persistable permission grants found for UID "
6849                        + callingUid + " and Uri " + grantUri.toSafeString());
6850            }
6851
6852            if (exactValid) {
6853                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6854            }
6855            if (prefixValid) {
6856                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6857            }
6858
6859            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6860
6861            if (persistChanged) {
6862                schedulePersistUriGrants();
6863            }
6864        }
6865    }
6866
6867    @Override
6868    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6869        enforceNotIsolatedCaller("releasePersistableUriPermission");
6870
6871        Preconditions.checkFlagsArgument(modeFlags,
6872                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6873
6874        synchronized (this) {
6875            final int callingUid = Binder.getCallingUid();
6876            boolean persistChanged = false;
6877
6878            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6879                    new GrantUri(userId, uri, false));
6880            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6881                    new GrantUri(userId, uri, true));
6882            if (exactPerm == null && prefixPerm == null) {
6883                throw new SecurityException("No permission grants found for UID " + callingUid
6884                        + " and Uri " + uri.toSafeString());
6885            }
6886
6887            if (exactPerm != null) {
6888                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6889                removeUriPermissionIfNeededLocked(exactPerm);
6890            }
6891            if (prefixPerm != null) {
6892                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6893                removeUriPermissionIfNeededLocked(prefixPerm);
6894            }
6895
6896            if (persistChanged) {
6897                schedulePersistUriGrants();
6898            }
6899        }
6900    }
6901
6902    /**
6903     * Prune any older {@link UriPermission} for the given UID until outstanding
6904     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6905     *
6906     * @return if any mutations occured that require persisting.
6907     */
6908    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6909        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6910        if (perms == null) return false;
6911        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6912
6913        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6914        for (UriPermission perm : perms.values()) {
6915            if (perm.persistedModeFlags != 0) {
6916                persisted.add(perm);
6917            }
6918        }
6919
6920        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6921        if (trimCount <= 0) return false;
6922
6923        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6924        for (int i = 0; i < trimCount; i++) {
6925            final UriPermission perm = persisted.get(i);
6926
6927            if (DEBUG_URI_PERMISSION) {
6928                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6929            }
6930
6931            perm.releasePersistableModes(~0);
6932            removeUriPermissionIfNeededLocked(perm);
6933        }
6934
6935        return true;
6936    }
6937
6938    @Override
6939    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6940            String packageName, boolean incoming) {
6941        enforceNotIsolatedCaller("getPersistedUriPermissions");
6942        Preconditions.checkNotNull(packageName, "packageName");
6943
6944        final int callingUid = Binder.getCallingUid();
6945        final IPackageManager pm = AppGlobals.getPackageManager();
6946        try {
6947            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6948            if (packageUid != callingUid) {
6949                throw new SecurityException(
6950                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6951            }
6952        } catch (RemoteException e) {
6953            throw new SecurityException("Failed to verify package name ownership");
6954        }
6955
6956        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6957        synchronized (this) {
6958            if (incoming) {
6959                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6960                        callingUid);
6961                if (perms == null) {
6962                    Slog.w(TAG, "No permission grants found for " + packageName);
6963                } else {
6964                    for (UriPermission perm : perms.values()) {
6965                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6966                            result.add(perm.buildPersistedPublicApiObject());
6967                        }
6968                    }
6969                }
6970            } else {
6971                final int size = mGrantedUriPermissions.size();
6972                for (int i = 0; i < size; i++) {
6973                    final ArrayMap<GrantUri, UriPermission> perms =
6974                            mGrantedUriPermissions.valueAt(i);
6975                    for (UriPermission perm : perms.values()) {
6976                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6977                            result.add(perm.buildPersistedPublicApiObject());
6978                        }
6979                    }
6980                }
6981            }
6982        }
6983        return new ParceledListSlice<android.content.UriPermission>(result);
6984    }
6985
6986    @Override
6987    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6988        synchronized (this) {
6989            ProcessRecord app =
6990                who != null ? getRecordForAppLocked(who) : null;
6991            if (app == null) return;
6992
6993            Message msg = Message.obtain();
6994            msg.what = WAIT_FOR_DEBUGGER_MSG;
6995            msg.obj = app;
6996            msg.arg1 = waiting ? 1 : 0;
6997            mHandler.sendMessage(msg);
6998        }
6999    }
7000
7001    @Override
7002    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7003        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7004        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7005        outInfo.availMem = Process.getFreeMemory();
7006        outInfo.totalMem = Process.getTotalMemory();
7007        outInfo.threshold = homeAppMem;
7008        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7009        outInfo.hiddenAppThreshold = cachedAppMem;
7010        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7011                ProcessList.SERVICE_ADJ);
7012        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7013                ProcessList.VISIBLE_APP_ADJ);
7014        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7015                ProcessList.FOREGROUND_APP_ADJ);
7016    }
7017
7018    // =========================================================
7019    // TASK MANAGEMENT
7020    // =========================================================
7021
7022    @Override
7023    public List<IAppTask> getAppTasks() {
7024        int callingUid = Binder.getCallingUid();
7025        long ident = Binder.clearCallingIdentity();
7026        synchronized(this) {
7027            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7028            try {
7029                if (localLOGV) Slog.v(TAG, "getAppTasks");
7030
7031                final int N = mRecentTasks.size();
7032                for (int i = 0; i < N; i++) {
7033                    TaskRecord tr = mRecentTasks.get(i);
7034                    // Skip tasks that are not created by the caller
7035                    if (tr.creatorUid == callingUid) {
7036                        ActivityManager.RecentTaskInfo taskInfo =
7037                                createRecentTaskInfoFromTaskRecord(tr);
7038                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7039                        list.add(taskImpl);
7040                    }
7041                }
7042            } finally {
7043                Binder.restoreCallingIdentity(ident);
7044            }
7045            return list;
7046        }
7047    }
7048
7049    @Override
7050    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7051        final int callingUid = Binder.getCallingUid();
7052        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7053
7054        synchronized(this) {
7055            if (localLOGV) Slog.v(
7056                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7057
7058            final boolean allowed = checkCallingPermission(
7059                    android.Manifest.permission.GET_TASKS)
7060                    == PackageManager.PERMISSION_GRANTED;
7061            if (!allowed) {
7062                Slog.w(TAG, "getTasks: caller " + callingUid
7063                        + " does not hold GET_TASKS; limiting output");
7064            }
7065
7066            // TODO: Improve with MRU list from all ActivityStacks.
7067            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7068        }
7069
7070        return list;
7071    }
7072
7073    TaskRecord getMostRecentTask() {
7074        return mRecentTasks.get(0);
7075    }
7076
7077    /**
7078     * Creates a new RecentTaskInfo from a TaskRecord.
7079     */
7080    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7081        ActivityManager.RecentTaskInfo rti
7082                = new ActivityManager.RecentTaskInfo();
7083        rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7084        rti.persistentId = tr.taskId;
7085        rti.baseIntent = new Intent(tr.getBaseIntent());
7086        rti.origActivity = tr.origActivity;
7087        rti.description = tr.lastDescription;
7088        rti.stackId = tr.stack.mStackId;
7089        rti.userId = tr.userId;
7090
7091        // Traverse upwards looking for any break between main task activities and
7092        // utility activities.
7093        final ArrayList<ActivityRecord> activities = tr.mActivities;
7094        int activityNdx;
7095        final int numActivities = activities.size();
7096        for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7097             ++activityNdx) {
7098            final ActivityRecord r = activities.get(activityNdx);
7099            if (r.intent != null &&
7100                    (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7101                            != 0) {
7102                break;
7103            }
7104        }
7105        if (activityNdx > 0) {
7106            // Traverse downwards starting below break looking for set label, icon.
7107            // Note that if there are activities in the task but none of them set the
7108            // recent activity values, then we do not fall back to the last set
7109            // values in the TaskRecord.
7110            rti.activityValues = new ActivityManager.RecentsActivityValues();
7111            for (--activityNdx; activityNdx >= 0; --activityNdx) {
7112                final ActivityRecord r = activities.get(activityNdx);
7113                if (r.activityValues != null) {
7114                    if (rti.activityValues.label == null) {
7115                        rti.activityValues.label = r.activityValues.label;
7116                        tr.lastActivityValues.label = r.activityValues.label;
7117                    }
7118                    if (rti.activityValues.icon == null) {
7119                        rti.activityValues.icon = r.activityValues.icon;
7120                        tr.lastActivityValues.icon = r.activityValues.icon;
7121                    }
7122                    if (rti.activityValues.colorPrimary == 0) {
7123                        rti.activityValues.colorPrimary = r.activityValues.colorPrimary;
7124                        tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary;
7125                    }
7126                }
7127            }
7128        } else {
7129            // If there are no activity records in this task, then we use the last
7130            // resolved values
7131            rti.activityValues =
7132                    new ActivityManager.RecentsActivityValues(tr.lastActivityValues);
7133        }
7134        return rti;
7135    }
7136
7137    @Override
7138    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7139            int flags, int userId) {
7140        final int callingUid = Binder.getCallingUid();
7141        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7142                false, true, "getRecentTasks", null);
7143
7144        synchronized (this) {
7145            final boolean allowed = checkCallingPermission(
7146                    android.Manifest.permission.GET_TASKS)
7147                    == PackageManager.PERMISSION_GRANTED;
7148            if (!allowed) {
7149                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7150                        + " does not hold GET_TASKS; limiting output");
7151            }
7152            final boolean detailed = checkCallingPermission(
7153                    android.Manifest.permission.GET_DETAILED_TASKS)
7154                    == PackageManager.PERMISSION_GRANTED;
7155
7156            IPackageManager pm = AppGlobals.getPackageManager();
7157
7158            final int N = mRecentTasks.size();
7159            ArrayList<ActivityManager.RecentTaskInfo> res
7160                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7161                            maxNum < N ? maxNum : N);
7162
7163            final Set<Integer> includedUsers;
7164            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7165                includedUsers = getProfileIdsLocked(userId);
7166            } else {
7167                includedUsers = new HashSet<Integer>();
7168            }
7169            includedUsers.add(Integer.valueOf(userId));
7170            for (int i=0; i<N && maxNum > 0; i++) {
7171                TaskRecord tr = mRecentTasks.get(i);
7172                // Only add calling user or related users recent tasks
7173                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7174
7175                // Return the entry if desired by the caller.  We always return
7176                // the first entry, because callers always expect this to be the
7177                // foreground app.  We may filter others if the caller has
7178                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7179                // we should exclude the entry.
7180
7181                if (i == 0
7182                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7183                        || (tr.intent == null)
7184                        || ((tr.intent.getFlags()
7185                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7186                    if (!allowed) {
7187                        // If the caller doesn't have the GET_TASKS permission, then only
7188                        // allow them to see a small subset of tasks -- their own and home.
7189                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7190                            continue;
7191                        }
7192                    }
7193
7194                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7195                    if (!detailed) {
7196                        rti.baseIntent.replaceExtras((Bundle)null);
7197                    }
7198
7199                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7200                        // Check whether this activity is currently available.
7201                        try {
7202                            if (rti.origActivity != null) {
7203                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7204                                        == null) {
7205                                    continue;
7206                                }
7207                            } else if (rti.baseIntent != null) {
7208                                if (pm.queryIntentActivities(rti.baseIntent,
7209                                        null, 0, userId) == null) {
7210                                    continue;
7211                                }
7212                            }
7213                        } catch (RemoteException e) {
7214                            // Will never happen.
7215                        }
7216                    }
7217
7218                    res.add(rti);
7219                    maxNum--;
7220                }
7221            }
7222            return res;
7223        }
7224    }
7225
7226    private TaskRecord recentTaskForIdLocked(int id) {
7227        final int N = mRecentTasks.size();
7228            for (int i=0; i<N; i++) {
7229                TaskRecord tr = mRecentTasks.get(i);
7230                if (tr.taskId == id) {
7231                    return tr;
7232                }
7233            }
7234            return null;
7235    }
7236
7237    @Override
7238    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7239        synchronized (this) {
7240            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7241                    "getTaskThumbnails()");
7242            TaskRecord tr = recentTaskForIdLocked(id);
7243            if (tr != null) {
7244                return tr.getTaskThumbnailsLocked();
7245            }
7246        }
7247        return null;
7248    }
7249
7250    @Override
7251    public Bitmap getTaskTopThumbnail(int id) {
7252        synchronized (this) {
7253            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7254                    "getTaskTopThumbnail()");
7255            TaskRecord tr = recentTaskForIdLocked(id);
7256            if (tr != null) {
7257                return tr.getTaskTopThumbnailLocked();
7258            }
7259        }
7260        return null;
7261    }
7262
7263    @Override
7264    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) {
7265        synchronized (this) {
7266            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7267            if (r != null) {
7268                r.activityValues = rav;
7269            }
7270        }
7271    }
7272
7273    @Override
7274    public boolean removeSubTask(int taskId, int subTaskIndex) {
7275        synchronized (this) {
7276            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7277                    "removeSubTask()");
7278            long ident = Binder.clearCallingIdentity();
7279            try {
7280                TaskRecord tr = recentTaskForIdLocked(taskId);
7281                if (tr != null) {
7282                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7283                }
7284                return false;
7285            } finally {
7286                Binder.restoreCallingIdentity(ident);
7287            }
7288        }
7289    }
7290
7291    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7292        if (!pr.killedByAm) {
7293            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7294            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7295                    pr.processName, pr.setAdj, reason);
7296            pr.killedByAm = true;
7297            Process.killProcessQuiet(pr.pid);
7298        }
7299    }
7300
7301    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7302        tr.disposeThumbnail();
7303        mRecentTasks.remove(tr);
7304        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7305        Intent baseIntent = new Intent(
7306                tr.intent != null ? tr.intent : tr.affinityIntent);
7307        ComponentName component = baseIntent.getComponent();
7308        if (component == null) {
7309            Slog.w(TAG, "Now component for base intent of task: " + tr);
7310            return;
7311        }
7312
7313        // Find any running services associated with this app.
7314        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7315
7316        if (killProcesses) {
7317            // Find any running processes associated with this app.
7318            final String pkg = component.getPackageName();
7319            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7320            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7321            for (int i=0; i<pmap.size(); i++) {
7322                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7323                for (int j=0; j<uids.size(); j++) {
7324                    ProcessRecord proc = uids.valueAt(j);
7325                    if (proc.userId != tr.userId) {
7326                        continue;
7327                    }
7328                    if (!proc.pkgList.containsKey(pkg)) {
7329                        continue;
7330                    }
7331                    procs.add(proc);
7332                }
7333            }
7334
7335            // Kill the running processes.
7336            for (int i=0; i<procs.size(); i++) {
7337                ProcessRecord pr = procs.get(i);
7338                if (pr == mHomeProcess) {
7339                    // Don't kill the home process along with tasks from the same package.
7340                    continue;
7341                }
7342                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7343                    killUnneededProcessLocked(pr, "remove task");
7344                } else {
7345                    pr.waitingToKill = "remove task";
7346                }
7347            }
7348        }
7349    }
7350
7351    /**
7352     * Removes the task with the specified task id.
7353     *
7354     * @param taskId Identifier of the task to be removed.
7355     * @param flags Additional operational flags.  May be 0 or
7356     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7357     * @return Returns true if the given task was found and removed.
7358     */
7359    private boolean removeTaskByIdLocked(int taskId, int flags) {
7360        TaskRecord tr = recentTaskForIdLocked(taskId);
7361        if (tr != null) {
7362            tr.removeTaskActivitiesLocked(-1, false);
7363            cleanUpRemovedTaskLocked(tr, flags);
7364            return true;
7365        }
7366        return false;
7367    }
7368
7369    @Override
7370    public boolean removeTask(int taskId, int flags) {
7371        synchronized (this) {
7372            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7373                    "removeTask()");
7374            long ident = Binder.clearCallingIdentity();
7375            try {
7376                return removeTaskByIdLocked(taskId, flags);
7377            } finally {
7378                Binder.restoreCallingIdentity(ident);
7379            }
7380        }
7381    }
7382
7383    /**
7384     * TODO: Add mController hook
7385     */
7386    @Override
7387    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7388        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7389                "moveTaskToFront()");
7390
7391        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7392        synchronized(this) {
7393            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7394                    Binder.getCallingUid(), "Task to front")) {
7395                ActivityOptions.abort(options);
7396                return;
7397            }
7398            final long origId = Binder.clearCallingIdentity();
7399            try {
7400                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7401                if (task == null) {
7402                    return;
7403                }
7404                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7405                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7406                    return;
7407                }
7408                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7409            } finally {
7410                Binder.restoreCallingIdentity(origId);
7411            }
7412            ActivityOptions.abort(options);
7413        }
7414    }
7415
7416    @Override
7417    public void moveTaskToBack(int taskId) {
7418        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7419                "moveTaskToBack()");
7420
7421        synchronized(this) {
7422            TaskRecord tr = recentTaskForIdLocked(taskId);
7423            if (tr != null) {
7424                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7425                ActivityStack stack = tr.stack;
7426                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7427                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7428                            Binder.getCallingUid(), "Task to back")) {
7429                        return;
7430                    }
7431                }
7432                final long origId = Binder.clearCallingIdentity();
7433                try {
7434                    stack.moveTaskToBackLocked(taskId, null);
7435                } finally {
7436                    Binder.restoreCallingIdentity(origId);
7437                }
7438            }
7439        }
7440    }
7441
7442    /**
7443     * Moves an activity, and all of the other activities within the same task, to the bottom
7444     * of the history stack.  The activity's order within the task is unchanged.
7445     *
7446     * @param token A reference to the activity we wish to move
7447     * @param nonRoot If false then this only works if the activity is the root
7448     *                of a task; if true it will work for any activity in a task.
7449     * @return Returns true if the move completed, false if not.
7450     */
7451    @Override
7452    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7453        enforceNotIsolatedCaller("moveActivityTaskToBack");
7454        synchronized(this) {
7455            final long origId = Binder.clearCallingIdentity();
7456            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7457            if (taskId >= 0) {
7458                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7459            }
7460            Binder.restoreCallingIdentity(origId);
7461        }
7462        return false;
7463    }
7464
7465    @Override
7466    public void moveTaskBackwards(int task) {
7467        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7468                "moveTaskBackwards()");
7469
7470        synchronized(this) {
7471            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7472                    Binder.getCallingUid(), "Task backwards")) {
7473                return;
7474            }
7475            final long origId = Binder.clearCallingIdentity();
7476            moveTaskBackwardsLocked(task);
7477            Binder.restoreCallingIdentity(origId);
7478        }
7479    }
7480
7481    private final void moveTaskBackwardsLocked(int task) {
7482        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7483    }
7484
7485    @Override
7486    public IBinder getHomeActivityToken() throws RemoteException {
7487        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7488                "getHomeActivityToken()");
7489        synchronized (this) {
7490            return mStackSupervisor.getHomeActivityToken();
7491        }
7492    }
7493
7494    @Override
7495    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7496            IActivityContainerCallback callback) throws RemoteException {
7497        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7498                "createActivityContainer()");
7499        synchronized (this) {
7500            if (parentActivityToken == null) {
7501                throw new IllegalArgumentException("parent token must not be null");
7502            }
7503            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7504            if (r == null) {
7505                return null;
7506            }
7507            if (callback == null) {
7508                throw new IllegalArgumentException("callback must not be null");
7509            }
7510            return mStackSupervisor.createActivityContainer(r, callback);
7511        }
7512    }
7513
7514    @Override
7515    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7516        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7517                "deleteActivityContainer()");
7518        synchronized (this) {
7519            mStackSupervisor.deleteActivityContainer(container);
7520        }
7521    }
7522
7523    @Override
7524    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7525            throws RemoteException {
7526        synchronized (this) {
7527            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7528            if (stack != null) {
7529                return stack.mActivityContainer;
7530            }
7531            return null;
7532        }
7533    }
7534
7535    @Override
7536    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7537        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7538                "moveTaskToStack()");
7539        if (stackId == HOME_STACK_ID) {
7540            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7541                    new RuntimeException("here").fillInStackTrace());
7542        }
7543        synchronized (this) {
7544            long ident = Binder.clearCallingIdentity();
7545            try {
7546                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7547                        + stackId + " toTop=" + toTop);
7548                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7549            } finally {
7550                Binder.restoreCallingIdentity(ident);
7551            }
7552        }
7553    }
7554
7555    @Override
7556    public void resizeStack(int stackBoxId, Rect bounds) {
7557        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7558                "resizeStackBox()");
7559        long ident = Binder.clearCallingIdentity();
7560        try {
7561            mWindowManager.resizeStack(stackBoxId, bounds);
7562        } finally {
7563            Binder.restoreCallingIdentity(ident);
7564        }
7565    }
7566
7567    @Override
7568    public List<StackInfo> getAllStackInfos() {
7569        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7570                "getAllStackInfos()");
7571        long ident = Binder.clearCallingIdentity();
7572        try {
7573            synchronized (this) {
7574                return mStackSupervisor.getAllStackInfosLocked();
7575            }
7576        } finally {
7577            Binder.restoreCallingIdentity(ident);
7578        }
7579    }
7580
7581    @Override
7582    public StackInfo getStackInfo(int stackId) {
7583        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7584                "getStackInfo()");
7585        long ident = Binder.clearCallingIdentity();
7586        try {
7587            synchronized (this) {
7588                return mStackSupervisor.getStackInfoLocked(stackId);
7589            }
7590        } finally {
7591            Binder.restoreCallingIdentity(ident);
7592        }
7593    }
7594
7595    @Override
7596    public boolean isInHomeStack(int taskId) {
7597        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7598                "getStackInfo()");
7599        long ident = Binder.clearCallingIdentity();
7600        try {
7601            synchronized (this) {
7602                TaskRecord tr = recentTaskForIdLocked(taskId);
7603                if (tr != null) {
7604                    return tr.stack.isHomeStack();
7605                }
7606            }
7607        } finally {
7608            Binder.restoreCallingIdentity(ident);
7609        }
7610        return false;
7611    }
7612
7613    @Override
7614    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7615        synchronized(this) {
7616            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7617        }
7618    }
7619
7620    private boolean isLockTaskAuthorized(ComponentName name) {
7621//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7622//                "startLockTaskMode()");
7623//        DevicePolicyManager dpm = (DevicePolicyManager)
7624//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7625//        return dpm != null && dpm.isLockTaskPermitted(name);
7626        return true;
7627    }
7628
7629    private void startLockTaskMode(TaskRecord task) {
7630        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7631            return;
7632        }
7633        long ident = Binder.clearCallingIdentity();
7634        try {
7635            synchronized (this) {
7636                // Since we lost lock on task, make sure it is still there.
7637                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7638                if (task != null) {
7639                    mStackSupervisor.setLockTaskModeLocked(task);
7640                }
7641            }
7642        } finally {
7643            Binder.restoreCallingIdentity(ident);
7644        }
7645    }
7646
7647    @Override
7648    public void startLockTaskMode(int taskId) {
7649        long ident = Binder.clearCallingIdentity();
7650        try {
7651            final TaskRecord task;
7652            synchronized (this) {
7653                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7654            }
7655            if (task != null) {
7656                startLockTaskMode(task);
7657            }
7658        } finally {
7659            Binder.restoreCallingIdentity(ident);
7660        }
7661    }
7662
7663    @Override
7664    public void startLockTaskMode(IBinder token) {
7665        long ident = Binder.clearCallingIdentity();
7666        try {
7667            final TaskRecord task;
7668            synchronized (this) {
7669                final ActivityRecord r = ActivityRecord.forToken(token);
7670                if (r == null) {
7671                    return;
7672                }
7673                task = r.task;
7674            }
7675            if (task != null) {
7676                startLockTaskMode(task);
7677            }
7678        } finally {
7679            Binder.restoreCallingIdentity(ident);
7680        }
7681    }
7682
7683    @Override
7684    public void stopLockTaskMode() {
7685//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7686//                "stopLockTaskMode()");
7687        synchronized (this) {
7688            mStackSupervisor.setLockTaskModeLocked(null);
7689        }
7690    }
7691
7692    @Override
7693    public boolean isInLockTaskMode() {
7694        synchronized (this) {
7695            return mStackSupervisor.isInLockTaskMode();
7696        }
7697    }
7698
7699    // =========================================================
7700    // CONTENT PROVIDERS
7701    // =========================================================
7702
7703    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7704        List<ProviderInfo> providers = null;
7705        try {
7706            providers = AppGlobals.getPackageManager().
7707                queryContentProviders(app.processName, app.uid,
7708                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7709        } catch (RemoteException ex) {
7710        }
7711        if (DEBUG_MU)
7712            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7713        int userId = app.userId;
7714        if (providers != null) {
7715            int N = providers.size();
7716            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7717            for (int i=0; i<N; i++) {
7718                ProviderInfo cpi =
7719                    (ProviderInfo)providers.get(i);
7720                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7721                        cpi.name, cpi.flags);
7722                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7723                    // This is a singleton provider, but a user besides the
7724                    // default user is asking to initialize a process it runs
7725                    // in...  well, no, it doesn't actually run in this process,
7726                    // it runs in the process of the default user.  Get rid of it.
7727                    providers.remove(i);
7728                    N--;
7729                    i--;
7730                    continue;
7731                }
7732
7733                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7734                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7735                if (cpr == null) {
7736                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7737                    mProviderMap.putProviderByClass(comp, cpr);
7738                }
7739                if (DEBUG_MU)
7740                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7741                app.pubProviders.put(cpi.name, cpr);
7742                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7743                    // Don't add this if it is a platform component that is marked
7744                    // to run in multiple processes, because this is actually
7745                    // part of the framework so doesn't make sense to track as a
7746                    // separate apk in the process.
7747                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7748                }
7749                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7750            }
7751        }
7752        return providers;
7753    }
7754
7755    /**
7756     * Check if {@link ProcessRecord} has a possible chance at accessing the
7757     * given {@link ProviderInfo}. Final permission checking is always done
7758     * in {@link ContentProvider}.
7759     */
7760    private final String checkContentProviderPermissionLocked(
7761            ProviderInfo cpi, ProcessRecord r, int userId) {
7762        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7763        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7764        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7765        // Looking for cross-user grants before to enforce the typical cross-users permissions
7766        if (userId != UserHandle.getUserId(callingUid)) {
7767            if (perms != null) {
7768                for (GrantUri grantUri : perms.keySet()) {
7769                    if (grantUri.sourceUserId == userId) {
7770                        String authority = grantUri.uri.getAuthority();
7771                        if (authority.equals(cpi.authority)) {
7772                            return null;
7773                        }
7774                    }
7775                }
7776            }
7777        }
7778        userId = handleIncomingUser(callingPid, callingUid, userId,
7779                false, true, "checkContentProviderPermissionLocked", null);
7780        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7781                cpi.applicationInfo.uid, cpi.exported)
7782                == PackageManager.PERMISSION_GRANTED) {
7783            return null;
7784        }
7785        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7786                cpi.applicationInfo.uid, cpi.exported)
7787                == PackageManager.PERMISSION_GRANTED) {
7788            return null;
7789        }
7790
7791        PathPermission[] pps = cpi.pathPermissions;
7792        if (pps != null) {
7793            int i = pps.length;
7794            while (i > 0) {
7795                i--;
7796                PathPermission pp = pps[i];
7797                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7798                        cpi.applicationInfo.uid, cpi.exported)
7799                        == PackageManager.PERMISSION_GRANTED) {
7800                    return null;
7801                }
7802                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7803                        cpi.applicationInfo.uid, cpi.exported)
7804                        == PackageManager.PERMISSION_GRANTED) {
7805                    return null;
7806                }
7807            }
7808        }
7809
7810        if (perms != null) {
7811            for (GrantUri grantUri : perms.keySet()) {
7812                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7813                    return null;
7814                }
7815            }
7816        }
7817
7818        String msg;
7819        if (!cpi.exported) {
7820            msg = "Permission Denial: opening provider " + cpi.name
7821                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7822                    + ", uid=" + callingUid + ") that is not exported from uid "
7823                    + cpi.applicationInfo.uid;
7824        } else {
7825            msg = "Permission Denial: opening provider " + cpi.name
7826                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7827                    + ", uid=" + callingUid + ") requires "
7828                    + cpi.readPermission + " or " + cpi.writePermission;
7829        }
7830        Slog.w(TAG, msg);
7831        return msg;
7832    }
7833
7834    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7835            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7836        if (r != null) {
7837            for (int i=0; i<r.conProviders.size(); i++) {
7838                ContentProviderConnection conn = r.conProviders.get(i);
7839                if (conn.provider == cpr) {
7840                    if (DEBUG_PROVIDER) Slog.v(TAG,
7841                            "Adding provider requested by "
7842                            + r.processName + " from process "
7843                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7844                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7845                    if (stable) {
7846                        conn.stableCount++;
7847                        conn.numStableIncs++;
7848                    } else {
7849                        conn.unstableCount++;
7850                        conn.numUnstableIncs++;
7851                    }
7852                    return conn;
7853                }
7854            }
7855            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7856            if (stable) {
7857                conn.stableCount = 1;
7858                conn.numStableIncs = 1;
7859            } else {
7860                conn.unstableCount = 1;
7861                conn.numUnstableIncs = 1;
7862            }
7863            cpr.connections.add(conn);
7864            r.conProviders.add(conn);
7865            return conn;
7866        }
7867        cpr.addExternalProcessHandleLocked(externalProcessToken);
7868        return null;
7869    }
7870
7871    boolean decProviderCountLocked(ContentProviderConnection conn,
7872            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7873        if (conn != null) {
7874            cpr = conn.provider;
7875            if (DEBUG_PROVIDER) Slog.v(TAG,
7876                    "Removing provider requested by "
7877                    + conn.client.processName + " from process "
7878                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7879                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7880            if (stable) {
7881                conn.stableCount--;
7882            } else {
7883                conn.unstableCount--;
7884            }
7885            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7886                cpr.connections.remove(conn);
7887                conn.client.conProviders.remove(conn);
7888                return true;
7889            }
7890            return false;
7891        }
7892        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7893        return false;
7894    }
7895
7896    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7897            String name, IBinder token, boolean stable, int userId) {
7898        ContentProviderRecord cpr;
7899        ContentProviderConnection conn = null;
7900        ProviderInfo cpi = null;
7901
7902        synchronized(this) {
7903            ProcessRecord r = null;
7904            if (caller != null) {
7905                r = getRecordForAppLocked(caller);
7906                if (r == null) {
7907                    throw new SecurityException(
7908                            "Unable to find app for caller " + caller
7909                          + " (pid=" + Binder.getCallingPid()
7910                          + ") when getting content provider " + name);
7911                }
7912            }
7913
7914            // First check if this content provider has been published...
7915            cpr = mProviderMap.getProviderByName(name, userId);
7916            boolean providerRunning = cpr != null;
7917            if (providerRunning) {
7918                cpi = cpr.info;
7919                String msg;
7920                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7921                    throw new SecurityException(msg);
7922                }
7923
7924                if (r != null && cpr.canRunHere(r)) {
7925                    // This provider has been published or is in the process
7926                    // of being published...  but it is also allowed to run
7927                    // in the caller's process, so don't make a connection
7928                    // and just let the caller instantiate its own instance.
7929                    ContentProviderHolder holder = cpr.newHolder(null);
7930                    // don't give caller the provider object, it needs
7931                    // to make its own.
7932                    holder.provider = null;
7933                    return holder;
7934                }
7935
7936                final long origId = Binder.clearCallingIdentity();
7937
7938                // In this case the provider instance already exists, so we can
7939                // return it right away.
7940                conn = incProviderCountLocked(r, cpr, token, stable);
7941                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7942                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7943                        // If this is a perceptible app accessing the provider,
7944                        // make sure to count it as being accessed and thus
7945                        // back up on the LRU list.  This is good because
7946                        // content providers are often expensive to start.
7947                        updateLruProcessLocked(cpr.proc, false, null);
7948                    }
7949                }
7950
7951                if (cpr.proc != null) {
7952                    if (false) {
7953                        if (cpr.name.flattenToShortString().equals(
7954                                "com.android.providers.calendar/.CalendarProvider2")) {
7955                            Slog.v(TAG, "****************** KILLING "
7956                                + cpr.name.flattenToShortString());
7957                            Process.killProcess(cpr.proc.pid);
7958                        }
7959                    }
7960                    boolean success = updateOomAdjLocked(cpr.proc);
7961                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7962                    // NOTE: there is still a race here where a signal could be
7963                    // pending on the process even though we managed to update its
7964                    // adj level.  Not sure what to do about this, but at least
7965                    // the race is now smaller.
7966                    if (!success) {
7967                        // Uh oh...  it looks like the provider's process
7968                        // has been killed on us.  We need to wait for a new
7969                        // process to be started, and make sure its death
7970                        // doesn't kill our process.
7971                        Slog.i(TAG,
7972                                "Existing provider " + cpr.name.flattenToShortString()
7973                                + " is crashing; detaching " + r);
7974                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7975                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7976                        if (!lastRef) {
7977                            // This wasn't the last ref our process had on
7978                            // the provider...  we have now been killed, bail.
7979                            return null;
7980                        }
7981                        providerRunning = false;
7982                        conn = null;
7983                    }
7984                }
7985
7986                Binder.restoreCallingIdentity(origId);
7987            }
7988
7989            boolean singleton;
7990            if (!providerRunning) {
7991                try {
7992                    cpi = AppGlobals.getPackageManager().
7993                        resolveContentProvider(name,
7994                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7995                } catch (RemoteException ex) {
7996                }
7997                if (cpi == null) {
7998                    return null;
7999                }
8000                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8001                        cpi.name, cpi.flags);
8002                if (singleton) {
8003                    userId = 0;
8004                }
8005                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8006
8007                String msg;
8008                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
8009                    throw new SecurityException(msg);
8010                }
8011
8012                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8013                        && !cpi.processName.equals("system")) {
8014                    // If this content provider does not run in the system
8015                    // process, and the system is not yet ready to run other
8016                    // processes, then fail fast instead of hanging.
8017                    throw new IllegalArgumentException(
8018                            "Attempt to launch content provider before system ready");
8019                }
8020
8021                // Make sure that the user who owns this provider is started.  If not,
8022                // we don't want to allow it to run.
8023                if (mStartedUsers.get(userId) == null) {
8024                    Slog.w(TAG, "Unable to launch app "
8025                            + cpi.applicationInfo.packageName + "/"
8026                            + cpi.applicationInfo.uid + " for provider "
8027                            + name + ": user " + userId + " is stopped");
8028                    return null;
8029                }
8030
8031                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8032                cpr = mProviderMap.getProviderByClass(comp, userId);
8033                final boolean firstClass = cpr == null;
8034                if (firstClass) {
8035                    try {
8036                        ApplicationInfo ai =
8037                            AppGlobals.getPackageManager().
8038                                getApplicationInfo(
8039                                        cpi.applicationInfo.packageName,
8040                                        STOCK_PM_FLAGS, userId);
8041                        if (ai == null) {
8042                            Slog.w(TAG, "No package info for content provider "
8043                                    + cpi.name);
8044                            return null;
8045                        }
8046                        ai = getAppInfoForUser(ai, userId);
8047                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8048                    } catch (RemoteException ex) {
8049                        // pm is in same process, this will never happen.
8050                    }
8051                }
8052
8053                if (r != null && cpr.canRunHere(r)) {
8054                    // If this is a multiprocess provider, then just return its
8055                    // info and allow the caller to instantiate it.  Only do
8056                    // this if the provider is the same user as the caller's
8057                    // process, or can run as root (so can be in any process).
8058                    return cpr.newHolder(null);
8059                }
8060
8061                if (DEBUG_PROVIDER) {
8062                    RuntimeException e = new RuntimeException("here");
8063                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8064                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8065                }
8066
8067                // This is single process, and our app is now connecting to it.
8068                // See if we are already in the process of launching this
8069                // provider.
8070                final int N = mLaunchingProviders.size();
8071                int i;
8072                for (i=0; i<N; i++) {
8073                    if (mLaunchingProviders.get(i) == cpr) {
8074                        break;
8075                    }
8076                }
8077
8078                // If the provider is not already being launched, then get it
8079                // started.
8080                if (i >= N) {
8081                    final long origId = Binder.clearCallingIdentity();
8082
8083                    try {
8084                        // Content provider is now in use, its package can't be stopped.
8085                        try {
8086                            AppGlobals.getPackageManager().setPackageStoppedState(
8087                                    cpr.appInfo.packageName, false, userId);
8088                        } catch (RemoteException e) {
8089                        } catch (IllegalArgumentException e) {
8090                            Slog.w(TAG, "Failed trying to unstop package "
8091                                    + cpr.appInfo.packageName + ": " + e);
8092                        }
8093
8094                        // Use existing process if already started
8095                        ProcessRecord proc = getProcessRecordLocked(
8096                                cpi.processName, cpr.appInfo.uid, false);
8097                        if (proc != null && proc.thread != null) {
8098                            if (DEBUG_PROVIDER) {
8099                                Slog.d(TAG, "Installing in existing process " + proc);
8100                            }
8101                            proc.pubProviders.put(cpi.name, cpr);
8102                            try {
8103                                proc.thread.scheduleInstallProvider(cpi);
8104                            } catch (RemoteException e) {
8105                            }
8106                        } else {
8107                            proc = startProcessLocked(cpi.processName,
8108                                    cpr.appInfo, false, 0, "content provider",
8109                                    new ComponentName(cpi.applicationInfo.packageName,
8110                                            cpi.name), false, false, false);
8111                            if (proc == null) {
8112                                Slog.w(TAG, "Unable to launch app "
8113                                        + cpi.applicationInfo.packageName + "/"
8114                                        + cpi.applicationInfo.uid + " for provider "
8115                                        + name + ": process is bad");
8116                                return null;
8117                            }
8118                        }
8119                        cpr.launchingApp = proc;
8120                        mLaunchingProviders.add(cpr);
8121                    } finally {
8122                        Binder.restoreCallingIdentity(origId);
8123                    }
8124                }
8125
8126                // Make sure the provider is published (the same provider class
8127                // may be published under multiple names).
8128                if (firstClass) {
8129                    mProviderMap.putProviderByClass(comp, cpr);
8130                }
8131
8132                mProviderMap.putProviderByName(name, cpr);
8133                conn = incProviderCountLocked(r, cpr, token, stable);
8134                if (conn != null) {
8135                    conn.waiting = true;
8136                }
8137            }
8138        }
8139
8140        // Wait for the provider to be published...
8141        synchronized (cpr) {
8142            while (cpr.provider == null) {
8143                if (cpr.launchingApp == null) {
8144                    Slog.w(TAG, "Unable to launch app "
8145                            + cpi.applicationInfo.packageName + "/"
8146                            + cpi.applicationInfo.uid + " for provider "
8147                            + name + ": launching app became null");
8148                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8149                            UserHandle.getUserId(cpi.applicationInfo.uid),
8150                            cpi.applicationInfo.packageName,
8151                            cpi.applicationInfo.uid, name);
8152                    return null;
8153                }
8154                try {
8155                    if (DEBUG_MU) {
8156                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8157                                + cpr.launchingApp);
8158                    }
8159                    if (conn != null) {
8160                        conn.waiting = true;
8161                    }
8162                    cpr.wait();
8163                } catch (InterruptedException ex) {
8164                } finally {
8165                    if (conn != null) {
8166                        conn.waiting = false;
8167                    }
8168                }
8169            }
8170        }
8171        return cpr != null ? cpr.newHolder(conn) : null;
8172    }
8173
8174    @Override
8175    public final ContentProviderHolder getContentProvider(
8176            IApplicationThread caller, String name, int userId, boolean stable) {
8177        enforceNotIsolatedCaller("getContentProvider");
8178        if (caller == null) {
8179            String msg = "null IApplicationThread when getting content provider "
8180                    + name;
8181            Slog.w(TAG, msg);
8182            throw new SecurityException(msg);
8183        }
8184        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8185        // with cross-user grant.
8186        return getContentProviderImpl(caller, name, null, stable, userId);
8187    }
8188
8189    public ContentProviderHolder getContentProviderExternal(
8190            String name, int userId, IBinder token) {
8191        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8192            "Do not have permission in call getContentProviderExternal()");
8193        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8194                false, true, "getContentProvider", null);
8195        return getContentProviderExternalUnchecked(name, token, userId);
8196    }
8197
8198    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8199            IBinder token, int userId) {
8200        return getContentProviderImpl(null, name, token, true, userId);
8201    }
8202
8203    /**
8204     * Drop a content provider from a ProcessRecord's bookkeeping
8205     */
8206    public void removeContentProvider(IBinder connection, boolean stable) {
8207        enforceNotIsolatedCaller("removeContentProvider");
8208        long ident = Binder.clearCallingIdentity();
8209        try {
8210            synchronized (this) {
8211                ContentProviderConnection conn;
8212                try {
8213                    conn = (ContentProviderConnection)connection;
8214                } catch (ClassCastException e) {
8215                    String msg ="removeContentProvider: " + connection
8216                            + " not a ContentProviderConnection";
8217                    Slog.w(TAG, msg);
8218                    throw new IllegalArgumentException(msg);
8219                }
8220                if (conn == null) {
8221                    throw new NullPointerException("connection is null");
8222                }
8223                if (decProviderCountLocked(conn, null, null, stable)) {
8224                    updateOomAdjLocked();
8225                }
8226            }
8227        } finally {
8228            Binder.restoreCallingIdentity(ident);
8229        }
8230    }
8231
8232    public void removeContentProviderExternal(String name, IBinder token) {
8233        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8234            "Do not have permission in call removeContentProviderExternal()");
8235        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8236    }
8237
8238    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8239        synchronized (this) {
8240            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8241            if(cpr == null) {
8242                //remove from mProvidersByClass
8243                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8244                return;
8245            }
8246
8247            //update content provider record entry info
8248            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8249            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8250            if (localCpr.hasExternalProcessHandles()) {
8251                if (localCpr.removeExternalProcessHandleLocked(token)) {
8252                    updateOomAdjLocked();
8253                } else {
8254                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8255                            + " with no external reference for token: "
8256                            + token + ".");
8257                }
8258            } else {
8259                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8260                        + " with no external references.");
8261            }
8262        }
8263    }
8264
8265    public final void publishContentProviders(IApplicationThread caller,
8266            List<ContentProviderHolder> providers) {
8267        if (providers == null) {
8268            return;
8269        }
8270
8271        enforceNotIsolatedCaller("publishContentProviders");
8272        synchronized (this) {
8273            final ProcessRecord r = getRecordForAppLocked(caller);
8274            if (DEBUG_MU)
8275                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8276            if (r == null) {
8277                throw new SecurityException(
8278                        "Unable to find app for caller " + caller
8279                      + " (pid=" + Binder.getCallingPid()
8280                      + ") when publishing content providers");
8281            }
8282
8283            final long origId = Binder.clearCallingIdentity();
8284
8285            final int N = providers.size();
8286            for (int i=0; i<N; i++) {
8287                ContentProviderHolder src = providers.get(i);
8288                if (src == null || src.info == null || src.provider == null) {
8289                    continue;
8290                }
8291                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8292                if (DEBUG_MU)
8293                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8294                if (dst != null) {
8295                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8296                    mProviderMap.putProviderByClass(comp, dst);
8297                    String names[] = dst.info.authority.split(";");
8298                    for (int j = 0; j < names.length; j++) {
8299                        mProviderMap.putProviderByName(names[j], dst);
8300                    }
8301
8302                    int NL = mLaunchingProviders.size();
8303                    int j;
8304                    for (j=0; j<NL; j++) {
8305                        if (mLaunchingProviders.get(j) == dst) {
8306                            mLaunchingProviders.remove(j);
8307                            j--;
8308                            NL--;
8309                        }
8310                    }
8311                    synchronized (dst) {
8312                        dst.provider = src.provider;
8313                        dst.proc = r;
8314                        dst.notifyAll();
8315                    }
8316                    updateOomAdjLocked(r);
8317                }
8318            }
8319
8320            Binder.restoreCallingIdentity(origId);
8321        }
8322    }
8323
8324    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8325        ContentProviderConnection conn;
8326        try {
8327            conn = (ContentProviderConnection)connection;
8328        } catch (ClassCastException e) {
8329            String msg ="refContentProvider: " + connection
8330                    + " not a ContentProviderConnection";
8331            Slog.w(TAG, msg);
8332            throw new IllegalArgumentException(msg);
8333        }
8334        if (conn == null) {
8335            throw new NullPointerException("connection is null");
8336        }
8337
8338        synchronized (this) {
8339            if (stable > 0) {
8340                conn.numStableIncs += stable;
8341            }
8342            stable = conn.stableCount + stable;
8343            if (stable < 0) {
8344                throw new IllegalStateException("stableCount < 0: " + stable);
8345            }
8346
8347            if (unstable > 0) {
8348                conn.numUnstableIncs += unstable;
8349            }
8350            unstable = conn.unstableCount + unstable;
8351            if (unstable < 0) {
8352                throw new IllegalStateException("unstableCount < 0: " + unstable);
8353            }
8354
8355            if ((stable+unstable) <= 0) {
8356                throw new IllegalStateException("ref counts can't go to zero here: stable="
8357                        + stable + " unstable=" + unstable);
8358            }
8359            conn.stableCount = stable;
8360            conn.unstableCount = unstable;
8361            return !conn.dead;
8362        }
8363    }
8364
8365    public void unstableProviderDied(IBinder connection) {
8366        ContentProviderConnection conn;
8367        try {
8368            conn = (ContentProviderConnection)connection;
8369        } catch (ClassCastException e) {
8370            String msg ="refContentProvider: " + connection
8371                    + " not a ContentProviderConnection";
8372            Slog.w(TAG, msg);
8373            throw new IllegalArgumentException(msg);
8374        }
8375        if (conn == null) {
8376            throw new NullPointerException("connection is null");
8377        }
8378
8379        // Safely retrieve the content provider associated with the connection.
8380        IContentProvider provider;
8381        synchronized (this) {
8382            provider = conn.provider.provider;
8383        }
8384
8385        if (provider == null) {
8386            // Um, yeah, we're way ahead of you.
8387            return;
8388        }
8389
8390        // Make sure the caller is being honest with us.
8391        if (provider.asBinder().pingBinder()) {
8392            // Er, no, still looks good to us.
8393            synchronized (this) {
8394                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8395                        + " says " + conn + " died, but we don't agree");
8396                return;
8397            }
8398        }
8399
8400        // Well look at that!  It's dead!
8401        synchronized (this) {
8402            if (conn.provider.provider != provider) {
8403                // But something changed...  good enough.
8404                return;
8405            }
8406
8407            ProcessRecord proc = conn.provider.proc;
8408            if (proc == null || proc.thread == null) {
8409                // Seems like the process is already cleaned up.
8410                return;
8411            }
8412
8413            // As far as we're concerned, this is just like receiving a
8414            // death notification...  just a bit prematurely.
8415            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8416                    + ") early provider death");
8417            final long ident = Binder.clearCallingIdentity();
8418            try {
8419                appDiedLocked(proc, proc.pid, proc.thread);
8420            } finally {
8421                Binder.restoreCallingIdentity(ident);
8422            }
8423        }
8424    }
8425
8426    @Override
8427    public void appNotRespondingViaProvider(IBinder connection) {
8428        enforceCallingPermission(
8429                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8430
8431        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8432        if (conn == null) {
8433            Slog.w(TAG, "ContentProviderConnection is null");
8434            return;
8435        }
8436
8437        final ProcessRecord host = conn.provider.proc;
8438        if (host == null) {
8439            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8440            return;
8441        }
8442
8443        final long token = Binder.clearCallingIdentity();
8444        try {
8445            appNotResponding(host, null, null, false, "ContentProvider not responding");
8446        } finally {
8447            Binder.restoreCallingIdentity(token);
8448        }
8449    }
8450
8451    public final void installSystemProviders() {
8452        List<ProviderInfo> providers;
8453        synchronized (this) {
8454            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8455            providers = generateApplicationProvidersLocked(app);
8456            if (providers != null) {
8457                for (int i=providers.size()-1; i>=0; i--) {
8458                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8459                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8460                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8461                                + ": not system .apk");
8462                        providers.remove(i);
8463                    }
8464                }
8465            }
8466        }
8467        if (providers != null) {
8468            mSystemThread.installSystemProviders(providers);
8469        }
8470
8471        mCoreSettingsObserver = new CoreSettingsObserver(this);
8472
8473        mUsageStatsService.monitorPackages();
8474    }
8475
8476    /**
8477     * Allows app to retrieve the MIME type of a URI without having permission
8478     * to access its content provider.
8479     *
8480     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8481     *
8482     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8483     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8484     */
8485    public String getProviderMimeType(Uri uri, int userId) {
8486        enforceNotIsolatedCaller("getProviderMimeType");
8487        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8488                userId, false, true, "getProviderMimeType", null);
8489        final String name = uri.getAuthority();
8490        final long ident = Binder.clearCallingIdentity();
8491        ContentProviderHolder holder = null;
8492
8493        try {
8494            holder = getContentProviderExternalUnchecked(name, null, userId);
8495            if (holder != null) {
8496                return holder.provider.getType(uri);
8497            }
8498        } catch (RemoteException e) {
8499            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8500            return null;
8501        } finally {
8502            if (holder != null) {
8503                removeContentProviderExternalUnchecked(name, null, userId);
8504            }
8505            Binder.restoreCallingIdentity(ident);
8506        }
8507
8508        return null;
8509    }
8510
8511    // =========================================================
8512    // GLOBAL MANAGEMENT
8513    // =========================================================
8514
8515    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8516            boolean isolated) {
8517        String proc = customProcess != null ? customProcess : info.processName;
8518        BatteryStatsImpl.Uid.Proc ps = null;
8519        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8520        int uid = info.uid;
8521        if (isolated) {
8522            int userId = UserHandle.getUserId(uid);
8523            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8524            while (true) {
8525                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8526                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8527                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8528                }
8529                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8530                mNextIsolatedProcessUid++;
8531                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8532                    // No process for this uid, use it.
8533                    break;
8534                }
8535                stepsLeft--;
8536                if (stepsLeft <= 0) {
8537                    return null;
8538                }
8539            }
8540        }
8541        return new ProcessRecord(stats, info, proc, uid);
8542    }
8543
8544    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8545        ProcessRecord app;
8546        if (!isolated) {
8547            app = getProcessRecordLocked(info.processName, info.uid, true);
8548        } else {
8549            app = null;
8550        }
8551
8552        if (app == null) {
8553            app = newProcessRecordLocked(info, null, isolated);
8554            mProcessNames.put(info.processName, app.uid, app);
8555            if (isolated) {
8556                mIsolatedProcesses.put(app.uid, app);
8557            }
8558            updateLruProcessLocked(app, false, null);
8559            updateOomAdjLocked();
8560        }
8561
8562        // This package really, really can not be stopped.
8563        try {
8564            AppGlobals.getPackageManager().setPackageStoppedState(
8565                    info.packageName, false, UserHandle.getUserId(app.uid));
8566        } catch (RemoteException e) {
8567        } catch (IllegalArgumentException e) {
8568            Slog.w(TAG, "Failed trying to unstop package "
8569                    + info.packageName + ": " + e);
8570        }
8571
8572        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8573                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8574            app.persistent = true;
8575            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8576        }
8577        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8578            mPersistentStartingProcesses.add(app);
8579            startProcessLocked(app, "added application", app.processName);
8580        }
8581
8582        return app;
8583    }
8584
8585    public void unhandledBack() {
8586        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8587                "unhandledBack()");
8588
8589        synchronized(this) {
8590            final long origId = Binder.clearCallingIdentity();
8591            try {
8592                getFocusedStack().unhandledBackLocked();
8593            } finally {
8594                Binder.restoreCallingIdentity(origId);
8595            }
8596        }
8597    }
8598
8599    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8600        enforceNotIsolatedCaller("openContentUri");
8601        final int userId = UserHandle.getCallingUserId();
8602        String name = uri.getAuthority();
8603        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8604        ParcelFileDescriptor pfd = null;
8605        if (cph != null) {
8606            // We record the binder invoker's uid in thread-local storage before
8607            // going to the content provider to open the file.  Later, in the code
8608            // that handles all permissions checks, we look for this uid and use
8609            // that rather than the Activity Manager's own uid.  The effect is that
8610            // we do the check against the caller's permissions even though it looks
8611            // to the content provider like the Activity Manager itself is making
8612            // the request.
8613            sCallerIdentity.set(new Identity(
8614                    Binder.getCallingPid(), Binder.getCallingUid()));
8615            try {
8616                pfd = cph.provider.openFile(null, uri, "r", null);
8617            } catch (FileNotFoundException e) {
8618                // do nothing; pfd will be returned null
8619            } finally {
8620                // Ensure that whatever happens, we clean up the identity state
8621                sCallerIdentity.remove();
8622            }
8623
8624            // We've got the fd now, so we're done with the provider.
8625            removeContentProviderExternalUnchecked(name, null, userId);
8626        } else {
8627            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8628        }
8629        return pfd;
8630    }
8631
8632    // Actually is sleeping or shutting down or whatever else in the future
8633    // is an inactive state.
8634    public boolean isSleepingOrShuttingDown() {
8635        return mSleeping || mShuttingDown;
8636    }
8637
8638    public boolean isSleeping() {
8639        return mSleeping;
8640    }
8641
8642    void goingToSleep() {
8643        synchronized(this) {
8644            mWentToSleep = true;
8645            updateEventDispatchingLocked();
8646            goToSleepIfNeededLocked();
8647        }
8648    }
8649
8650    void finishRunningVoiceLocked() {
8651        if (mRunningVoice) {
8652            mRunningVoice = false;
8653            goToSleepIfNeededLocked();
8654        }
8655    }
8656
8657    void goToSleepIfNeededLocked() {
8658        if (mWentToSleep && !mRunningVoice) {
8659            if (!mSleeping) {
8660                mSleeping = true;
8661                mStackSupervisor.goingToSleepLocked();
8662
8663                // Initialize the wake times of all processes.
8664                checkExcessivePowerUsageLocked(false);
8665                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8666                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8667                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8668            }
8669        }
8670    }
8671
8672    @Override
8673    public boolean shutdown(int timeout) {
8674        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8675                != PackageManager.PERMISSION_GRANTED) {
8676            throw new SecurityException("Requires permission "
8677                    + android.Manifest.permission.SHUTDOWN);
8678        }
8679
8680        boolean timedout = false;
8681
8682        synchronized(this) {
8683            mShuttingDown = true;
8684            updateEventDispatchingLocked();
8685            timedout = mStackSupervisor.shutdownLocked(timeout);
8686        }
8687
8688        mAppOpsService.shutdown();
8689        mUsageStatsService.shutdown();
8690        mBatteryStatsService.shutdown();
8691        synchronized (this) {
8692            mProcessStats.shutdownLocked();
8693        }
8694
8695        return timedout;
8696    }
8697
8698    public final void activitySlept(IBinder token) {
8699        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8700
8701        final long origId = Binder.clearCallingIdentity();
8702
8703        synchronized (this) {
8704            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8705            if (r != null) {
8706                mStackSupervisor.activitySleptLocked(r);
8707            }
8708        }
8709
8710        Binder.restoreCallingIdentity(origId);
8711    }
8712
8713    void logLockScreen(String msg) {
8714        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8715                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8716                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8717                mStackSupervisor.mDismissKeyguardOnNextActivity);
8718    }
8719
8720    private void comeOutOfSleepIfNeededLocked() {
8721        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8722            if (mSleeping) {
8723                mSleeping = false;
8724                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8725            }
8726        }
8727    }
8728
8729    void wakingUp() {
8730        synchronized(this) {
8731            mWentToSleep = false;
8732            updateEventDispatchingLocked();
8733            comeOutOfSleepIfNeededLocked();
8734        }
8735    }
8736
8737    void startRunningVoiceLocked() {
8738        if (!mRunningVoice) {
8739            mRunningVoice = true;
8740            comeOutOfSleepIfNeededLocked();
8741        }
8742    }
8743
8744    private void updateEventDispatchingLocked() {
8745        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8746    }
8747
8748    public void setLockScreenShown(boolean shown) {
8749        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8750                != PackageManager.PERMISSION_GRANTED) {
8751            throw new SecurityException("Requires permission "
8752                    + android.Manifest.permission.DEVICE_POWER);
8753        }
8754
8755        synchronized(this) {
8756            long ident = Binder.clearCallingIdentity();
8757            try {
8758                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8759                mLockScreenShown = shown;
8760                comeOutOfSleepIfNeededLocked();
8761            } finally {
8762                Binder.restoreCallingIdentity(ident);
8763            }
8764        }
8765    }
8766
8767    public void stopAppSwitches() {
8768        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8769                != PackageManager.PERMISSION_GRANTED) {
8770            throw new SecurityException("Requires permission "
8771                    + android.Manifest.permission.STOP_APP_SWITCHES);
8772        }
8773
8774        synchronized(this) {
8775            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8776                    + APP_SWITCH_DELAY_TIME;
8777            mDidAppSwitch = false;
8778            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8779            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8780            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8781        }
8782    }
8783
8784    public void resumeAppSwitches() {
8785        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8786                != PackageManager.PERMISSION_GRANTED) {
8787            throw new SecurityException("Requires permission "
8788                    + android.Manifest.permission.STOP_APP_SWITCHES);
8789        }
8790
8791        synchronized(this) {
8792            // Note that we don't execute any pending app switches... we will
8793            // let those wait until either the timeout, or the next start
8794            // activity request.
8795            mAppSwitchesAllowedTime = 0;
8796        }
8797    }
8798
8799    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8800            String name) {
8801        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8802            return true;
8803        }
8804
8805        final int perm = checkComponentPermission(
8806                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8807                callingUid, -1, true);
8808        if (perm == PackageManager.PERMISSION_GRANTED) {
8809            return true;
8810        }
8811
8812        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8813        return false;
8814    }
8815
8816    public void setDebugApp(String packageName, boolean waitForDebugger,
8817            boolean persistent) {
8818        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8819                "setDebugApp()");
8820
8821        long ident = Binder.clearCallingIdentity();
8822        try {
8823            // Note that this is not really thread safe if there are multiple
8824            // callers into it at the same time, but that's not a situation we
8825            // care about.
8826            if (persistent) {
8827                final ContentResolver resolver = mContext.getContentResolver();
8828                Settings.Global.putString(
8829                    resolver, Settings.Global.DEBUG_APP,
8830                    packageName);
8831                Settings.Global.putInt(
8832                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8833                    waitForDebugger ? 1 : 0);
8834            }
8835
8836            synchronized (this) {
8837                if (!persistent) {
8838                    mOrigDebugApp = mDebugApp;
8839                    mOrigWaitForDebugger = mWaitForDebugger;
8840                }
8841                mDebugApp = packageName;
8842                mWaitForDebugger = waitForDebugger;
8843                mDebugTransient = !persistent;
8844                if (packageName != null) {
8845                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8846                            false, UserHandle.USER_ALL, "set debug app");
8847                }
8848            }
8849        } finally {
8850            Binder.restoreCallingIdentity(ident);
8851        }
8852    }
8853
8854    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8855        synchronized (this) {
8856            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8857            if (!isDebuggable) {
8858                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8859                    throw new SecurityException("Process not debuggable: " + app.packageName);
8860                }
8861            }
8862
8863            mOpenGlTraceApp = processName;
8864        }
8865    }
8866
8867    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8868            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8869        synchronized (this) {
8870            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8871            if (!isDebuggable) {
8872                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8873                    throw new SecurityException("Process not debuggable: " + app.packageName);
8874                }
8875            }
8876            mProfileApp = processName;
8877            mProfileFile = profileFile;
8878            if (mProfileFd != null) {
8879                try {
8880                    mProfileFd.close();
8881                } catch (IOException e) {
8882                }
8883                mProfileFd = null;
8884            }
8885            mProfileFd = profileFd;
8886            mProfileType = 0;
8887            mAutoStopProfiler = autoStopProfiler;
8888        }
8889    }
8890
8891    @Override
8892    public void setAlwaysFinish(boolean enabled) {
8893        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8894                "setAlwaysFinish()");
8895
8896        Settings.Global.putInt(
8897                mContext.getContentResolver(),
8898                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8899
8900        synchronized (this) {
8901            mAlwaysFinishActivities = enabled;
8902        }
8903    }
8904
8905    @Override
8906    public void setActivityController(IActivityController controller) {
8907        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8908                "setActivityController()");
8909        synchronized (this) {
8910            mController = controller;
8911            Watchdog.getInstance().setActivityController(controller);
8912        }
8913    }
8914
8915    @Override
8916    public void setUserIsMonkey(boolean userIsMonkey) {
8917        synchronized (this) {
8918            synchronized (mPidsSelfLocked) {
8919                final int callingPid = Binder.getCallingPid();
8920                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8921                if (precessRecord == null) {
8922                    throw new SecurityException("Unknown process: " + callingPid);
8923                }
8924                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8925                    throw new SecurityException("Only an instrumentation process "
8926                            + "with a UiAutomation can call setUserIsMonkey");
8927                }
8928            }
8929            mUserIsMonkey = userIsMonkey;
8930        }
8931    }
8932
8933    @Override
8934    public boolean isUserAMonkey() {
8935        synchronized (this) {
8936            // If there is a controller also implies the user is a monkey.
8937            return (mUserIsMonkey || mController != null);
8938        }
8939    }
8940
8941    public void requestBugReport() {
8942        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8943        SystemProperties.set("ctl.start", "bugreport");
8944    }
8945
8946    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8947        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8948    }
8949
8950    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8951        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8952            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8953        }
8954        return KEY_DISPATCHING_TIMEOUT;
8955    }
8956
8957    @Override
8958    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8959        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8960                != PackageManager.PERMISSION_GRANTED) {
8961            throw new SecurityException("Requires permission "
8962                    + android.Manifest.permission.FILTER_EVENTS);
8963        }
8964        ProcessRecord proc;
8965        long timeout;
8966        synchronized (this) {
8967            synchronized (mPidsSelfLocked) {
8968                proc = mPidsSelfLocked.get(pid);
8969            }
8970            timeout = getInputDispatchingTimeoutLocked(proc);
8971        }
8972
8973        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8974            return -1;
8975        }
8976
8977        return timeout;
8978    }
8979
8980    /**
8981     * Handle input dispatching timeouts.
8982     * Returns whether input dispatching should be aborted or not.
8983     */
8984    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8985            final ActivityRecord activity, final ActivityRecord parent,
8986            final boolean aboveSystem, String reason) {
8987        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8988                != PackageManager.PERMISSION_GRANTED) {
8989            throw new SecurityException("Requires permission "
8990                    + android.Manifest.permission.FILTER_EVENTS);
8991        }
8992
8993        final String annotation;
8994        if (reason == null) {
8995            annotation = "Input dispatching timed out";
8996        } else {
8997            annotation = "Input dispatching timed out (" + reason + ")";
8998        }
8999
9000        if (proc != null) {
9001            synchronized (this) {
9002                if (proc.debugging) {
9003                    return false;
9004                }
9005
9006                if (mDidDexOpt) {
9007                    // Give more time since we were dexopting.
9008                    mDidDexOpt = false;
9009                    return false;
9010                }
9011
9012                if (proc.instrumentationClass != null) {
9013                    Bundle info = new Bundle();
9014                    info.putString("shortMsg", "keyDispatchingTimedOut");
9015                    info.putString("longMsg", annotation);
9016                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9017                    return true;
9018                }
9019            }
9020            mHandler.post(new Runnable() {
9021                @Override
9022                public void run() {
9023                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9024                }
9025            });
9026        }
9027
9028        return true;
9029    }
9030
9031    public Bundle getAssistContextExtras(int requestType) {
9032        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9033                "getAssistContextExtras()");
9034        PendingAssistExtras pae;
9035        Bundle extras = new Bundle();
9036        synchronized (this) {
9037            ActivityRecord activity = getFocusedStack().mResumedActivity;
9038            if (activity == null) {
9039                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9040                return null;
9041            }
9042            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9043            if (activity.app == null || activity.app.thread == null) {
9044                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9045                return extras;
9046            }
9047            if (activity.app.pid == Binder.getCallingPid()) {
9048                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9049                return extras;
9050            }
9051            pae = new PendingAssistExtras(activity);
9052            try {
9053                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9054                        requestType);
9055                mPendingAssistExtras.add(pae);
9056                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9057            } catch (RemoteException e) {
9058                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9059                return extras;
9060            }
9061        }
9062        synchronized (pae) {
9063            while (!pae.haveResult) {
9064                try {
9065                    pae.wait();
9066                } catch (InterruptedException e) {
9067                }
9068            }
9069            if (pae.result != null) {
9070                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9071            }
9072        }
9073        synchronized (this) {
9074            mPendingAssistExtras.remove(pae);
9075            mHandler.removeCallbacks(pae);
9076        }
9077        return extras;
9078    }
9079
9080    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9081        PendingAssistExtras pae = (PendingAssistExtras)token;
9082        synchronized (pae) {
9083            pae.result = extras;
9084            pae.haveResult = true;
9085            pae.notifyAll();
9086        }
9087    }
9088
9089    public void registerProcessObserver(IProcessObserver observer) {
9090        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9091                "registerProcessObserver()");
9092        synchronized (this) {
9093            mProcessObservers.register(observer);
9094        }
9095    }
9096
9097    @Override
9098    public void unregisterProcessObserver(IProcessObserver observer) {
9099        synchronized (this) {
9100            mProcessObservers.unregister(observer);
9101        }
9102    }
9103
9104    @Override
9105    public boolean convertFromTranslucent(IBinder token) {
9106        final long origId = Binder.clearCallingIdentity();
9107        try {
9108            synchronized (this) {
9109                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9110                if (r == null) {
9111                    return false;
9112                }
9113                if (r.changeWindowTranslucency(true)) {
9114                    mWindowManager.setAppFullscreen(token, true);
9115                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9116                    return true;
9117                }
9118                return false;
9119            }
9120        } finally {
9121            Binder.restoreCallingIdentity(origId);
9122        }
9123    }
9124
9125    @Override
9126    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9127        final long origId = Binder.clearCallingIdentity();
9128        try {
9129            synchronized (this) {
9130                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9131                if (r == null) {
9132                    return false;
9133                }
9134                if (r.changeWindowTranslucency(false)) {
9135                    r.task.stack.convertToTranslucent(r, options);
9136                    mWindowManager.setAppFullscreen(token, false);
9137                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9138                    return true;
9139                }
9140                return false;
9141            }
9142        } finally {
9143            Binder.restoreCallingIdentity(origId);
9144        }
9145    }
9146
9147    @Override
9148    public ActivityOptions getActivityOptions(IBinder token) {
9149        final long origId = Binder.clearCallingIdentity();
9150        try {
9151            synchronized (this) {
9152                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9153                if (r != null) {
9154                    final ActivityOptions activityOptions = r.pendingOptions;
9155                    r.pendingOptions = null;
9156                    return activityOptions;
9157                }
9158                return null;
9159            }
9160        } finally {
9161            Binder.restoreCallingIdentity(origId);
9162        }
9163    }
9164
9165    @Override
9166    public void setImmersive(IBinder token, boolean immersive) {
9167        synchronized(this) {
9168            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9169            if (r == null) {
9170                throw new IllegalArgumentException();
9171            }
9172            r.immersive = immersive;
9173
9174            // update associated state if we're frontmost
9175            if (r == mFocusedActivity) {
9176                if (DEBUG_IMMERSIVE) {
9177                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9178                }
9179                applyUpdateLockStateLocked(r);
9180            }
9181        }
9182    }
9183
9184    @Override
9185    public boolean isImmersive(IBinder token) {
9186        synchronized (this) {
9187            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9188            if (r == null) {
9189                throw new IllegalArgumentException();
9190            }
9191            return r.immersive;
9192        }
9193    }
9194
9195    public boolean isTopActivityImmersive() {
9196        enforceNotIsolatedCaller("startActivity");
9197        synchronized (this) {
9198            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9199            return (r != null) ? r.immersive : false;
9200        }
9201    }
9202
9203    public final void enterSafeMode() {
9204        synchronized(this) {
9205            // It only makes sense to do this before the system is ready
9206            // and started launching other packages.
9207            if (!mSystemReady) {
9208                try {
9209                    AppGlobals.getPackageManager().enterSafeMode();
9210                } catch (RemoteException e) {
9211                }
9212            }
9213
9214            mSafeMode = true;
9215        }
9216    }
9217
9218    public final void showSafeModeOverlay() {
9219        View v = LayoutInflater.from(mContext).inflate(
9220                com.android.internal.R.layout.safe_mode, null);
9221        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9222        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9223        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9224        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9225        lp.gravity = Gravity.BOTTOM | Gravity.START;
9226        lp.format = v.getBackground().getOpacity();
9227        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9228                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9229        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9230        ((WindowManager)mContext.getSystemService(
9231                Context.WINDOW_SERVICE)).addView(v, lp);
9232    }
9233
9234    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9235        if (!(sender instanceof PendingIntentRecord)) {
9236            return;
9237        }
9238        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9239        synchronized (stats) {
9240            if (mBatteryStatsService.isOnBattery()) {
9241                mBatteryStatsService.enforceCallingPermission();
9242                PendingIntentRecord rec = (PendingIntentRecord)sender;
9243                int MY_UID = Binder.getCallingUid();
9244                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9245                BatteryStatsImpl.Uid.Pkg pkg =
9246                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9247                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9248                pkg.incWakeupsLocked();
9249            }
9250        }
9251    }
9252
9253    public boolean killPids(int[] pids, String pReason, boolean secure) {
9254        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9255            throw new SecurityException("killPids only available to the system");
9256        }
9257        String reason = (pReason == null) ? "Unknown" : pReason;
9258        // XXX Note: don't acquire main activity lock here, because the window
9259        // manager calls in with its locks held.
9260
9261        boolean killed = false;
9262        synchronized (mPidsSelfLocked) {
9263            int[] types = new int[pids.length];
9264            int worstType = 0;
9265            for (int i=0; i<pids.length; i++) {
9266                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9267                if (proc != null) {
9268                    int type = proc.setAdj;
9269                    types[i] = type;
9270                    if (type > worstType) {
9271                        worstType = type;
9272                    }
9273                }
9274            }
9275
9276            // If the worst oom_adj is somewhere in the cached proc LRU range,
9277            // then constrain it so we will kill all cached procs.
9278            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9279                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9280                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9281            }
9282
9283            // If this is not a secure call, don't let it kill processes that
9284            // are important.
9285            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9286                worstType = ProcessList.SERVICE_ADJ;
9287            }
9288
9289            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9290            for (int i=0; i<pids.length; i++) {
9291                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9292                if (proc == null) {
9293                    continue;
9294                }
9295                int adj = proc.setAdj;
9296                if (adj >= worstType && !proc.killedByAm) {
9297                    killUnneededProcessLocked(proc, reason);
9298                    killed = true;
9299                }
9300            }
9301        }
9302        return killed;
9303    }
9304
9305    @Override
9306    public void killUid(int uid, String reason) {
9307        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9308            throw new SecurityException("killUid only available to the system");
9309        }
9310        synchronized (this) {
9311            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9312                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9313                    reason != null ? reason : "kill uid");
9314        }
9315    }
9316
9317    @Override
9318    public boolean killProcessesBelowForeground(String reason) {
9319        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9320            throw new SecurityException("killProcessesBelowForeground() only available to system");
9321        }
9322
9323        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9324    }
9325
9326    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9327        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9328            throw new SecurityException("killProcessesBelowAdj() only available to system");
9329        }
9330
9331        boolean killed = false;
9332        synchronized (mPidsSelfLocked) {
9333            final int size = mPidsSelfLocked.size();
9334            for (int i = 0; i < size; i++) {
9335                final int pid = mPidsSelfLocked.keyAt(i);
9336                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9337                if (proc == null) continue;
9338
9339                final int adj = proc.setAdj;
9340                if (adj > belowAdj && !proc.killedByAm) {
9341                    killUnneededProcessLocked(proc, reason);
9342                    killed = true;
9343                }
9344            }
9345        }
9346        return killed;
9347    }
9348
9349    @Override
9350    public void hang(final IBinder who, boolean allowRestart) {
9351        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9352                != PackageManager.PERMISSION_GRANTED) {
9353            throw new SecurityException("Requires permission "
9354                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9355        }
9356
9357        final IBinder.DeathRecipient death = new DeathRecipient() {
9358            @Override
9359            public void binderDied() {
9360                synchronized (this) {
9361                    notifyAll();
9362                }
9363            }
9364        };
9365
9366        try {
9367            who.linkToDeath(death, 0);
9368        } catch (RemoteException e) {
9369            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9370            return;
9371        }
9372
9373        synchronized (this) {
9374            Watchdog.getInstance().setAllowRestart(allowRestart);
9375            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9376            synchronized (death) {
9377                while (who.isBinderAlive()) {
9378                    try {
9379                        death.wait();
9380                    } catch (InterruptedException e) {
9381                    }
9382                }
9383            }
9384            Watchdog.getInstance().setAllowRestart(true);
9385        }
9386    }
9387
9388    @Override
9389    public void restart() {
9390        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9391                != PackageManager.PERMISSION_GRANTED) {
9392            throw new SecurityException("Requires permission "
9393                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9394        }
9395
9396        Log.i(TAG, "Sending shutdown broadcast...");
9397
9398        BroadcastReceiver br = new BroadcastReceiver() {
9399            @Override public void onReceive(Context context, Intent intent) {
9400                // Now the broadcast is done, finish up the low-level shutdown.
9401                Log.i(TAG, "Shutting down activity manager...");
9402                shutdown(10000);
9403                Log.i(TAG, "Shutdown complete, restarting!");
9404                Process.killProcess(Process.myPid());
9405                System.exit(10);
9406            }
9407        };
9408
9409        // First send the high-level shut down broadcast.
9410        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9411        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9412        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9413        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9414        mContext.sendOrderedBroadcastAsUser(intent,
9415                UserHandle.ALL, null, br, mHandler, 0, null, null);
9416        */
9417        br.onReceive(mContext, intent);
9418    }
9419
9420    private long getLowRamTimeSinceIdle(long now) {
9421        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9422    }
9423
9424    @Override
9425    public void performIdleMaintenance() {
9426        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9427                != PackageManager.PERMISSION_GRANTED) {
9428            throw new SecurityException("Requires permission "
9429                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9430        }
9431
9432        synchronized (this) {
9433            final long now = SystemClock.uptimeMillis();
9434            final long timeSinceLastIdle = now - mLastIdleTime;
9435            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9436            mLastIdleTime = now;
9437            mLowRamTimeSinceLastIdle = 0;
9438            if (mLowRamStartTime != 0) {
9439                mLowRamStartTime = now;
9440            }
9441
9442            StringBuilder sb = new StringBuilder(128);
9443            sb.append("Idle maintenance over ");
9444            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9445            sb.append(" low RAM for ");
9446            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9447            Slog.i(TAG, sb.toString());
9448
9449            // If at least 1/3 of our time since the last idle period has been spent
9450            // with RAM low, then we want to kill processes.
9451            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9452
9453            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9454                ProcessRecord proc = mLruProcesses.get(i);
9455                if (proc.notCachedSinceIdle) {
9456                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9457                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9458                        if (doKilling && proc.initialIdlePss != 0
9459                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9460                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9461                                    + " from " + proc.initialIdlePss + ")");
9462                        }
9463                    }
9464                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9465                    proc.notCachedSinceIdle = true;
9466                    proc.initialIdlePss = 0;
9467                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9468                            isSleeping(), now);
9469                }
9470            }
9471
9472            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9473            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9474        }
9475    }
9476
9477    private void retrieveSettings() {
9478        final ContentResolver resolver = mContext.getContentResolver();
9479        String debugApp = Settings.Global.getString(
9480            resolver, Settings.Global.DEBUG_APP);
9481        boolean waitForDebugger = Settings.Global.getInt(
9482            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9483        boolean alwaysFinishActivities = Settings.Global.getInt(
9484            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9485        boolean forceRtl = Settings.Global.getInt(
9486                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9487        // Transfer any global setting for forcing RTL layout, into a System Property
9488        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9489
9490        Configuration configuration = new Configuration();
9491        Settings.System.getConfiguration(resolver, configuration);
9492        if (forceRtl) {
9493            // This will take care of setting the correct layout direction flags
9494            configuration.setLayoutDirection(configuration.locale);
9495        }
9496
9497        synchronized (this) {
9498            mDebugApp = mOrigDebugApp = debugApp;
9499            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9500            mAlwaysFinishActivities = alwaysFinishActivities;
9501            // This happens before any activities are started, so we can
9502            // change mConfiguration in-place.
9503            updateConfigurationLocked(configuration, null, false, true);
9504            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9505        }
9506    }
9507
9508    public boolean testIsSystemReady() {
9509        // no need to synchronize(this) just to read & return the value
9510        return mSystemReady;
9511    }
9512
9513    private static File getCalledPreBootReceiversFile() {
9514        File dataDir = Environment.getDataDirectory();
9515        File systemDir = new File(dataDir, "system");
9516        File fname = new File(systemDir, "called_pre_boots.dat");
9517        return fname;
9518    }
9519
9520    static final int LAST_DONE_VERSION = 10000;
9521
9522    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9523        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9524        File file = getCalledPreBootReceiversFile();
9525        FileInputStream fis = null;
9526        try {
9527            fis = new FileInputStream(file);
9528            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9529            int fvers = dis.readInt();
9530            if (fvers == LAST_DONE_VERSION) {
9531                String vers = dis.readUTF();
9532                String codename = dis.readUTF();
9533                String build = dis.readUTF();
9534                if (android.os.Build.VERSION.RELEASE.equals(vers)
9535                        && android.os.Build.VERSION.CODENAME.equals(codename)
9536                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9537                    int num = dis.readInt();
9538                    while (num > 0) {
9539                        num--;
9540                        String pkg = dis.readUTF();
9541                        String cls = dis.readUTF();
9542                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9543                    }
9544                }
9545            }
9546        } catch (FileNotFoundException e) {
9547        } catch (IOException e) {
9548            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9549        } finally {
9550            if (fis != null) {
9551                try {
9552                    fis.close();
9553                } catch (IOException e) {
9554                }
9555            }
9556        }
9557        return lastDoneReceivers;
9558    }
9559
9560    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9561        File file = getCalledPreBootReceiversFile();
9562        FileOutputStream fos = null;
9563        DataOutputStream dos = null;
9564        try {
9565            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9566            fos = new FileOutputStream(file);
9567            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9568            dos.writeInt(LAST_DONE_VERSION);
9569            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9570            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9571            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9572            dos.writeInt(list.size());
9573            for (int i=0; i<list.size(); i++) {
9574                dos.writeUTF(list.get(i).getPackageName());
9575                dos.writeUTF(list.get(i).getClassName());
9576            }
9577        } catch (IOException e) {
9578            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9579            file.delete();
9580        } finally {
9581            FileUtils.sync(fos);
9582            if (dos != null) {
9583                try {
9584                    dos.close();
9585                } catch (IOException e) {
9586                    // TODO Auto-generated catch block
9587                    e.printStackTrace();
9588                }
9589            }
9590        }
9591    }
9592
9593    public void systemReady(final Runnable goingCallback) {
9594        synchronized(this) {
9595            if (mSystemReady) {
9596                if (goingCallback != null) goingCallback.run();
9597                return;
9598            }
9599
9600            // Check to see if there are any update receivers to run.
9601            if (!mDidUpdate) {
9602                if (mWaitingUpdate) {
9603                    return;
9604                }
9605                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9606                List<ResolveInfo> ris = null;
9607                try {
9608                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9609                            intent, null, 0, 0);
9610                } catch (RemoteException e) {
9611                }
9612                if (ris != null) {
9613                    for (int i=ris.size()-1; i>=0; i--) {
9614                        if ((ris.get(i).activityInfo.applicationInfo.flags
9615                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9616                            ris.remove(i);
9617                        }
9618                    }
9619                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9620
9621                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9622
9623                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9624                    for (int i=0; i<ris.size(); i++) {
9625                        ActivityInfo ai = ris.get(i).activityInfo;
9626                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9627                        if (lastDoneReceivers.contains(comp)) {
9628                            // We already did the pre boot receiver for this app with the current
9629                            // platform version, so don't do it again...
9630                            ris.remove(i);
9631                            i--;
9632                            // ...however, do keep it as one that has been done, so we don't
9633                            // forget about it when rewriting the file of last done receivers.
9634                            doneReceivers.add(comp);
9635                        }
9636                    }
9637
9638                    final int[] users = getUsersLocked();
9639                    for (int i=0; i<ris.size(); i++) {
9640                        ActivityInfo ai = ris.get(i).activityInfo;
9641                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9642                        doneReceivers.add(comp);
9643                        intent.setComponent(comp);
9644                        for (int j=0; j<users.length; j++) {
9645                            IIntentReceiver finisher = null;
9646                            if (i == ris.size()-1 && j == users.length-1) {
9647                                finisher = new IIntentReceiver.Stub() {
9648                                    public void performReceive(Intent intent, int resultCode,
9649                                            String data, Bundle extras, boolean ordered,
9650                                            boolean sticky, int sendingUser) {
9651                                        // The raw IIntentReceiver interface is called
9652                                        // with the AM lock held, so redispatch to
9653                                        // execute our code without the lock.
9654                                        mHandler.post(new Runnable() {
9655                                            public void run() {
9656                                                synchronized (ActivityManagerService.this) {
9657                                                    mDidUpdate = true;
9658                                                }
9659                                                writeLastDonePreBootReceivers(doneReceivers);
9660                                                showBootMessage(mContext.getText(
9661                                                        R.string.android_upgrading_complete),
9662                                                        false);
9663                                                systemReady(goingCallback);
9664                                            }
9665                                        });
9666                                    }
9667                                };
9668                            }
9669                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9670                                    + " for user " + users[j]);
9671                            broadcastIntentLocked(null, null, intent, null, finisher,
9672                                    0, null, null, null, AppOpsManager.OP_NONE,
9673                                    true, false, MY_PID, Process.SYSTEM_UID,
9674                                    users[j]);
9675                            if (finisher != null) {
9676                                mWaitingUpdate = true;
9677                            }
9678                        }
9679                    }
9680                }
9681                if (mWaitingUpdate) {
9682                    return;
9683                }
9684                mDidUpdate = true;
9685            }
9686
9687            mAppOpsService.systemReady();
9688            mUsageStatsService.systemReady();
9689            mSystemReady = true;
9690        }
9691
9692        ArrayList<ProcessRecord> procsToKill = null;
9693        synchronized(mPidsSelfLocked) {
9694            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9695                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9696                if (!isAllowedWhileBooting(proc.info)){
9697                    if (procsToKill == null) {
9698                        procsToKill = new ArrayList<ProcessRecord>();
9699                    }
9700                    procsToKill.add(proc);
9701                }
9702            }
9703        }
9704
9705        synchronized(this) {
9706            if (procsToKill != null) {
9707                for (int i=procsToKill.size()-1; i>=0; i--) {
9708                    ProcessRecord proc = procsToKill.get(i);
9709                    Slog.i(TAG, "Removing system update proc: " + proc);
9710                    removeProcessLocked(proc, true, false, "system update done");
9711                }
9712            }
9713
9714            // Now that we have cleaned up any update processes, we
9715            // are ready to start launching real processes and know that
9716            // we won't trample on them any more.
9717            mProcessesReady = true;
9718        }
9719
9720        Slog.i(TAG, "System now ready");
9721        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9722            SystemClock.uptimeMillis());
9723
9724        synchronized(this) {
9725            // Make sure we have no pre-ready processes sitting around.
9726
9727            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9728                ResolveInfo ri = mContext.getPackageManager()
9729                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9730                                STOCK_PM_FLAGS);
9731                CharSequence errorMsg = null;
9732                if (ri != null) {
9733                    ActivityInfo ai = ri.activityInfo;
9734                    ApplicationInfo app = ai.applicationInfo;
9735                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9736                        mTopAction = Intent.ACTION_FACTORY_TEST;
9737                        mTopData = null;
9738                        mTopComponent = new ComponentName(app.packageName,
9739                                ai.name);
9740                    } else {
9741                        errorMsg = mContext.getResources().getText(
9742                                com.android.internal.R.string.factorytest_not_system);
9743                    }
9744                } else {
9745                    errorMsg = mContext.getResources().getText(
9746                            com.android.internal.R.string.factorytest_no_action);
9747                }
9748                if (errorMsg != null) {
9749                    mTopAction = null;
9750                    mTopData = null;
9751                    mTopComponent = null;
9752                    Message msg = Message.obtain();
9753                    msg.what = SHOW_FACTORY_ERROR_MSG;
9754                    msg.getData().putCharSequence("msg", errorMsg);
9755                    mHandler.sendMessage(msg);
9756                }
9757            }
9758        }
9759
9760        retrieveSettings();
9761
9762        synchronized (this) {
9763            readGrantedUriPermissionsLocked();
9764        }
9765
9766        if (goingCallback != null) goingCallback.run();
9767
9768        mSystemServiceManager.startUser(mCurrentUserId);
9769
9770        synchronized (this) {
9771            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9772                try {
9773                    List apps = AppGlobals.getPackageManager().
9774                        getPersistentApplications(STOCK_PM_FLAGS);
9775                    if (apps != null) {
9776                        int N = apps.size();
9777                        int i;
9778                        for (i=0; i<N; i++) {
9779                            ApplicationInfo info
9780                                = (ApplicationInfo)apps.get(i);
9781                            if (info != null &&
9782                                    !info.packageName.equals("android")) {
9783                                addAppLocked(info, false);
9784                            }
9785                        }
9786                    }
9787                } catch (RemoteException ex) {
9788                    // pm is in same process, this will never happen.
9789                }
9790            }
9791
9792            // Start up initial activity.
9793            mBooting = true;
9794
9795            try {
9796                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9797                    Message msg = Message.obtain();
9798                    msg.what = SHOW_UID_ERROR_MSG;
9799                    mHandler.sendMessage(msg);
9800                }
9801            } catch (RemoteException e) {
9802            }
9803
9804            long ident = Binder.clearCallingIdentity();
9805            try {
9806                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9807                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9808                        | Intent.FLAG_RECEIVER_FOREGROUND);
9809                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9810                broadcastIntentLocked(null, null, intent,
9811                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9812                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9813                intent = new Intent(Intent.ACTION_USER_STARTING);
9814                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9815                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9816                broadcastIntentLocked(null, null, intent,
9817                        null, new IIntentReceiver.Stub() {
9818                            @Override
9819                            public void performReceive(Intent intent, int resultCode, String data,
9820                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9821                                    throws RemoteException {
9822                            }
9823                        }, 0, null, null,
9824                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9825                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9826            } catch (Throwable t) {
9827                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9828            } finally {
9829                Binder.restoreCallingIdentity(ident);
9830            }
9831            mStackSupervisor.resumeTopActivitiesLocked();
9832            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9833        }
9834    }
9835
9836    private boolean makeAppCrashingLocked(ProcessRecord app,
9837            String shortMsg, String longMsg, String stackTrace) {
9838        app.crashing = true;
9839        app.crashingReport = generateProcessError(app,
9840                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9841        startAppProblemLocked(app);
9842        app.stopFreezingAllLocked();
9843        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9844    }
9845
9846    private void makeAppNotRespondingLocked(ProcessRecord app,
9847            String activity, String shortMsg, String longMsg) {
9848        app.notResponding = true;
9849        app.notRespondingReport = generateProcessError(app,
9850                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9851                activity, shortMsg, longMsg, null);
9852        startAppProblemLocked(app);
9853        app.stopFreezingAllLocked();
9854    }
9855
9856    /**
9857     * Generate a process error record, suitable for attachment to a ProcessRecord.
9858     *
9859     * @param app The ProcessRecord in which the error occurred.
9860     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9861     *                      ActivityManager.AppErrorStateInfo
9862     * @param activity The activity associated with the crash, if known.
9863     * @param shortMsg Short message describing the crash.
9864     * @param longMsg Long message describing the crash.
9865     * @param stackTrace Full crash stack trace, may be null.
9866     *
9867     * @return Returns a fully-formed AppErrorStateInfo record.
9868     */
9869    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9870            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9871        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9872
9873        report.condition = condition;
9874        report.processName = app.processName;
9875        report.pid = app.pid;
9876        report.uid = app.info.uid;
9877        report.tag = activity;
9878        report.shortMsg = shortMsg;
9879        report.longMsg = longMsg;
9880        report.stackTrace = stackTrace;
9881
9882        return report;
9883    }
9884
9885    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9886        synchronized (this) {
9887            app.crashing = false;
9888            app.crashingReport = null;
9889            app.notResponding = false;
9890            app.notRespondingReport = null;
9891            if (app.anrDialog == fromDialog) {
9892                app.anrDialog = null;
9893            }
9894            if (app.waitDialog == fromDialog) {
9895                app.waitDialog = null;
9896            }
9897            if (app.pid > 0 && app.pid != MY_PID) {
9898                handleAppCrashLocked(app, null, null, null);
9899                killUnneededProcessLocked(app, "user request after error");
9900            }
9901        }
9902    }
9903
9904    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9905            String stackTrace) {
9906        long now = SystemClock.uptimeMillis();
9907
9908        Long crashTime;
9909        if (!app.isolated) {
9910            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9911        } else {
9912            crashTime = null;
9913        }
9914        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9915            // This process loses!
9916            Slog.w(TAG, "Process " + app.info.processName
9917                    + " has crashed too many times: killing!");
9918            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9919                    app.userId, app.info.processName, app.uid);
9920            mStackSupervisor.handleAppCrashLocked(app);
9921            if (!app.persistent) {
9922                // We don't want to start this process again until the user
9923                // explicitly does so...  but for persistent process, we really
9924                // need to keep it running.  If a persistent process is actually
9925                // repeatedly crashing, then badness for everyone.
9926                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9927                        app.info.processName);
9928                if (!app.isolated) {
9929                    // XXX We don't have a way to mark isolated processes
9930                    // as bad, since they don't have a peristent identity.
9931                    mBadProcesses.put(app.info.processName, app.uid,
9932                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9933                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9934                }
9935                app.bad = true;
9936                app.removed = true;
9937                // Don't let services in this process be restarted and potentially
9938                // annoy the user repeatedly.  Unless it is persistent, since those
9939                // processes run critical code.
9940                removeProcessLocked(app, false, false, "crash");
9941                mStackSupervisor.resumeTopActivitiesLocked();
9942                return false;
9943            }
9944            mStackSupervisor.resumeTopActivitiesLocked();
9945        } else {
9946            mStackSupervisor.finishTopRunningActivityLocked(app);
9947        }
9948
9949        // Bump up the crash count of any services currently running in the proc.
9950        for (int i=app.services.size()-1; i>=0; i--) {
9951            // Any services running in the application need to be placed
9952            // back in the pending list.
9953            ServiceRecord sr = app.services.valueAt(i);
9954            sr.crashCount++;
9955        }
9956
9957        // If the crashing process is what we consider to be the "home process" and it has been
9958        // replaced by a third-party app, clear the package preferred activities from packages
9959        // with a home activity running in the process to prevent a repeatedly crashing app
9960        // from blocking the user to manually clear the list.
9961        final ArrayList<ActivityRecord> activities = app.activities;
9962        if (app == mHomeProcess && activities.size() > 0
9963                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9964            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9965                final ActivityRecord r = activities.get(activityNdx);
9966                if (r.isHomeActivity()) {
9967                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9968                    try {
9969                        ActivityThread.getPackageManager()
9970                                .clearPackagePreferredActivities(r.packageName);
9971                    } catch (RemoteException c) {
9972                        // pm is in same process, this will never happen.
9973                    }
9974                }
9975            }
9976        }
9977
9978        if (!app.isolated) {
9979            // XXX Can't keep track of crash times for isolated processes,
9980            // because they don't have a perisistent identity.
9981            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9982        }
9983
9984        return true;
9985    }
9986
9987    void startAppProblemLocked(ProcessRecord app) {
9988        if (app.userId == mCurrentUserId) {
9989            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9990                    mContext, app.info.packageName, app.info.flags);
9991        } else {
9992            // If this app is not running under the current user, then we
9993            // can't give it a report button because that would require
9994            // launching the report UI under a different user.
9995            app.errorReportReceiver = null;
9996        }
9997        skipCurrentReceiverLocked(app);
9998    }
9999
10000    void skipCurrentReceiverLocked(ProcessRecord app) {
10001        for (BroadcastQueue queue : mBroadcastQueues) {
10002            queue.skipCurrentReceiverLocked(app);
10003        }
10004    }
10005
10006    /**
10007     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10008     * The application process will exit immediately after this call returns.
10009     * @param app object of the crashing app, null for the system server
10010     * @param crashInfo describing the exception
10011     */
10012    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10013        ProcessRecord r = findAppProcess(app, "Crash");
10014        final String processName = app == null ? "system_server"
10015                : (r == null ? "unknown" : r.processName);
10016
10017        handleApplicationCrashInner("crash", r, processName, crashInfo);
10018    }
10019
10020    /* Native crash reporting uses this inner version because it needs to be somewhat
10021     * decoupled from the AM-managed cleanup lifecycle
10022     */
10023    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10024            ApplicationErrorReport.CrashInfo crashInfo) {
10025        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10026                UserHandle.getUserId(Binder.getCallingUid()), processName,
10027                r == null ? -1 : r.info.flags,
10028                crashInfo.exceptionClassName,
10029                crashInfo.exceptionMessage,
10030                crashInfo.throwFileName,
10031                crashInfo.throwLineNumber);
10032
10033        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10034
10035        crashApplication(r, crashInfo);
10036    }
10037
10038    public void handleApplicationStrictModeViolation(
10039            IBinder app,
10040            int violationMask,
10041            StrictMode.ViolationInfo info) {
10042        ProcessRecord r = findAppProcess(app, "StrictMode");
10043        if (r == null) {
10044            return;
10045        }
10046
10047        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10048            Integer stackFingerprint = info.hashCode();
10049            boolean logIt = true;
10050            synchronized (mAlreadyLoggedViolatedStacks) {
10051                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10052                    logIt = false;
10053                    // TODO: sub-sample into EventLog for these, with
10054                    // the info.durationMillis?  Then we'd get
10055                    // the relative pain numbers, without logging all
10056                    // the stack traces repeatedly.  We'd want to do
10057                    // likewise in the client code, which also does
10058                    // dup suppression, before the Binder call.
10059                } else {
10060                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10061                        mAlreadyLoggedViolatedStacks.clear();
10062                    }
10063                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10064                }
10065            }
10066            if (logIt) {
10067                logStrictModeViolationToDropBox(r, info);
10068            }
10069        }
10070
10071        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10072            AppErrorResult result = new AppErrorResult();
10073            synchronized (this) {
10074                final long origId = Binder.clearCallingIdentity();
10075
10076                Message msg = Message.obtain();
10077                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10078                HashMap<String, Object> data = new HashMap<String, Object>();
10079                data.put("result", result);
10080                data.put("app", r);
10081                data.put("violationMask", violationMask);
10082                data.put("info", info);
10083                msg.obj = data;
10084                mHandler.sendMessage(msg);
10085
10086                Binder.restoreCallingIdentity(origId);
10087            }
10088            int res = result.get();
10089            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10090        }
10091    }
10092
10093    // Depending on the policy in effect, there could be a bunch of
10094    // these in quick succession so we try to batch these together to
10095    // minimize disk writes, number of dropbox entries, and maximize
10096    // compression, by having more fewer, larger records.
10097    private void logStrictModeViolationToDropBox(
10098            ProcessRecord process,
10099            StrictMode.ViolationInfo info) {
10100        if (info == null) {
10101            return;
10102        }
10103        final boolean isSystemApp = process == null ||
10104                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10105                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10106        final String processName = process == null ? "unknown" : process.processName;
10107        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10108        final DropBoxManager dbox = (DropBoxManager)
10109                mContext.getSystemService(Context.DROPBOX_SERVICE);
10110
10111        // Exit early if the dropbox isn't configured to accept this report type.
10112        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10113
10114        boolean bufferWasEmpty;
10115        boolean needsFlush;
10116        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10117        synchronized (sb) {
10118            bufferWasEmpty = sb.length() == 0;
10119            appendDropBoxProcessHeaders(process, processName, sb);
10120            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10121            sb.append("System-App: ").append(isSystemApp).append("\n");
10122            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10123            if (info.violationNumThisLoop != 0) {
10124                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10125            }
10126            if (info.numAnimationsRunning != 0) {
10127                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10128            }
10129            if (info.broadcastIntentAction != null) {
10130                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10131            }
10132            if (info.durationMillis != -1) {
10133                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10134            }
10135            if (info.numInstances != -1) {
10136                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10137            }
10138            if (info.tags != null) {
10139                for (String tag : info.tags) {
10140                    sb.append("Span-Tag: ").append(tag).append("\n");
10141                }
10142            }
10143            sb.append("\n");
10144            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10145                sb.append(info.crashInfo.stackTrace);
10146            }
10147            sb.append("\n");
10148
10149            // Only buffer up to ~64k.  Various logging bits truncate
10150            // things at 128k.
10151            needsFlush = (sb.length() > 64 * 1024);
10152        }
10153
10154        // Flush immediately if the buffer's grown too large, or this
10155        // is a non-system app.  Non-system apps are isolated with a
10156        // different tag & policy and not batched.
10157        //
10158        // Batching is useful during internal testing with
10159        // StrictMode settings turned up high.  Without batching,
10160        // thousands of separate files could be created on boot.
10161        if (!isSystemApp || needsFlush) {
10162            new Thread("Error dump: " + dropboxTag) {
10163                @Override
10164                public void run() {
10165                    String report;
10166                    synchronized (sb) {
10167                        report = sb.toString();
10168                        sb.delete(0, sb.length());
10169                        sb.trimToSize();
10170                    }
10171                    if (report.length() != 0) {
10172                        dbox.addText(dropboxTag, report);
10173                    }
10174                }
10175            }.start();
10176            return;
10177        }
10178
10179        // System app batching:
10180        if (!bufferWasEmpty) {
10181            // An existing dropbox-writing thread is outstanding, so
10182            // we don't need to start it up.  The existing thread will
10183            // catch the buffer appends we just did.
10184            return;
10185        }
10186
10187        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10188        // (After this point, we shouldn't access AMS internal data structures.)
10189        new Thread("Error dump: " + dropboxTag) {
10190            @Override
10191            public void run() {
10192                // 5 second sleep to let stacks arrive and be batched together
10193                try {
10194                    Thread.sleep(5000);  // 5 seconds
10195                } catch (InterruptedException e) {}
10196
10197                String errorReport;
10198                synchronized (mStrictModeBuffer) {
10199                    errorReport = mStrictModeBuffer.toString();
10200                    if (errorReport.length() == 0) {
10201                        return;
10202                    }
10203                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10204                    mStrictModeBuffer.trimToSize();
10205                }
10206                dbox.addText(dropboxTag, errorReport);
10207            }
10208        }.start();
10209    }
10210
10211    /**
10212     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10213     * @param app object of the crashing app, null for the system server
10214     * @param tag reported by the caller
10215     * @param crashInfo describing the context of the error
10216     * @return true if the process should exit immediately (WTF is fatal)
10217     */
10218    public boolean handleApplicationWtf(IBinder app, String tag,
10219            ApplicationErrorReport.CrashInfo crashInfo) {
10220        ProcessRecord r = findAppProcess(app, "WTF");
10221        final String processName = app == null ? "system_server"
10222                : (r == null ? "unknown" : r.processName);
10223
10224        EventLog.writeEvent(EventLogTags.AM_WTF,
10225                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10226                processName,
10227                r == null ? -1 : r.info.flags,
10228                tag, crashInfo.exceptionMessage);
10229
10230        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10231
10232        if (r != null && r.pid != Process.myPid() &&
10233                Settings.Global.getInt(mContext.getContentResolver(),
10234                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10235            crashApplication(r, crashInfo);
10236            return true;
10237        } else {
10238            return false;
10239        }
10240    }
10241
10242    /**
10243     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10244     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10245     */
10246    private ProcessRecord findAppProcess(IBinder app, String reason) {
10247        if (app == null) {
10248            return null;
10249        }
10250
10251        synchronized (this) {
10252            final int NP = mProcessNames.getMap().size();
10253            for (int ip=0; ip<NP; ip++) {
10254                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10255                final int NA = apps.size();
10256                for (int ia=0; ia<NA; ia++) {
10257                    ProcessRecord p = apps.valueAt(ia);
10258                    if (p.thread != null && p.thread.asBinder() == app) {
10259                        return p;
10260                    }
10261                }
10262            }
10263
10264            Slog.w(TAG, "Can't find mystery application for " + reason
10265                    + " from pid=" + Binder.getCallingPid()
10266                    + " uid=" + Binder.getCallingUid() + ": " + app);
10267            return null;
10268        }
10269    }
10270
10271    /**
10272     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10273     * to append various headers to the dropbox log text.
10274     */
10275    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10276            StringBuilder sb) {
10277        // Watchdog thread ends up invoking this function (with
10278        // a null ProcessRecord) to add the stack file to dropbox.
10279        // Do not acquire a lock on this (am) in such cases, as it
10280        // could cause a potential deadlock, if and when watchdog
10281        // is invoked due to unavailability of lock on am and it
10282        // would prevent watchdog from killing system_server.
10283        if (process == null) {
10284            sb.append("Process: ").append(processName).append("\n");
10285            return;
10286        }
10287        // Note: ProcessRecord 'process' is guarded by the service
10288        // instance.  (notably process.pkgList, which could otherwise change
10289        // concurrently during execution of this method)
10290        synchronized (this) {
10291            sb.append("Process: ").append(processName).append("\n");
10292            int flags = process.info.flags;
10293            IPackageManager pm = AppGlobals.getPackageManager();
10294            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10295            for (int ip=0; ip<process.pkgList.size(); ip++) {
10296                String pkg = process.pkgList.keyAt(ip);
10297                sb.append("Package: ").append(pkg);
10298                try {
10299                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10300                    if (pi != null) {
10301                        sb.append(" v").append(pi.versionCode);
10302                        if (pi.versionName != null) {
10303                            sb.append(" (").append(pi.versionName).append(")");
10304                        }
10305                    }
10306                } catch (RemoteException e) {
10307                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10308                }
10309                sb.append("\n");
10310            }
10311        }
10312    }
10313
10314    private static String processClass(ProcessRecord process) {
10315        if (process == null || process.pid == MY_PID) {
10316            return "system_server";
10317        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10318            return "system_app";
10319        } else {
10320            return "data_app";
10321        }
10322    }
10323
10324    /**
10325     * Write a description of an error (crash, WTF, ANR) to the drop box.
10326     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10327     * @param process which caused the error, null means the system server
10328     * @param activity which triggered the error, null if unknown
10329     * @param parent activity related to the error, null if unknown
10330     * @param subject line related to the error, null if absent
10331     * @param report in long form describing the error, null if absent
10332     * @param logFile to include in the report, null if none
10333     * @param crashInfo giving an application stack trace, null if absent
10334     */
10335    public void addErrorToDropBox(String eventType,
10336            ProcessRecord process, String processName, ActivityRecord activity,
10337            ActivityRecord parent, String subject,
10338            final String report, final File logFile,
10339            final ApplicationErrorReport.CrashInfo crashInfo) {
10340        // NOTE -- this must never acquire the ActivityManagerService lock,
10341        // otherwise the watchdog may be prevented from resetting the system.
10342
10343        final String dropboxTag = processClass(process) + "_" + eventType;
10344        final DropBoxManager dbox = (DropBoxManager)
10345                mContext.getSystemService(Context.DROPBOX_SERVICE);
10346
10347        // Exit early if the dropbox isn't configured to accept this report type.
10348        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10349
10350        final StringBuilder sb = new StringBuilder(1024);
10351        appendDropBoxProcessHeaders(process, processName, sb);
10352        if (activity != null) {
10353            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10354        }
10355        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10356            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10357        }
10358        if (parent != null && parent != activity) {
10359            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10360        }
10361        if (subject != null) {
10362            sb.append("Subject: ").append(subject).append("\n");
10363        }
10364        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10365        if (Debug.isDebuggerConnected()) {
10366            sb.append("Debugger: Connected\n");
10367        }
10368        sb.append("\n");
10369
10370        // Do the rest in a worker thread to avoid blocking the caller on I/O
10371        // (After this point, we shouldn't access AMS internal data structures.)
10372        Thread worker = new Thread("Error dump: " + dropboxTag) {
10373            @Override
10374            public void run() {
10375                if (report != null) {
10376                    sb.append(report);
10377                }
10378                if (logFile != null) {
10379                    try {
10380                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10381                                    "\n\n[[TRUNCATED]]"));
10382                    } catch (IOException e) {
10383                        Slog.e(TAG, "Error reading " + logFile, e);
10384                    }
10385                }
10386                if (crashInfo != null && crashInfo.stackTrace != null) {
10387                    sb.append(crashInfo.stackTrace);
10388                }
10389
10390                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10391                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10392                if (lines > 0) {
10393                    sb.append("\n");
10394
10395                    // Merge several logcat streams, and take the last N lines
10396                    InputStreamReader input = null;
10397                    try {
10398                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10399                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10400                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10401
10402                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10403                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10404                        input = new InputStreamReader(logcat.getInputStream());
10405
10406                        int num;
10407                        char[] buf = new char[8192];
10408                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10409                    } catch (IOException e) {
10410                        Slog.e(TAG, "Error running logcat", e);
10411                    } finally {
10412                        if (input != null) try { input.close(); } catch (IOException e) {}
10413                    }
10414                }
10415
10416                dbox.addText(dropboxTag, sb.toString());
10417            }
10418        };
10419
10420        if (process == null) {
10421            // If process is null, we are being called from some internal code
10422            // and may be about to die -- run this synchronously.
10423            worker.run();
10424        } else {
10425            worker.start();
10426        }
10427    }
10428
10429    /**
10430     * Bring up the "unexpected error" dialog box for a crashing app.
10431     * Deal with edge cases (intercepts from instrumented applications,
10432     * ActivityController, error intent receivers, that sort of thing).
10433     * @param r the application crashing
10434     * @param crashInfo describing the failure
10435     */
10436    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10437        long timeMillis = System.currentTimeMillis();
10438        String shortMsg = crashInfo.exceptionClassName;
10439        String longMsg = crashInfo.exceptionMessage;
10440        String stackTrace = crashInfo.stackTrace;
10441        if (shortMsg != null && longMsg != null) {
10442            longMsg = shortMsg + ": " + longMsg;
10443        } else if (shortMsg != null) {
10444            longMsg = shortMsg;
10445        }
10446
10447        AppErrorResult result = new AppErrorResult();
10448        synchronized (this) {
10449            if (mController != null) {
10450                try {
10451                    String name = r != null ? r.processName : null;
10452                    int pid = r != null ? r.pid : Binder.getCallingPid();
10453                    if (!mController.appCrashed(name, pid,
10454                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10455                        Slog.w(TAG, "Force-killing crashed app " + name
10456                                + " at watcher's request");
10457                        Process.killProcess(pid);
10458                        return;
10459                    }
10460                } catch (RemoteException e) {
10461                    mController = null;
10462                    Watchdog.getInstance().setActivityController(null);
10463                }
10464            }
10465
10466            final long origId = Binder.clearCallingIdentity();
10467
10468            // If this process is running instrumentation, finish it.
10469            if (r != null && r.instrumentationClass != null) {
10470                Slog.w(TAG, "Error in app " + r.processName
10471                      + " running instrumentation " + r.instrumentationClass + ":");
10472                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10473                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10474                Bundle info = new Bundle();
10475                info.putString("shortMsg", shortMsg);
10476                info.putString("longMsg", longMsg);
10477                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10478                Binder.restoreCallingIdentity(origId);
10479                return;
10480            }
10481
10482            // If we can't identify the process or it's already exceeded its crash quota,
10483            // quit right away without showing a crash dialog.
10484            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10485                Binder.restoreCallingIdentity(origId);
10486                return;
10487            }
10488
10489            Message msg = Message.obtain();
10490            msg.what = SHOW_ERROR_MSG;
10491            HashMap data = new HashMap();
10492            data.put("result", result);
10493            data.put("app", r);
10494            msg.obj = data;
10495            mHandler.sendMessage(msg);
10496
10497            Binder.restoreCallingIdentity(origId);
10498        }
10499
10500        int res = result.get();
10501
10502        Intent appErrorIntent = null;
10503        synchronized (this) {
10504            if (r != null && !r.isolated) {
10505                // XXX Can't keep track of crash time for isolated processes,
10506                // since they don't have a persistent identity.
10507                mProcessCrashTimes.put(r.info.processName, r.uid,
10508                        SystemClock.uptimeMillis());
10509            }
10510            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10511                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10512            }
10513        }
10514
10515        if (appErrorIntent != null) {
10516            try {
10517                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10518            } catch (ActivityNotFoundException e) {
10519                Slog.w(TAG, "bug report receiver dissappeared", e);
10520            }
10521        }
10522    }
10523
10524    Intent createAppErrorIntentLocked(ProcessRecord r,
10525            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10526        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10527        if (report == null) {
10528            return null;
10529        }
10530        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10531        result.setComponent(r.errorReportReceiver);
10532        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10533        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10534        return result;
10535    }
10536
10537    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10538            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10539        if (r.errorReportReceiver == null) {
10540            return null;
10541        }
10542
10543        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10544            return null;
10545        }
10546
10547        ApplicationErrorReport report = new ApplicationErrorReport();
10548        report.packageName = r.info.packageName;
10549        report.installerPackageName = r.errorReportReceiver.getPackageName();
10550        report.processName = r.processName;
10551        report.time = timeMillis;
10552        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10553
10554        if (r.crashing || r.forceCrashReport) {
10555            report.type = ApplicationErrorReport.TYPE_CRASH;
10556            report.crashInfo = crashInfo;
10557        } else if (r.notResponding) {
10558            report.type = ApplicationErrorReport.TYPE_ANR;
10559            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10560
10561            report.anrInfo.activity = r.notRespondingReport.tag;
10562            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10563            report.anrInfo.info = r.notRespondingReport.longMsg;
10564        }
10565
10566        return report;
10567    }
10568
10569    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10570        enforceNotIsolatedCaller("getProcessesInErrorState");
10571        // assume our apps are happy - lazy create the list
10572        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10573
10574        final boolean allUsers = ActivityManager.checkUidPermission(
10575                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10576                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10577        int userId = UserHandle.getUserId(Binder.getCallingUid());
10578
10579        synchronized (this) {
10580
10581            // iterate across all processes
10582            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10583                ProcessRecord app = mLruProcesses.get(i);
10584                if (!allUsers && app.userId != userId) {
10585                    continue;
10586                }
10587                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10588                    // This one's in trouble, so we'll generate a report for it
10589                    // crashes are higher priority (in case there's a crash *and* an anr)
10590                    ActivityManager.ProcessErrorStateInfo report = null;
10591                    if (app.crashing) {
10592                        report = app.crashingReport;
10593                    } else if (app.notResponding) {
10594                        report = app.notRespondingReport;
10595                    }
10596
10597                    if (report != null) {
10598                        if (errList == null) {
10599                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10600                        }
10601                        errList.add(report);
10602                    } else {
10603                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10604                                " crashing = " + app.crashing +
10605                                " notResponding = " + app.notResponding);
10606                    }
10607                }
10608            }
10609        }
10610
10611        return errList;
10612    }
10613
10614    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10615        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10616            if (currApp != null) {
10617                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10618            }
10619            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10620        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10621            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10622        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10623            if (currApp != null) {
10624                currApp.lru = 0;
10625            }
10626            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10627        } else if (adj >= ProcessList.SERVICE_ADJ) {
10628            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10629        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10630            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10631        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10632            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10633        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10634            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10635        } else {
10636            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10637        }
10638    }
10639
10640    private void fillInProcMemInfo(ProcessRecord app,
10641            ActivityManager.RunningAppProcessInfo outInfo) {
10642        outInfo.pid = app.pid;
10643        outInfo.uid = app.info.uid;
10644        if (mHeavyWeightProcess == app) {
10645            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10646        }
10647        if (app.persistent) {
10648            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10649        }
10650        if (app.activities.size() > 0) {
10651            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10652        }
10653        outInfo.lastTrimLevel = app.trimMemoryLevel;
10654        int adj = app.curAdj;
10655        outInfo.importance = oomAdjToImportance(adj, outInfo);
10656        outInfo.importanceReasonCode = app.adjTypeCode;
10657        outInfo.processState = app.curProcState;
10658    }
10659
10660    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10661        enforceNotIsolatedCaller("getRunningAppProcesses");
10662        // Lazy instantiation of list
10663        List<ActivityManager.RunningAppProcessInfo> runList = null;
10664        final boolean allUsers = ActivityManager.checkUidPermission(
10665                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10666                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10667        int userId = UserHandle.getUserId(Binder.getCallingUid());
10668        synchronized (this) {
10669            // Iterate across all processes
10670            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10671                ProcessRecord app = mLruProcesses.get(i);
10672                if (!allUsers && app.userId != userId) {
10673                    continue;
10674                }
10675                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10676                    // Generate process state info for running application
10677                    ActivityManager.RunningAppProcessInfo currApp =
10678                        new ActivityManager.RunningAppProcessInfo(app.processName,
10679                                app.pid, app.getPackageList());
10680                    fillInProcMemInfo(app, currApp);
10681                    if (app.adjSource instanceof ProcessRecord) {
10682                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10683                        currApp.importanceReasonImportance = oomAdjToImportance(
10684                                app.adjSourceOom, null);
10685                    } else if (app.adjSource instanceof ActivityRecord) {
10686                        ActivityRecord r = (ActivityRecord)app.adjSource;
10687                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10688                    }
10689                    if (app.adjTarget instanceof ComponentName) {
10690                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10691                    }
10692                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10693                    //        + " lru=" + currApp.lru);
10694                    if (runList == null) {
10695                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10696                    }
10697                    runList.add(currApp);
10698                }
10699            }
10700        }
10701        return runList;
10702    }
10703
10704    public List<ApplicationInfo> getRunningExternalApplications() {
10705        enforceNotIsolatedCaller("getRunningExternalApplications");
10706        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10707        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10708        if (runningApps != null && runningApps.size() > 0) {
10709            Set<String> extList = new HashSet<String>();
10710            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10711                if (app.pkgList != null) {
10712                    for (String pkg : app.pkgList) {
10713                        extList.add(pkg);
10714                    }
10715                }
10716            }
10717            IPackageManager pm = AppGlobals.getPackageManager();
10718            for (String pkg : extList) {
10719                try {
10720                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10721                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10722                        retList.add(info);
10723                    }
10724                } catch (RemoteException e) {
10725                }
10726            }
10727        }
10728        return retList;
10729    }
10730
10731    @Override
10732    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10733        enforceNotIsolatedCaller("getMyMemoryState");
10734        synchronized (this) {
10735            ProcessRecord proc;
10736            synchronized (mPidsSelfLocked) {
10737                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10738            }
10739            fillInProcMemInfo(proc, outInfo);
10740        }
10741    }
10742
10743    @Override
10744    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10745        if (checkCallingPermission(android.Manifest.permission.DUMP)
10746                != PackageManager.PERMISSION_GRANTED) {
10747            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10748                    + Binder.getCallingPid()
10749                    + ", uid=" + Binder.getCallingUid()
10750                    + " without permission "
10751                    + android.Manifest.permission.DUMP);
10752            return;
10753        }
10754
10755        boolean dumpAll = false;
10756        boolean dumpClient = false;
10757        String dumpPackage = null;
10758
10759        int opti = 0;
10760        while (opti < args.length) {
10761            String opt = args[opti];
10762            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10763                break;
10764            }
10765            opti++;
10766            if ("-a".equals(opt)) {
10767                dumpAll = true;
10768            } else if ("-c".equals(opt)) {
10769                dumpClient = true;
10770            } else if ("-h".equals(opt)) {
10771                pw.println("Activity manager dump options:");
10772                pw.println("  [-a] [-c] [-h] [cmd] ...");
10773                pw.println("  cmd may be one of:");
10774                pw.println("    a[ctivities]: activity stack state");
10775                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10776                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10777                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10778                pw.println("    o[om]: out of memory management");
10779                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10780                pw.println("    provider [COMP_SPEC]: provider client-side state");
10781                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10782                pw.println("    service [COMP_SPEC]: service client-side state");
10783                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10784                pw.println("    all: dump all activities");
10785                pw.println("    top: dump the top activity");
10786                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10787                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10788                pw.println("    a partial substring in a component name, a");
10789                pw.println("    hex object identifier.");
10790                pw.println("  -a: include all available server state.");
10791                pw.println("  -c: include client state.");
10792                return;
10793            } else {
10794                pw.println("Unknown argument: " + opt + "; use -h for help");
10795            }
10796        }
10797
10798        long origId = Binder.clearCallingIdentity();
10799        boolean more = false;
10800        // Is the caller requesting to dump a particular piece of data?
10801        if (opti < args.length) {
10802            String cmd = args[opti];
10803            opti++;
10804            if ("activities".equals(cmd) || "a".equals(cmd)) {
10805                synchronized (this) {
10806                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10807                }
10808            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10809                String[] newArgs;
10810                String name;
10811                if (opti >= args.length) {
10812                    name = null;
10813                    newArgs = EMPTY_STRING_ARRAY;
10814                } else {
10815                    name = args[opti];
10816                    opti++;
10817                    newArgs = new String[args.length - opti];
10818                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10819                            args.length - opti);
10820                }
10821                synchronized (this) {
10822                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10823                }
10824            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10825                String[] newArgs;
10826                String name;
10827                if (opti >= args.length) {
10828                    name = null;
10829                    newArgs = EMPTY_STRING_ARRAY;
10830                } else {
10831                    name = args[opti];
10832                    opti++;
10833                    newArgs = new String[args.length - opti];
10834                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10835                            args.length - opti);
10836                }
10837                synchronized (this) {
10838                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10839                }
10840            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10841                String[] newArgs;
10842                String name;
10843                if (opti >= args.length) {
10844                    name = null;
10845                    newArgs = EMPTY_STRING_ARRAY;
10846                } else {
10847                    name = args[opti];
10848                    opti++;
10849                    newArgs = new String[args.length - opti];
10850                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10851                            args.length - opti);
10852                }
10853                synchronized (this) {
10854                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10855                }
10856            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10857                synchronized (this) {
10858                    dumpOomLocked(fd, pw, args, opti, true);
10859                }
10860            } else if ("provider".equals(cmd)) {
10861                String[] newArgs;
10862                String name;
10863                if (opti >= args.length) {
10864                    name = null;
10865                    newArgs = EMPTY_STRING_ARRAY;
10866                } else {
10867                    name = args[opti];
10868                    opti++;
10869                    newArgs = new String[args.length - opti];
10870                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10871                }
10872                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10873                    pw.println("No providers match: " + name);
10874                    pw.println("Use -h for help.");
10875                }
10876            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10877                synchronized (this) {
10878                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10879                }
10880            } else if ("service".equals(cmd)) {
10881                String[] newArgs;
10882                String name;
10883                if (opti >= args.length) {
10884                    name = null;
10885                    newArgs = EMPTY_STRING_ARRAY;
10886                } else {
10887                    name = args[opti];
10888                    opti++;
10889                    newArgs = new String[args.length - opti];
10890                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10891                            args.length - opti);
10892                }
10893                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10894                    pw.println("No services match: " + name);
10895                    pw.println("Use -h for help.");
10896                }
10897            } else if ("package".equals(cmd)) {
10898                String[] newArgs;
10899                if (opti >= args.length) {
10900                    pw.println("package: no package name specified");
10901                    pw.println("Use -h for help.");
10902                } else {
10903                    dumpPackage = args[opti];
10904                    opti++;
10905                    newArgs = new String[args.length - opti];
10906                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10907                            args.length - opti);
10908                    args = newArgs;
10909                    opti = 0;
10910                    more = true;
10911                }
10912            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10913                synchronized (this) {
10914                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10915                }
10916            } else {
10917                // Dumping a single activity?
10918                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10919                    pw.println("Bad activity command, or no activities match: " + cmd);
10920                    pw.println("Use -h for help.");
10921                }
10922            }
10923            if (!more) {
10924                Binder.restoreCallingIdentity(origId);
10925                return;
10926            }
10927        }
10928
10929        // No piece of data specified, dump everything.
10930        synchronized (this) {
10931            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10932            pw.println();
10933            if (dumpAll) {
10934                pw.println("-------------------------------------------------------------------------------");
10935            }
10936            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10937            pw.println();
10938            if (dumpAll) {
10939                pw.println("-------------------------------------------------------------------------------");
10940            }
10941            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10942            pw.println();
10943            if (dumpAll) {
10944                pw.println("-------------------------------------------------------------------------------");
10945            }
10946            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10947            pw.println();
10948            if (dumpAll) {
10949                pw.println("-------------------------------------------------------------------------------");
10950            }
10951            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10952            pw.println();
10953            if (dumpAll) {
10954                pw.println("-------------------------------------------------------------------------------");
10955            }
10956            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10957        }
10958        Binder.restoreCallingIdentity(origId);
10959    }
10960
10961    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10962            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10963        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10964
10965        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10966                dumpPackage);
10967        boolean needSep = printedAnything;
10968
10969        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10970                dumpPackage, needSep, "  mFocusedActivity: ");
10971        if (printed) {
10972            printedAnything = true;
10973            needSep = false;
10974        }
10975
10976        if (dumpPackage == null) {
10977            if (needSep) {
10978                pw.println();
10979            }
10980            needSep = true;
10981            printedAnything = true;
10982            mStackSupervisor.dump(pw, "  ");
10983        }
10984
10985        if (mRecentTasks.size() > 0) {
10986            boolean printedHeader = false;
10987
10988            final int N = mRecentTasks.size();
10989            for (int i=0; i<N; i++) {
10990                TaskRecord tr = mRecentTasks.get(i);
10991                if (dumpPackage != null) {
10992                    if (tr.realActivity == null ||
10993                            !dumpPackage.equals(tr.realActivity)) {
10994                        continue;
10995                    }
10996                }
10997                if (!printedHeader) {
10998                    if (needSep) {
10999                        pw.println();
11000                    }
11001                    pw.println("  Recent tasks:");
11002                    printedHeader = true;
11003                    printedAnything = true;
11004                }
11005                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11006                        pw.println(tr);
11007                if (dumpAll) {
11008                    mRecentTasks.get(i).dump(pw, "    ");
11009                }
11010            }
11011        }
11012
11013        if (!printedAnything) {
11014            pw.println("  (nothing)");
11015        }
11016    }
11017
11018    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11019            int opti, boolean dumpAll, String dumpPackage) {
11020        boolean needSep = false;
11021        boolean printedAnything = false;
11022        int numPers = 0;
11023
11024        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11025
11026        if (dumpAll) {
11027            final int NP = mProcessNames.getMap().size();
11028            for (int ip=0; ip<NP; ip++) {
11029                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11030                final int NA = procs.size();
11031                for (int ia=0; ia<NA; ia++) {
11032                    ProcessRecord r = procs.valueAt(ia);
11033                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11034                        continue;
11035                    }
11036                    if (!needSep) {
11037                        pw.println("  All known processes:");
11038                        needSep = true;
11039                        printedAnything = true;
11040                    }
11041                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11042                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11043                        pw.print(" "); pw.println(r);
11044                    r.dump(pw, "    ");
11045                    if (r.persistent) {
11046                        numPers++;
11047                    }
11048                }
11049            }
11050        }
11051
11052        if (mIsolatedProcesses.size() > 0) {
11053            boolean printed = false;
11054            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11055                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11056                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11057                    continue;
11058                }
11059                if (!printed) {
11060                    if (needSep) {
11061                        pw.println();
11062                    }
11063                    pw.println("  Isolated process list (sorted by uid):");
11064                    printedAnything = true;
11065                    printed = true;
11066                    needSep = true;
11067                }
11068                pw.println(String.format("%sIsolated #%2d: %s",
11069                        "    ", i, r.toString()));
11070            }
11071        }
11072
11073        if (mLruProcesses.size() > 0) {
11074            if (needSep) {
11075                pw.println();
11076            }
11077            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11078                    pw.print(" total, non-act at ");
11079                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11080                    pw.print(", non-svc at ");
11081                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11082                    pw.println("):");
11083            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11084            needSep = true;
11085            printedAnything = true;
11086        }
11087
11088        if (dumpAll || dumpPackage != null) {
11089            synchronized (mPidsSelfLocked) {
11090                boolean printed = false;
11091                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11092                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11093                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11094                        continue;
11095                    }
11096                    if (!printed) {
11097                        if (needSep) pw.println();
11098                        needSep = true;
11099                        pw.println("  PID mappings:");
11100                        printed = true;
11101                        printedAnything = true;
11102                    }
11103                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11104                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11105                }
11106            }
11107        }
11108
11109        if (mForegroundProcesses.size() > 0) {
11110            synchronized (mPidsSelfLocked) {
11111                boolean printed = false;
11112                for (int i=0; i<mForegroundProcesses.size(); i++) {
11113                    ProcessRecord r = mPidsSelfLocked.get(
11114                            mForegroundProcesses.valueAt(i).pid);
11115                    if (dumpPackage != null && (r == null
11116                            || !r.pkgList.containsKey(dumpPackage))) {
11117                        continue;
11118                    }
11119                    if (!printed) {
11120                        if (needSep) pw.println();
11121                        needSep = true;
11122                        pw.println("  Foreground Processes:");
11123                        printed = true;
11124                        printedAnything = true;
11125                    }
11126                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11127                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11128                }
11129            }
11130        }
11131
11132        if (mPersistentStartingProcesses.size() > 0) {
11133            if (needSep) pw.println();
11134            needSep = true;
11135            printedAnything = true;
11136            pw.println("  Persisent processes that are starting:");
11137            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11138                    "Starting Norm", "Restarting PERS", dumpPackage);
11139        }
11140
11141        if (mRemovedProcesses.size() > 0) {
11142            if (needSep) pw.println();
11143            needSep = true;
11144            printedAnything = true;
11145            pw.println("  Processes that are being removed:");
11146            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11147                    "Removed Norm", "Removed PERS", dumpPackage);
11148        }
11149
11150        if (mProcessesOnHold.size() > 0) {
11151            if (needSep) pw.println();
11152            needSep = true;
11153            printedAnything = true;
11154            pw.println("  Processes that are on old until the system is ready:");
11155            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11156                    "OnHold Norm", "OnHold PERS", dumpPackage);
11157        }
11158
11159        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11160
11161        if (mProcessCrashTimes.getMap().size() > 0) {
11162            boolean printed = false;
11163            long now = SystemClock.uptimeMillis();
11164            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11165            final int NP = pmap.size();
11166            for (int ip=0; ip<NP; ip++) {
11167                String pname = pmap.keyAt(ip);
11168                SparseArray<Long> uids = pmap.valueAt(ip);
11169                final int N = uids.size();
11170                for (int i=0; i<N; i++) {
11171                    int puid = uids.keyAt(i);
11172                    ProcessRecord r = mProcessNames.get(pname, puid);
11173                    if (dumpPackage != null && (r == null
11174                            || !r.pkgList.containsKey(dumpPackage))) {
11175                        continue;
11176                    }
11177                    if (!printed) {
11178                        if (needSep) pw.println();
11179                        needSep = true;
11180                        pw.println("  Time since processes crashed:");
11181                        printed = true;
11182                        printedAnything = true;
11183                    }
11184                    pw.print("    Process "); pw.print(pname);
11185                            pw.print(" uid "); pw.print(puid);
11186                            pw.print(": last crashed ");
11187                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11188                            pw.println(" ago");
11189                }
11190            }
11191        }
11192
11193        if (mBadProcesses.getMap().size() > 0) {
11194            boolean printed = false;
11195            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11196            final int NP = pmap.size();
11197            for (int ip=0; ip<NP; ip++) {
11198                String pname = pmap.keyAt(ip);
11199                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11200                final int N = uids.size();
11201                for (int i=0; i<N; i++) {
11202                    int puid = uids.keyAt(i);
11203                    ProcessRecord r = mProcessNames.get(pname, puid);
11204                    if (dumpPackage != null && (r == null
11205                            || !r.pkgList.containsKey(dumpPackage))) {
11206                        continue;
11207                    }
11208                    if (!printed) {
11209                        if (needSep) pw.println();
11210                        needSep = true;
11211                        pw.println("  Bad processes:");
11212                        printedAnything = true;
11213                    }
11214                    BadProcessInfo info = uids.valueAt(i);
11215                    pw.print("    Bad process "); pw.print(pname);
11216                            pw.print(" uid "); pw.print(puid);
11217                            pw.print(": crashed at time "); pw.println(info.time);
11218                    if (info.shortMsg != null) {
11219                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11220                    }
11221                    if (info.longMsg != null) {
11222                        pw.print("      Long msg: "); pw.println(info.longMsg);
11223                    }
11224                    if (info.stack != null) {
11225                        pw.println("      Stack:");
11226                        int lastPos = 0;
11227                        for (int pos=0; pos<info.stack.length(); pos++) {
11228                            if (info.stack.charAt(pos) == '\n') {
11229                                pw.print("        ");
11230                                pw.write(info.stack, lastPos, pos-lastPos);
11231                                pw.println();
11232                                lastPos = pos+1;
11233                            }
11234                        }
11235                        if (lastPos < info.stack.length()) {
11236                            pw.print("        ");
11237                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11238                            pw.println();
11239                        }
11240                    }
11241                }
11242            }
11243        }
11244
11245        if (dumpPackage == null) {
11246            pw.println();
11247            needSep = false;
11248            pw.println("  mStartedUsers:");
11249            for (int i=0; i<mStartedUsers.size(); i++) {
11250                UserStartedState uss = mStartedUsers.valueAt(i);
11251                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11252                        pw.print(": "); uss.dump("", pw);
11253            }
11254            pw.print("  mStartedUserArray: [");
11255            for (int i=0; i<mStartedUserArray.length; i++) {
11256                if (i > 0) pw.print(", ");
11257                pw.print(mStartedUserArray[i]);
11258            }
11259            pw.println("]");
11260            pw.print("  mUserLru: [");
11261            for (int i=0; i<mUserLru.size(); i++) {
11262                if (i > 0) pw.print(", ");
11263                pw.print(mUserLru.get(i));
11264            }
11265            pw.println("]");
11266            if (dumpAll) {
11267                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11268            }
11269        }
11270        if (mHomeProcess != null && (dumpPackage == null
11271                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11272            if (needSep) {
11273                pw.println();
11274                needSep = false;
11275            }
11276            pw.println("  mHomeProcess: " + mHomeProcess);
11277        }
11278        if (mPreviousProcess != null && (dumpPackage == null
11279                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11280            if (needSep) {
11281                pw.println();
11282                needSep = false;
11283            }
11284            pw.println("  mPreviousProcess: " + mPreviousProcess);
11285        }
11286        if (dumpAll) {
11287            StringBuilder sb = new StringBuilder(128);
11288            sb.append("  mPreviousProcessVisibleTime: ");
11289            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11290            pw.println(sb);
11291        }
11292        if (mHeavyWeightProcess != null && (dumpPackage == null
11293                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11294            if (needSep) {
11295                pw.println();
11296                needSep = false;
11297            }
11298            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11299        }
11300        if (dumpPackage == null) {
11301            pw.println("  mConfiguration: " + mConfiguration);
11302        }
11303        if (dumpAll) {
11304            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11305            if (mCompatModePackages.getPackages().size() > 0) {
11306                boolean printed = false;
11307                for (Map.Entry<String, Integer> entry
11308                        : mCompatModePackages.getPackages().entrySet()) {
11309                    String pkg = entry.getKey();
11310                    int mode = entry.getValue();
11311                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11312                        continue;
11313                    }
11314                    if (!printed) {
11315                        pw.println("  mScreenCompatPackages:");
11316                        printed = true;
11317                    }
11318                    pw.print("    "); pw.print(pkg); pw.print(": ");
11319                            pw.print(mode); pw.println();
11320                }
11321            }
11322        }
11323        if (dumpPackage == null) {
11324            if (mSleeping || mWentToSleep || mLockScreenShown) {
11325                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11326                        + " mLockScreenShown " + mLockScreenShown);
11327            }
11328            if (mShuttingDown || mRunningVoice) {
11329                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11330            }
11331        }
11332        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11333                || mOrigWaitForDebugger) {
11334            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11335                    || dumpPackage.equals(mOrigDebugApp)) {
11336                if (needSep) {
11337                    pw.println();
11338                    needSep = false;
11339                }
11340                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11341                        + " mDebugTransient=" + mDebugTransient
11342                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11343            }
11344        }
11345        if (mOpenGlTraceApp != null) {
11346            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11347                if (needSep) {
11348                    pw.println();
11349                    needSep = false;
11350                }
11351                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11352            }
11353        }
11354        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11355                || mProfileFd != null) {
11356            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11357                if (needSep) {
11358                    pw.println();
11359                    needSep = false;
11360                }
11361                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11362                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11363                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11364                        + mAutoStopProfiler);
11365            }
11366        }
11367        if (dumpPackage == null) {
11368            if (mAlwaysFinishActivities || mController != null) {
11369                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11370                        + " mController=" + mController);
11371            }
11372            if (dumpAll) {
11373                pw.println("  Total persistent processes: " + numPers);
11374                pw.println("  mProcessesReady=" + mProcessesReady
11375                        + " mSystemReady=" + mSystemReady);
11376                pw.println("  mBooting=" + mBooting
11377                        + " mBooted=" + mBooted
11378                        + " mFactoryTest=" + mFactoryTest);
11379                pw.print("  mLastPowerCheckRealtime=");
11380                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11381                        pw.println("");
11382                pw.print("  mLastPowerCheckUptime=");
11383                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11384                        pw.println("");
11385                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11386                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11387                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11388                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11389                        + " (" + mLruProcesses.size() + " total)"
11390                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11391                        + " mNumServiceProcs=" + mNumServiceProcs
11392                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11393                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11394                        + " mLastMemoryLevel" + mLastMemoryLevel
11395                        + " mLastNumProcesses" + mLastNumProcesses);
11396                long now = SystemClock.uptimeMillis();
11397                pw.print("  mLastIdleTime=");
11398                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11399                        pw.print(" mLowRamSinceLastIdle=");
11400                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11401                        pw.println();
11402            }
11403        }
11404
11405        if (!printedAnything) {
11406            pw.println("  (nothing)");
11407        }
11408    }
11409
11410    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11411            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11412        if (mProcessesToGc.size() > 0) {
11413            boolean printed = false;
11414            long now = SystemClock.uptimeMillis();
11415            for (int i=0; i<mProcessesToGc.size(); i++) {
11416                ProcessRecord proc = mProcessesToGc.get(i);
11417                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11418                    continue;
11419                }
11420                if (!printed) {
11421                    if (needSep) pw.println();
11422                    needSep = true;
11423                    pw.println("  Processes that are waiting to GC:");
11424                    printed = true;
11425                }
11426                pw.print("    Process "); pw.println(proc);
11427                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11428                        pw.print(", last gced=");
11429                        pw.print(now-proc.lastRequestedGc);
11430                        pw.print(" ms ago, last lowMem=");
11431                        pw.print(now-proc.lastLowMemory);
11432                        pw.println(" ms ago");
11433
11434            }
11435        }
11436        return needSep;
11437    }
11438
11439    void printOomLevel(PrintWriter pw, String name, int adj) {
11440        pw.print("    ");
11441        if (adj >= 0) {
11442            pw.print(' ');
11443            if (adj < 10) pw.print(' ');
11444        } else {
11445            if (adj > -10) pw.print(' ');
11446        }
11447        pw.print(adj);
11448        pw.print(": ");
11449        pw.print(name);
11450        pw.print(" (");
11451        pw.print(mProcessList.getMemLevel(adj)/1024);
11452        pw.println(" kB)");
11453    }
11454
11455    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11456            int opti, boolean dumpAll) {
11457        boolean needSep = false;
11458
11459        if (mLruProcesses.size() > 0) {
11460            if (needSep) pw.println();
11461            needSep = true;
11462            pw.println("  OOM levels:");
11463            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11464            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11465            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11466            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11467            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11468            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11469            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11470            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11471            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11472            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11473            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11474            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11475            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11476
11477            if (needSep) pw.println();
11478            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11479                    pw.print(" total, non-act at ");
11480                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11481                    pw.print(", non-svc at ");
11482                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11483                    pw.println("):");
11484            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11485            needSep = true;
11486        }
11487
11488        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11489
11490        pw.println();
11491        pw.println("  mHomeProcess: " + mHomeProcess);
11492        pw.println("  mPreviousProcess: " + mPreviousProcess);
11493        if (mHeavyWeightProcess != null) {
11494            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11495        }
11496
11497        return true;
11498    }
11499
11500    /**
11501     * There are three ways to call this:
11502     *  - no provider specified: dump all the providers
11503     *  - a flattened component name that matched an existing provider was specified as the
11504     *    first arg: dump that one provider
11505     *  - the first arg isn't the flattened component name of an existing provider:
11506     *    dump all providers whose component contains the first arg as a substring
11507     */
11508    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11509            int opti, boolean dumpAll) {
11510        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11511    }
11512
11513    static class ItemMatcher {
11514        ArrayList<ComponentName> components;
11515        ArrayList<String> strings;
11516        ArrayList<Integer> objects;
11517        boolean all;
11518
11519        ItemMatcher() {
11520            all = true;
11521        }
11522
11523        void build(String name) {
11524            ComponentName componentName = ComponentName.unflattenFromString(name);
11525            if (componentName != null) {
11526                if (components == null) {
11527                    components = new ArrayList<ComponentName>();
11528                }
11529                components.add(componentName);
11530                all = false;
11531            } else {
11532                int objectId = 0;
11533                // Not a '/' separated full component name; maybe an object ID?
11534                try {
11535                    objectId = Integer.parseInt(name, 16);
11536                    if (objects == null) {
11537                        objects = new ArrayList<Integer>();
11538                    }
11539                    objects.add(objectId);
11540                    all = false;
11541                } catch (RuntimeException e) {
11542                    // Not an integer; just do string match.
11543                    if (strings == null) {
11544                        strings = new ArrayList<String>();
11545                    }
11546                    strings.add(name);
11547                    all = false;
11548                }
11549            }
11550        }
11551
11552        int build(String[] args, int opti) {
11553            for (; opti<args.length; opti++) {
11554                String name = args[opti];
11555                if ("--".equals(name)) {
11556                    return opti+1;
11557                }
11558                build(name);
11559            }
11560            return opti;
11561        }
11562
11563        boolean match(Object object, ComponentName comp) {
11564            if (all) {
11565                return true;
11566            }
11567            if (components != null) {
11568                for (int i=0; i<components.size(); i++) {
11569                    if (components.get(i).equals(comp)) {
11570                        return true;
11571                    }
11572                }
11573            }
11574            if (objects != null) {
11575                for (int i=0; i<objects.size(); i++) {
11576                    if (System.identityHashCode(object) == objects.get(i)) {
11577                        return true;
11578                    }
11579                }
11580            }
11581            if (strings != null) {
11582                String flat = comp.flattenToString();
11583                for (int i=0; i<strings.size(); i++) {
11584                    if (flat.contains(strings.get(i))) {
11585                        return true;
11586                    }
11587                }
11588            }
11589            return false;
11590        }
11591    }
11592
11593    /**
11594     * There are three things that cmd can be:
11595     *  - a flattened component name that matches an existing activity
11596     *  - the cmd arg isn't the flattened component name of an existing activity:
11597     *    dump all activity whose component contains the cmd as a substring
11598     *  - A hex number of the ActivityRecord object instance.
11599     */
11600    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11601            int opti, boolean dumpAll) {
11602        ArrayList<ActivityRecord> activities;
11603
11604        synchronized (this) {
11605            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11606        }
11607
11608        if (activities.size() <= 0) {
11609            return false;
11610        }
11611
11612        String[] newArgs = new String[args.length - opti];
11613        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11614
11615        TaskRecord lastTask = null;
11616        boolean needSep = false;
11617        for (int i=activities.size()-1; i>=0; i--) {
11618            ActivityRecord r = activities.get(i);
11619            if (needSep) {
11620                pw.println();
11621            }
11622            needSep = true;
11623            synchronized (this) {
11624                if (lastTask != r.task) {
11625                    lastTask = r.task;
11626                    pw.print("TASK "); pw.print(lastTask.affinity);
11627                            pw.print(" id="); pw.println(lastTask.taskId);
11628                    if (dumpAll) {
11629                        lastTask.dump(pw, "  ");
11630                    }
11631                }
11632            }
11633            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11634        }
11635        return true;
11636    }
11637
11638    /**
11639     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11640     * there is a thread associated with the activity.
11641     */
11642    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11643            final ActivityRecord r, String[] args, boolean dumpAll) {
11644        String innerPrefix = prefix + "  ";
11645        synchronized (this) {
11646            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11647                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11648                    pw.print(" pid=");
11649                    if (r.app != null) pw.println(r.app.pid);
11650                    else pw.println("(not running)");
11651            if (dumpAll) {
11652                r.dump(pw, innerPrefix);
11653            }
11654        }
11655        if (r.app != null && r.app.thread != null) {
11656            // flush anything that is already in the PrintWriter since the thread is going
11657            // to write to the file descriptor directly
11658            pw.flush();
11659            try {
11660                TransferPipe tp = new TransferPipe();
11661                try {
11662                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11663                            r.appToken, innerPrefix, args);
11664                    tp.go(fd);
11665                } finally {
11666                    tp.kill();
11667                }
11668            } catch (IOException e) {
11669                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11670            } catch (RemoteException e) {
11671                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11672            }
11673        }
11674    }
11675
11676    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11677            int opti, boolean dumpAll, String dumpPackage) {
11678        boolean needSep = false;
11679        boolean onlyHistory = false;
11680        boolean printedAnything = false;
11681
11682        if ("history".equals(dumpPackage)) {
11683            if (opti < args.length && "-s".equals(args[opti])) {
11684                dumpAll = false;
11685            }
11686            onlyHistory = true;
11687            dumpPackage = null;
11688        }
11689
11690        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11691        if (!onlyHistory && dumpAll) {
11692            if (mRegisteredReceivers.size() > 0) {
11693                boolean printed = false;
11694                Iterator it = mRegisteredReceivers.values().iterator();
11695                while (it.hasNext()) {
11696                    ReceiverList r = (ReceiverList)it.next();
11697                    if (dumpPackage != null && (r.app == null ||
11698                            !dumpPackage.equals(r.app.info.packageName))) {
11699                        continue;
11700                    }
11701                    if (!printed) {
11702                        pw.println("  Registered Receivers:");
11703                        needSep = true;
11704                        printed = true;
11705                        printedAnything = true;
11706                    }
11707                    pw.print("  * "); pw.println(r);
11708                    r.dump(pw, "    ");
11709                }
11710            }
11711
11712            if (mReceiverResolver.dump(pw, needSep ?
11713                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11714                    "    ", dumpPackage, false)) {
11715                needSep = true;
11716                printedAnything = true;
11717            }
11718        }
11719
11720        for (BroadcastQueue q : mBroadcastQueues) {
11721            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11722            printedAnything |= needSep;
11723        }
11724
11725        needSep = true;
11726
11727        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11728            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11729                if (needSep) {
11730                    pw.println();
11731                }
11732                needSep = true;
11733                printedAnything = true;
11734                pw.print("  Sticky broadcasts for user ");
11735                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11736                StringBuilder sb = new StringBuilder(128);
11737                for (Map.Entry<String, ArrayList<Intent>> ent
11738                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11739                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11740                    if (dumpAll) {
11741                        pw.println(":");
11742                        ArrayList<Intent> intents = ent.getValue();
11743                        final int N = intents.size();
11744                        for (int i=0; i<N; i++) {
11745                            sb.setLength(0);
11746                            sb.append("    Intent: ");
11747                            intents.get(i).toShortString(sb, false, true, false, false);
11748                            pw.println(sb.toString());
11749                            Bundle bundle = intents.get(i).getExtras();
11750                            if (bundle != null) {
11751                                pw.print("      ");
11752                                pw.println(bundle.toString());
11753                            }
11754                        }
11755                    } else {
11756                        pw.println("");
11757                    }
11758                }
11759            }
11760        }
11761
11762        if (!onlyHistory && dumpAll) {
11763            pw.println();
11764            for (BroadcastQueue queue : mBroadcastQueues) {
11765                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11766                        + queue.mBroadcastsScheduled);
11767            }
11768            pw.println("  mHandler:");
11769            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11770            needSep = true;
11771            printedAnything = true;
11772        }
11773
11774        if (!printedAnything) {
11775            pw.println("  (nothing)");
11776        }
11777    }
11778
11779    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11780            int opti, boolean dumpAll, String dumpPackage) {
11781        boolean needSep;
11782        boolean printedAnything = false;
11783
11784        ItemMatcher matcher = new ItemMatcher();
11785        matcher.build(args, opti);
11786
11787        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11788
11789        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11790        printedAnything |= needSep;
11791
11792        if (mLaunchingProviders.size() > 0) {
11793            boolean printed = false;
11794            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11795                ContentProviderRecord r = mLaunchingProviders.get(i);
11796                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11797                    continue;
11798                }
11799                if (!printed) {
11800                    if (needSep) pw.println();
11801                    needSep = true;
11802                    pw.println("  Launching content providers:");
11803                    printed = true;
11804                    printedAnything = true;
11805                }
11806                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11807                        pw.println(r);
11808            }
11809        }
11810
11811        if (mGrantedUriPermissions.size() > 0) {
11812            boolean printed = false;
11813            int dumpUid = -2;
11814            if (dumpPackage != null) {
11815                try {
11816                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11817                } catch (NameNotFoundException e) {
11818                    dumpUid = -1;
11819                }
11820            }
11821            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11822                int uid = mGrantedUriPermissions.keyAt(i);
11823                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11824                    continue;
11825                }
11826                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11827                if (!printed) {
11828                    if (needSep) pw.println();
11829                    needSep = true;
11830                    pw.println("  Granted Uri Permissions:");
11831                    printed = true;
11832                    printedAnything = true;
11833                }
11834                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11835                for (UriPermission perm : perms.values()) {
11836                    pw.print("    "); pw.println(perm);
11837                    if (dumpAll) {
11838                        perm.dump(pw, "      ");
11839                    }
11840                }
11841            }
11842        }
11843
11844        if (!printedAnything) {
11845            pw.println("  (nothing)");
11846        }
11847    }
11848
11849    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11850            int opti, boolean dumpAll, String dumpPackage) {
11851        boolean printed = false;
11852
11853        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11854
11855        if (mIntentSenderRecords.size() > 0) {
11856            Iterator<WeakReference<PendingIntentRecord>> it
11857                    = mIntentSenderRecords.values().iterator();
11858            while (it.hasNext()) {
11859                WeakReference<PendingIntentRecord> ref = it.next();
11860                PendingIntentRecord rec = ref != null ? ref.get(): null;
11861                if (dumpPackage != null && (rec == null
11862                        || !dumpPackage.equals(rec.key.packageName))) {
11863                    continue;
11864                }
11865                printed = true;
11866                if (rec != null) {
11867                    pw.print("  * "); pw.println(rec);
11868                    if (dumpAll) {
11869                        rec.dump(pw, "    ");
11870                    }
11871                } else {
11872                    pw.print("  * "); pw.println(ref);
11873                }
11874            }
11875        }
11876
11877        if (!printed) {
11878            pw.println("  (nothing)");
11879        }
11880    }
11881
11882    private static final int dumpProcessList(PrintWriter pw,
11883            ActivityManagerService service, List list,
11884            String prefix, String normalLabel, String persistentLabel,
11885            String dumpPackage) {
11886        int numPers = 0;
11887        final int N = list.size()-1;
11888        for (int i=N; i>=0; i--) {
11889            ProcessRecord r = (ProcessRecord)list.get(i);
11890            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11891                continue;
11892            }
11893            pw.println(String.format("%s%s #%2d: %s",
11894                    prefix, (r.persistent ? persistentLabel : normalLabel),
11895                    i, r.toString()));
11896            if (r.persistent) {
11897                numPers++;
11898            }
11899        }
11900        return numPers;
11901    }
11902
11903    private static final boolean dumpProcessOomList(PrintWriter pw,
11904            ActivityManagerService service, List<ProcessRecord> origList,
11905            String prefix, String normalLabel, String persistentLabel,
11906            boolean inclDetails, String dumpPackage) {
11907
11908        ArrayList<Pair<ProcessRecord, Integer>> list
11909                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11910        for (int i=0; i<origList.size(); i++) {
11911            ProcessRecord r = origList.get(i);
11912            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11913                continue;
11914            }
11915            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11916        }
11917
11918        if (list.size() <= 0) {
11919            return false;
11920        }
11921
11922        Comparator<Pair<ProcessRecord, Integer>> comparator
11923                = new Comparator<Pair<ProcessRecord, Integer>>() {
11924            @Override
11925            public int compare(Pair<ProcessRecord, Integer> object1,
11926                    Pair<ProcessRecord, Integer> object2) {
11927                if (object1.first.setAdj != object2.first.setAdj) {
11928                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11929                }
11930                if (object1.second.intValue() != object2.second.intValue()) {
11931                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11932                }
11933                return 0;
11934            }
11935        };
11936
11937        Collections.sort(list, comparator);
11938
11939        final long curRealtime = SystemClock.elapsedRealtime();
11940        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11941        final long curUptime = SystemClock.uptimeMillis();
11942        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11943
11944        for (int i=list.size()-1; i>=0; i--) {
11945            ProcessRecord r = list.get(i).first;
11946            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11947            char schedGroup;
11948            switch (r.setSchedGroup) {
11949                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11950                    schedGroup = 'B';
11951                    break;
11952                case Process.THREAD_GROUP_DEFAULT:
11953                    schedGroup = 'F';
11954                    break;
11955                default:
11956                    schedGroup = '?';
11957                    break;
11958            }
11959            char foreground;
11960            if (r.foregroundActivities) {
11961                foreground = 'A';
11962            } else if (r.foregroundServices) {
11963                foreground = 'S';
11964            } else {
11965                foreground = ' ';
11966            }
11967            String procState = ProcessList.makeProcStateString(r.curProcState);
11968            pw.print(prefix);
11969            pw.print(r.persistent ? persistentLabel : normalLabel);
11970            pw.print(" #");
11971            int num = (origList.size()-1)-list.get(i).second;
11972            if (num < 10) pw.print(' ');
11973            pw.print(num);
11974            pw.print(": ");
11975            pw.print(oomAdj);
11976            pw.print(' ');
11977            pw.print(schedGroup);
11978            pw.print('/');
11979            pw.print(foreground);
11980            pw.print('/');
11981            pw.print(procState);
11982            pw.print(" trm:");
11983            if (r.trimMemoryLevel < 10) pw.print(' ');
11984            pw.print(r.trimMemoryLevel);
11985            pw.print(' ');
11986            pw.print(r.toShortString());
11987            pw.print(" (");
11988            pw.print(r.adjType);
11989            pw.println(')');
11990            if (r.adjSource != null || r.adjTarget != null) {
11991                pw.print(prefix);
11992                pw.print("    ");
11993                if (r.adjTarget instanceof ComponentName) {
11994                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11995                } else if (r.adjTarget != null) {
11996                    pw.print(r.adjTarget.toString());
11997                } else {
11998                    pw.print("{null}");
11999                }
12000                pw.print("<=");
12001                if (r.adjSource instanceof ProcessRecord) {
12002                    pw.print("Proc{");
12003                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12004                    pw.println("}");
12005                } else if (r.adjSource != null) {
12006                    pw.println(r.adjSource.toString());
12007                } else {
12008                    pw.println("{null}");
12009                }
12010            }
12011            if (inclDetails) {
12012                pw.print(prefix);
12013                pw.print("    ");
12014                pw.print("oom: max="); pw.print(r.maxAdj);
12015                pw.print(" curRaw="); pw.print(r.curRawAdj);
12016                pw.print(" setRaw="); pw.print(r.setRawAdj);
12017                pw.print(" cur="); pw.print(r.curAdj);
12018                pw.print(" set="); pw.println(r.setAdj);
12019                pw.print(prefix);
12020                pw.print("    ");
12021                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12022                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12023                pw.print(" lastPss="); pw.print(r.lastPss);
12024                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12025                pw.print(prefix);
12026                pw.print("    ");
12027                pw.print("keeping="); pw.print(r.keeping);
12028                pw.print(" cached="); pw.print(r.cached);
12029                pw.print(" empty="); pw.print(r.empty);
12030                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12031
12032                if (!r.keeping) {
12033                    if (r.lastWakeTime != 0) {
12034                        long wtime;
12035                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12036                        synchronized (stats) {
12037                            wtime = stats.getProcessWakeTime(r.info.uid,
12038                                    r.pid, curRealtime);
12039                        }
12040                        long timeUsed = wtime - r.lastWakeTime;
12041                        pw.print(prefix);
12042                        pw.print("    ");
12043                        pw.print("keep awake over ");
12044                        TimeUtils.formatDuration(realtimeSince, pw);
12045                        pw.print(" used ");
12046                        TimeUtils.formatDuration(timeUsed, pw);
12047                        pw.print(" (");
12048                        pw.print((timeUsed*100)/realtimeSince);
12049                        pw.println("%)");
12050                    }
12051                    if (r.lastCpuTime != 0) {
12052                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12053                        pw.print(prefix);
12054                        pw.print("    ");
12055                        pw.print("run cpu over ");
12056                        TimeUtils.formatDuration(uptimeSince, pw);
12057                        pw.print(" used ");
12058                        TimeUtils.formatDuration(timeUsed, pw);
12059                        pw.print(" (");
12060                        pw.print((timeUsed*100)/uptimeSince);
12061                        pw.println("%)");
12062                    }
12063                }
12064            }
12065        }
12066        return true;
12067    }
12068
12069    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12070        ArrayList<ProcessRecord> procs;
12071        synchronized (this) {
12072            if (args != null && args.length > start
12073                    && args[start].charAt(0) != '-') {
12074                procs = new ArrayList<ProcessRecord>();
12075                int pid = -1;
12076                try {
12077                    pid = Integer.parseInt(args[start]);
12078                } catch (NumberFormatException e) {
12079                }
12080                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12081                    ProcessRecord proc = mLruProcesses.get(i);
12082                    if (proc.pid == pid) {
12083                        procs.add(proc);
12084                    } else if (proc.processName.equals(args[start])) {
12085                        procs.add(proc);
12086                    }
12087                }
12088                if (procs.size() <= 0) {
12089                    return null;
12090                }
12091            } else {
12092                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12093            }
12094        }
12095        return procs;
12096    }
12097
12098    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12099            PrintWriter pw, String[] args) {
12100        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12101        if (procs == null) {
12102            pw.println("No process found for: " + args[0]);
12103            return;
12104        }
12105
12106        long uptime = SystemClock.uptimeMillis();
12107        long realtime = SystemClock.elapsedRealtime();
12108        pw.println("Applications Graphics Acceleration Info:");
12109        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12110
12111        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12112            ProcessRecord r = procs.get(i);
12113            if (r.thread != null) {
12114                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12115                pw.flush();
12116                try {
12117                    TransferPipe tp = new TransferPipe();
12118                    try {
12119                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12120                        tp.go(fd);
12121                    } finally {
12122                        tp.kill();
12123                    }
12124                } catch (IOException e) {
12125                    pw.println("Failure while dumping the app: " + r);
12126                    pw.flush();
12127                } catch (RemoteException e) {
12128                    pw.println("Got a RemoteException while dumping the app " + r);
12129                    pw.flush();
12130                }
12131            }
12132        }
12133    }
12134
12135    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12136        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12137        if (procs == null) {
12138            pw.println("No process found for: " + args[0]);
12139            return;
12140        }
12141
12142        pw.println("Applications Database Info:");
12143
12144        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12145            ProcessRecord r = procs.get(i);
12146            if (r.thread != null) {
12147                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12148                pw.flush();
12149                try {
12150                    TransferPipe tp = new TransferPipe();
12151                    try {
12152                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12153                        tp.go(fd);
12154                    } finally {
12155                        tp.kill();
12156                    }
12157                } catch (IOException e) {
12158                    pw.println("Failure while dumping the app: " + r);
12159                    pw.flush();
12160                } catch (RemoteException e) {
12161                    pw.println("Got a RemoteException while dumping the app " + r);
12162                    pw.flush();
12163                }
12164            }
12165        }
12166    }
12167
12168    final static class MemItem {
12169        final boolean isProc;
12170        final String label;
12171        final String shortLabel;
12172        final long pss;
12173        final int id;
12174        final boolean hasActivities;
12175        ArrayList<MemItem> subitems;
12176
12177        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12178                boolean _hasActivities) {
12179            isProc = true;
12180            label = _label;
12181            shortLabel = _shortLabel;
12182            pss = _pss;
12183            id = _id;
12184            hasActivities = _hasActivities;
12185        }
12186
12187        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12188            isProc = false;
12189            label = _label;
12190            shortLabel = _shortLabel;
12191            pss = _pss;
12192            id = _id;
12193            hasActivities = false;
12194        }
12195    }
12196
12197    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12198            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12199        if (sort && !isCompact) {
12200            Collections.sort(items, new Comparator<MemItem>() {
12201                @Override
12202                public int compare(MemItem lhs, MemItem rhs) {
12203                    if (lhs.pss < rhs.pss) {
12204                        return 1;
12205                    } else if (lhs.pss > rhs.pss) {
12206                        return -1;
12207                    }
12208                    return 0;
12209                }
12210            });
12211        }
12212
12213        for (int i=0; i<items.size(); i++) {
12214            MemItem mi = items.get(i);
12215            if (!isCompact) {
12216                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12217            } else if (mi.isProc) {
12218                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12219                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12220                pw.println(mi.hasActivities ? ",a" : ",e");
12221            } else {
12222                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12223                pw.println(mi.pss);
12224            }
12225            if (mi.subitems != null) {
12226                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12227                        true, isCompact);
12228            }
12229        }
12230    }
12231
12232    // These are in KB.
12233    static final long[] DUMP_MEM_BUCKETS = new long[] {
12234        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12235        120*1024, 160*1024, 200*1024,
12236        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12237        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12238    };
12239
12240    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12241            boolean stackLike) {
12242        int start = label.lastIndexOf('.');
12243        if (start >= 0) start++;
12244        else start = 0;
12245        int end = label.length();
12246        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12247            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12248                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12249                out.append(bucket);
12250                out.append(stackLike ? "MB." : "MB ");
12251                out.append(label, start, end);
12252                return;
12253            }
12254        }
12255        out.append(memKB/1024);
12256        out.append(stackLike ? "MB." : "MB ");
12257        out.append(label, start, end);
12258    }
12259
12260    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12261            ProcessList.NATIVE_ADJ,
12262            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12263            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12264            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12265            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12266            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12267    };
12268    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12269            "Native",
12270            "System", "Persistent", "Foreground",
12271            "Visible", "Perceptible",
12272            "Heavy Weight", "Backup",
12273            "A Services", "Home",
12274            "Previous", "B Services", "Cached"
12275    };
12276    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12277            "native",
12278            "sys", "pers", "fore",
12279            "vis", "percept",
12280            "heavy", "backup",
12281            "servicea", "home",
12282            "prev", "serviceb", "cached"
12283    };
12284
12285    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12286            long realtime, boolean isCheckinRequest, boolean isCompact) {
12287        if (isCheckinRequest || isCompact) {
12288            // short checkin version
12289            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12290        } else {
12291            pw.println("Applications Memory Usage (kB):");
12292            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12293        }
12294    }
12295
12296    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12297            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12298        boolean dumpDetails = false;
12299        boolean dumpFullDetails = false;
12300        boolean dumpDalvik = false;
12301        boolean oomOnly = false;
12302        boolean isCompact = false;
12303        boolean localOnly = false;
12304
12305        int opti = 0;
12306        while (opti < args.length) {
12307            String opt = args[opti];
12308            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12309                break;
12310            }
12311            opti++;
12312            if ("-a".equals(opt)) {
12313                dumpDetails = true;
12314                dumpFullDetails = true;
12315                dumpDalvik = true;
12316            } else if ("-d".equals(opt)) {
12317                dumpDalvik = true;
12318            } else if ("-c".equals(opt)) {
12319                isCompact = true;
12320            } else if ("--oom".equals(opt)) {
12321                oomOnly = true;
12322            } else if ("--local".equals(opt)) {
12323                localOnly = true;
12324            } else if ("-h".equals(opt)) {
12325                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12326                pw.println("  -a: include all available information for each process.");
12327                pw.println("  -d: include dalvik details when dumping process details.");
12328                pw.println("  -c: dump in a compact machine-parseable representation.");
12329                pw.println("  --oom: only show processes organized by oom adj.");
12330                pw.println("  --local: only collect details locally, don't call process.");
12331                pw.println("If [process] is specified it can be the name or ");
12332                pw.println("pid of a specific process to dump.");
12333                return;
12334            } else {
12335                pw.println("Unknown argument: " + opt + "; use -h for help");
12336            }
12337        }
12338
12339        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12340        long uptime = SystemClock.uptimeMillis();
12341        long realtime = SystemClock.elapsedRealtime();
12342        final long[] tmpLong = new long[1];
12343
12344        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12345        if (procs == null) {
12346            // No Java processes.  Maybe they want to print a native process.
12347            if (args != null && args.length > opti
12348                    && args[opti].charAt(0) != '-') {
12349                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12350                        = new ArrayList<ProcessCpuTracker.Stats>();
12351                updateCpuStatsNow();
12352                int findPid = -1;
12353                try {
12354                    findPid = Integer.parseInt(args[opti]);
12355                } catch (NumberFormatException e) {
12356                }
12357                synchronized (mProcessCpuThread) {
12358                    final int N = mProcessCpuTracker.countStats();
12359                    for (int i=0; i<N; i++) {
12360                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12361                        if (st.pid == findPid || (st.baseName != null
12362                                && st.baseName.equals(args[opti]))) {
12363                            nativeProcs.add(st);
12364                        }
12365                    }
12366                }
12367                if (nativeProcs.size() > 0) {
12368                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12369                            isCompact);
12370                    Debug.MemoryInfo mi = null;
12371                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12372                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12373                        final int pid = r.pid;
12374                        if (!isCheckinRequest && dumpDetails) {
12375                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12376                        }
12377                        if (mi == null) {
12378                            mi = new Debug.MemoryInfo();
12379                        }
12380                        if (dumpDetails || (!brief && !oomOnly)) {
12381                            Debug.getMemoryInfo(pid, mi);
12382                        } else {
12383                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12384                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12385                        }
12386                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12387                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12388                        if (isCheckinRequest) {
12389                            pw.println();
12390                        }
12391                    }
12392                    return;
12393                }
12394            }
12395            pw.println("No process found for: " + args[opti]);
12396            return;
12397        }
12398
12399        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12400            dumpDetails = true;
12401        }
12402
12403        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12404
12405        String[] innerArgs = new String[args.length-opti];
12406        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12407
12408        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12409        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12410        long nativePss=0, dalvikPss=0, otherPss=0;
12411        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12412
12413        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12414        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12415                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12416
12417        long totalPss = 0;
12418        long cachedPss = 0;
12419
12420        Debug.MemoryInfo mi = null;
12421        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12422            final ProcessRecord r = procs.get(i);
12423            final IApplicationThread thread;
12424            final int pid;
12425            final int oomAdj;
12426            final boolean hasActivities;
12427            synchronized (this) {
12428                thread = r.thread;
12429                pid = r.pid;
12430                oomAdj = r.getSetAdjWithServices();
12431                hasActivities = r.activities.size() > 0;
12432            }
12433            if (thread != null) {
12434                if (!isCheckinRequest && dumpDetails) {
12435                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12436                }
12437                if (mi == null) {
12438                    mi = new Debug.MemoryInfo();
12439                }
12440                if (dumpDetails || (!brief && !oomOnly)) {
12441                    Debug.getMemoryInfo(pid, mi);
12442                } else {
12443                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12444                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12445                }
12446                if (dumpDetails) {
12447                    if (localOnly) {
12448                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12449                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12450                        if (isCheckinRequest) {
12451                            pw.println();
12452                        }
12453                    } else {
12454                        try {
12455                            pw.flush();
12456                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12457                                    dumpDalvik, innerArgs);
12458                        } catch (RemoteException e) {
12459                            if (!isCheckinRequest) {
12460                                pw.println("Got RemoteException!");
12461                                pw.flush();
12462                            }
12463                        }
12464                    }
12465                }
12466
12467                final long myTotalPss = mi.getTotalPss();
12468                final long myTotalUss = mi.getTotalUss();
12469
12470                synchronized (this) {
12471                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12472                        // Record this for posterity if the process has been stable.
12473                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12474                    }
12475                }
12476
12477                if (!isCheckinRequest && mi != null) {
12478                    totalPss += myTotalPss;
12479                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12480                            (hasActivities ? " / activities)" : ")"),
12481                            r.processName, myTotalPss, pid, hasActivities);
12482                    procMems.add(pssItem);
12483                    procMemsMap.put(pid, pssItem);
12484
12485                    nativePss += mi.nativePss;
12486                    dalvikPss += mi.dalvikPss;
12487                    otherPss += mi.otherPss;
12488                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12489                        long mem = mi.getOtherPss(j);
12490                        miscPss[j] += mem;
12491                        otherPss -= mem;
12492                    }
12493
12494                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12495                        cachedPss += myTotalPss;
12496                    }
12497
12498                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12499                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12500                                || oomIndex == (oomPss.length-1)) {
12501                            oomPss[oomIndex] += myTotalPss;
12502                            if (oomProcs[oomIndex] == null) {
12503                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12504                            }
12505                            oomProcs[oomIndex].add(pssItem);
12506                            break;
12507                        }
12508                    }
12509                }
12510            }
12511        }
12512
12513        if (!isCheckinRequest && procs.size() > 1) {
12514            // If we are showing aggregations, also look for native processes to
12515            // include so that our aggregations are more accurate.
12516            updateCpuStatsNow();
12517            synchronized (mProcessCpuThread) {
12518                final int N = mProcessCpuTracker.countStats();
12519                for (int i=0; i<N; i++) {
12520                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12521                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12522                        if (mi == null) {
12523                            mi = new Debug.MemoryInfo();
12524                        }
12525                        if (!brief && !oomOnly) {
12526                            Debug.getMemoryInfo(st.pid, mi);
12527                        } else {
12528                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12529                            mi.nativePrivateDirty = (int)tmpLong[0];
12530                        }
12531
12532                        final long myTotalPss = mi.getTotalPss();
12533                        totalPss += myTotalPss;
12534
12535                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12536                                st.name, myTotalPss, st.pid, false);
12537                        procMems.add(pssItem);
12538
12539                        nativePss += mi.nativePss;
12540                        dalvikPss += mi.dalvikPss;
12541                        otherPss += mi.otherPss;
12542                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12543                            long mem = mi.getOtherPss(j);
12544                            miscPss[j] += mem;
12545                            otherPss -= mem;
12546                        }
12547                        oomPss[0] += myTotalPss;
12548                        if (oomProcs[0] == null) {
12549                            oomProcs[0] = new ArrayList<MemItem>();
12550                        }
12551                        oomProcs[0].add(pssItem);
12552                    }
12553                }
12554            }
12555
12556            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12557
12558            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12559            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12560            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12561            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12562                String label = Debug.MemoryInfo.getOtherLabel(j);
12563                catMems.add(new MemItem(label, label, miscPss[j], j));
12564            }
12565
12566            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12567            for (int j=0; j<oomPss.length; j++) {
12568                if (oomPss[j] != 0) {
12569                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12570                            : DUMP_MEM_OOM_LABEL[j];
12571                    MemItem item = new MemItem(label, label, oomPss[j],
12572                            DUMP_MEM_OOM_ADJ[j]);
12573                    item.subitems = oomProcs[j];
12574                    oomMems.add(item);
12575                }
12576            }
12577
12578            if (!brief && !oomOnly && !isCompact) {
12579                pw.println();
12580                pw.println("Total PSS by process:");
12581                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12582                pw.println();
12583            }
12584            if (!isCompact) {
12585                pw.println("Total PSS by OOM adjustment:");
12586            }
12587            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12588            if (!brief && !oomOnly) {
12589                PrintWriter out = categoryPw != null ? categoryPw : pw;
12590                if (!isCompact) {
12591                    out.println();
12592                    out.println("Total PSS by category:");
12593                }
12594                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12595            }
12596            if (!isCompact) {
12597                pw.println();
12598            }
12599            MemInfoReader memInfo = new MemInfoReader();
12600            memInfo.readMemInfo();
12601            if (!brief) {
12602                if (!isCompact) {
12603                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12604                    pw.print(" kB (status ");
12605                    switch (mLastMemoryLevel) {
12606                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12607                            pw.println("normal)");
12608                            break;
12609                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12610                            pw.println("moderate)");
12611                            break;
12612                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12613                            pw.println("low)");
12614                            break;
12615                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12616                            pw.println("critical)");
12617                            break;
12618                        default:
12619                            pw.print(mLastMemoryLevel);
12620                            pw.println(")");
12621                            break;
12622                    }
12623                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12624                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12625                            pw.print(cachedPss); pw.print(" cached pss + ");
12626                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12627                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12628                } else {
12629                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12630                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12631                            + memInfo.getFreeSizeKb()); pw.print(",");
12632                    pw.println(totalPss - cachedPss);
12633                }
12634            }
12635            if (!isCompact) {
12636                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12637                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12638                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12639                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12640                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12641                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12642                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12643                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12644                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12645                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12646                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12647            }
12648            if (!brief) {
12649                if (memInfo.getZramTotalSizeKb() != 0) {
12650                    if (!isCompact) {
12651                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12652                                pw.print(" kB physical used for ");
12653                                pw.print(memInfo.getSwapTotalSizeKb()
12654                                        - memInfo.getSwapFreeSizeKb());
12655                                pw.print(" kB in swap (");
12656                                pw.print(memInfo.getSwapTotalSizeKb());
12657                                pw.println(" kB total swap)");
12658                    } else {
12659                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12660                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12661                                pw.println(memInfo.getSwapFreeSizeKb());
12662                    }
12663                }
12664                final int[] SINGLE_LONG_FORMAT = new int[] {
12665                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12666                };
12667                long[] longOut = new long[1];
12668                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12669                        SINGLE_LONG_FORMAT, null, longOut, null);
12670                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12671                longOut[0] = 0;
12672                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12673                        SINGLE_LONG_FORMAT, null, longOut, null);
12674                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12675                longOut[0] = 0;
12676                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12677                        SINGLE_LONG_FORMAT, null, longOut, null);
12678                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12679                longOut[0] = 0;
12680                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12681                        SINGLE_LONG_FORMAT, null, longOut, null);
12682                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12683                if (!isCompact) {
12684                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12685                        pw.print("      KSM: "); pw.print(sharing);
12686                                pw.print(" kB saved from shared ");
12687                                pw.print(shared); pw.println(" kB");
12688                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12689                                pw.print(voltile); pw.println(" kB volatile");
12690                    }
12691                    pw.print("   Tuning: ");
12692                    pw.print(ActivityManager.staticGetMemoryClass());
12693                    pw.print(" (large ");
12694                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12695                    pw.print("), oom ");
12696                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12697                    pw.print(" kB");
12698                    pw.print(", restore limit ");
12699                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12700                    pw.print(" kB");
12701                    if (ActivityManager.isLowRamDeviceStatic()) {
12702                        pw.print(" (low-ram)");
12703                    }
12704                    if (ActivityManager.isHighEndGfx()) {
12705                        pw.print(" (high-end-gfx)");
12706                    }
12707                    pw.println();
12708                } else {
12709                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12710                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12711                    pw.println(voltile);
12712                    pw.print("tuning,");
12713                    pw.print(ActivityManager.staticGetMemoryClass());
12714                    pw.print(',');
12715                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12716                    pw.print(',');
12717                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12718                    if (ActivityManager.isLowRamDeviceStatic()) {
12719                        pw.print(",low-ram");
12720                    }
12721                    if (ActivityManager.isHighEndGfx()) {
12722                        pw.print(",high-end-gfx");
12723                    }
12724                    pw.println();
12725                }
12726            }
12727        }
12728    }
12729
12730    /**
12731     * Searches array of arguments for the specified string
12732     * @param args array of argument strings
12733     * @param value value to search for
12734     * @return true if the value is contained in the array
12735     */
12736    private static boolean scanArgs(String[] args, String value) {
12737        if (args != null) {
12738            for (String arg : args) {
12739                if (value.equals(arg)) {
12740                    return true;
12741                }
12742            }
12743        }
12744        return false;
12745    }
12746
12747    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12748            ContentProviderRecord cpr, boolean always) {
12749        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12750
12751        if (!inLaunching || always) {
12752            synchronized (cpr) {
12753                cpr.launchingApp = null;
12754                cpr.notifyAll();
12755            }
12756            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12757            String names[] = cpr.info.authority.split(";");
12758            for (int j = 0; j < names.length; j++) {
12759                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12760            }
12761        }
12762
12763        for (int i=0; i<cpr.connections.size(); i++) {
12764            ContentProviderConnection conn = cpr.connections.get(i);
12765            if (conn.waiting) {
12766                // If this connection is waiting for the provider, then we don't
12767                // need to mess with its process unless we are always removing
12768                // or for some reason the provider is not currently launching.
12769                if (inLaunching && !always) {
12770                    continue;
12771                }
12772            }
12773            ProcessRecord capp = conn.client;
12774            conn.dead = true;
12775            if (conn.stableCount > 0) {
12776                if (!capp.persistent && capp.thread != null
12777                        && capp.pid != 0
12778                        && capp.pid != MY_PID) {
12779                    killUnneededProcessLocked(capp, "depends on provider "
12780                            + cpr.name.flattenToShortString()
12781                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12782                }
12783            } else if (capp.thread != null && conn.provider.provider != null) {
12784                try {
12785                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12786                } catch (RemoteException e) {
12787                }
12788                // In the protocol here, we don't expect the client to correctly
12789                // clean up this connection, we'll just remove it.
12790                cpr.connections.remove(i);
12791                conn.client.conProviders.remove(conn);
12792            }
12793        }
12794
12795        if (inLaunching && always) {
12796            mLaunchingProviders.remove(cpr);
12797        }
12798        return inLaunching;
12799    }
12800
12801    /**
12802     * Main code for cleaning up a process when it has gone away.  This is
12803     * called both as a result of the process dying, or directly when stopping
12804     * a process when running in single process mode.
12805     */
12806    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12807            boolean restarting, boolean allowRestart, int index) {
12808        if (index >= 0) {
12809            removeLruProcessLocked(app);
12810            ProcessList.remove(app.pid);
12811        }
12812
12813        mProcessesToGc.remove(app);
12814        mPendingPssProcesses.remove(app);
12815
12816        // Dismiss any open dialogs.
12817        if (app.crashDialog != null && !app.forceCrashReport) {
12818            app.crashDialog.dismiss();
12819            app.crashDialog = null;
12820        }
12821        if (app.anrDialog != null) {
12822            app.anrDialog.dismiss();
12823            app.anrDialog = null;
12824        }
12825        if (app.waitDialog != null) {
12826            app.waitDialog.dismiss();
12827            app.waitDialog = null;
12828        }
12829
12830        app.crashing = false;
12831        app.notResponding = false;
12832
12833        app.resetPackageList(mProcessStats);
12834        app.unlinkDeathRecipient();
12835        app.makeInactive(mProcessStats);
12836        app.forcingToForeground = null;
12837        updateProcessForegroundLocked(app, false, false);
12838        app.foregroundActivities = false;
12839        app.hasShownUi = false;
12840        app.treatLikeActivity = false;
12841        app.hasAboveClient = false;
12842        app.hasClientActivities = false;
12843
12844        mServices.killServicesLocked(app, allowRestart);
12845
12846        boolean restart = false;
12847
12848        // Remove published content providers.
12849        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12850            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12851            final boolean always = app.bad || !allowRestart;
12852            if (removeDyingProviderLocked(app, cpr, always) || always) {
12853                // We left the provider in the launching list, need to
12854                // restart it.
12855                restart = true;
12856            }
12857
12858            cpr.provider = null;
12859            cpr.proc = null;
12860        }
12861        app.pubProviders.clear();
12862
12863        // Take care of any launching providers waiting for this process.
12864        if (checkAppInLaunchingProvidersLocked(app, false)) {
12865            restart = true;
12866        }
12867
12868        // Unregister from connected content providers.
12869        if (!app.conProviders.isEmpty()) {
12870            for (int i=0; i<app.conProviders.size(); i++) {
12871                ContentProviderConnection conn = app.conProviders.get(i);
12872                conn.provider.connections.remove(conn);
12873            }
12874            app.conProviders.clear();
12875        }
12876
12877        // At this point there may be remaining entries in mLaunchingProviders
12878        // where we were the only one waiting, so they are no longer of use.
12879        // Look for these and clean up if found.
12880        // XXX Commented out for now.  Trying to figure out a way to reproduce
12881        // the actual situation to identify what is actually going on.
12882        if (false) {
12883            for (int i=0; i<mLaunchingProviders.size(); i++) {
12884                ContentProviderRecord cpr = (ContentProviderRecord)
12885                        mLaunchingProviders.get(i);
12886                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12887                    synchronized (cpr) {
12888                        cpr.launchingApp = null;
12889                        cpr.notifyAll();
12890                    }
12891                }
12892            }
12893        }
12894
12895        skipCurrentReceiverLocked(app);
12896
12897        // Unregister any receivers.
12898        for (int i=app.receivers.size()-1; i>=0; i--) {
12899            removeReceiverLocked(app.receivers.valueAt(i));
12900        }
12901        app.receivers.clear();
12902
12903        // If the app is undergoing backup, tell the backup manager about it
12904        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12905            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12906                    + mBackupTarget.appInfo + " died during backup");
12907            try {
12908                IBackupManager bm = IBackupManager.Stub.asInterface(
12909                        ServiceManager.getService(Context.BACKUP_SERVICE));
12910                bm.agentDisconnected(app.info.packageName);
12911            } catch (RemoteException e) {
12912                // can't happen; backup manager is local
12913            }
12914        }
12915
12916        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12917            ProcessChangeItem item = mPendingProcessChanges.get(i);
12918            if (item.pid == app.pid) {
12919                mPendingProcessChanges.remove(i);
12920                mAvailProcessChanges.add(item);
12921            }
12922        }
12923        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12924
12925        // If the caller is restarting this app, then leave it in its
12926        // current lists and let the caller take care of it.
12927        if (restarting) {
12928            return;
12929        }
12930
12931        if (!app.persistent || app.isolated) {
12932            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12933                    "Removing non-persistent process during cleanup: " + app);
12934            mProcessNames.remove(app.processName, app.uid);
12935            mIsolatedProcesses.remove(app.uid);
12936            if (mHeavyWeightProcess == app) {
12937                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12938                        mHeavyWeightProcess.userId, 0));
12939                mHeavyWeightProcess = null;
12940            }
12941        } else if (!app.removed) {
12942            // This app is persistent, so we need to keep its record around.
12943            // If it is not already on the pending app list, add it there
12944            // and start a new process for it.
12945            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12946                mPersistentStartingProcesses.add(app);
12947                restart = true;
12948            }
12949        }
12950        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12951                "Clean-up removing on hold: " + app);
12952        mProcessesOnHold.remove(app);
12953
12954        if (app == mHomeProcess) {
12955            mHomeProcess = null;
12956        }
12957        if (app == mPreviousProcess) {
12958            mPreviousProcess = null;
12959        }
12960
12961        if (restart && !app.isolated) {
12962            // We have components that still need to be running in the
12963            // process, so re-launch it.
12964            mProcessNames.put(app.processName, app.uid, app);
12965            startProcessLocked(app, "restart", app.processName);
12966        } else if (app.pid > 0 && app.pid != MY_PID) {
12967            // Goodbye!
12968            boolean removed;
12969            synchronized (mPidsSelfLocked) {
12970                mPidsSelfLocked.remove(app.pid);
12971                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12972            }
12973            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12974                    app.processName, app.info.uid);
12975            if (app.isolated) {
12976                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12977            }
12978            app.setPid(0);
12979        }
12980    }
12981
12982    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12983        // Look through the content providers we are waiting to have launched,
12984        // and if any run in this process then either schedule a restart of
12985        // the process or kill the client waiting for it if this process has
12986        // gone bad.
12987        int NL = mLaunchingProviders.size();
12988        boolean restart = false;
12989        for (int i=0; i<NL; i++) {
12990            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12991            if (cpr.launchingApp == app) {
12992                if (!alwaysBad && !app.bad) {
12993                    restart = true;
12994                } else {
12995                    removeDyingProviderLocked(app, cpr, true);
12996                    // cpr should have been removed from mLaunchingProviders
12997                    NL = mLaunchingProviders.size();
12998                    i--;
12999                }
13000            }
13001        }
13002        return restart;
13003    }
13004
13005    // =========================================================
13006    // SERVICES
13007    // =========================================================
13008
13009    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13010            int flags) {
13011        enforceNotIsolatedCaller("getServices");
13012        synchronized (this) {
13013            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13014        }
13015    }
13016
13017    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13018        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13019        synchronized (this) {
13020            return mServices.getRunningServiceControlPanelLocked(name);
13021        }
13022    }
13023
13024    public ComponentName startService(IApplicationThread caller, Intent service,
13025            String resolvedType, int userId) {
13026        enforceNotIsolatedCaller("startService");
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        if (DEBUG_SERVICE)
13033            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13034        synchronized(this) {
13035            final int callingPid = Binder.getCallingPid();
13036            final int callingUid = Binder.getCallingUid();
13037            final long origId = Binder.clearCallingIdentity();
13038            ComponentName res = mServices.startServiceLocked(caller, service,
13039                    resolvedType, callingPid, callingUid, userId);
13040            Binder.restoreCallingIdentity(origId);
13041            return res;
13042        }
13043    }
13044
13045    ComponentName startServiceInPackage(int uid,
13046            Intent service, String resolvedType, int userId) {
13047        synchronized(this) {
13048            if (DEBUG_SERVICE)
13049                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13050            final long origId = Binder.clearCallingIdentity();
13051            ComponentName res = mServices.startServiceLocked(null, service,
13052                    resolvedType, -1, uid, userId);
13053            Binder.restoreCallingIdentity(origId);
13054            return res;
13055        }
13056    }
13057
13058    public int stopService(IApplicationThread caller, Intent service,
13059            String resolvedType, int userId) {
13060        enforceNotIsolatedCaller("stopService");
13061        // Refuse possible leaked file descriptors
13062        if (service != null && service.hasFileDescriptors() == true) {
13063            throw new IllegalArgumentException("File descriptors passed in Intent");
13064        }
13065
13066        synchronized(this) {
13067            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13068        }
13069    }
13070
13071    public IBinder peekService(Intent service, String resolvedType) {
13072        enforceNotIsolatedCaller("peekService");
13073        // Refuse possible leaked file descriptors
13074        if (service != null && service.hasFileDescriptors() == true) {
13075            throw new IllegalArgumentException("File descriptors passed in Intent");
13076        }
13077        synchronized(this) {
13078            return mServices.peekServiceLocked(service, resolvedType);
13079        }
13080    }
13081
13082    public boolean stopServiceToken(ComponentName className, IBinder token,
13083            int startId) {
13084        synchronized(this) {
13085            return mServices.stopServiceTokenLocked(className, token, startId);
13086        }
13087    }
13088
13089    public void setServiceForeground(ComponentName className, IBinder token,
13090            int id, Notification notification, boolean removeNotification) {
13091        synchronized(this) {
13092            mServices.setServiceForegroundLocked(className, token, id, notification,
13093                    removeNotification);
13094        }
13095    }
13096
13097    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13098            boolean requireFull, String name, String callerPackage) {
13099        final int callingUserId = UserHandle.getUserId(callingUid);
13100        if (callingUserId != userId) {
13101            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13102                if ((requireFull || checkComponentPermission(
13103                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13104                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13105                        && checkComponentPermission(
13106                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13107                                callingPid, callingUid, -1, true)
13108                                != PackageManager.PERMISSION_GRANTED) {
13109                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13110                        // In this case, they would like to just execute as their
13111                        // owner user instead of failing.
13112                        userId = callingUserId;
13113                    } else {
13114                        StringBuilder builder = new StringBuilder(128);
13115                        builder.append("Permission Denial: ");
13116                        builder.append(name);
13117                        if (callerPackage != null) {
13118                            builder.append(" from ");
13119                            builder.append(callerPackage);
13120                        }
13121                        builder.append(" asks to run as user ");
13122                        builder.append(userId);
13123                        builder.append(" but is calling from user ");
13124                        builder.append(UserHandle.getUserId(callingUid));
13125                        builder.append("; this requires ");
13126                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13127                        if (!requireFull) {
13128                            builder.append(" or ");
13129                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13130                        }
13131                        String msg = builder.toString();
13132                        Slog.w(TAG, msg);
13133                        throw new SecurityException(msg);
13134                    }
13135                }
13136            }
13137            if (userId == UserHandle.USER_CURRENT
13138                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13139                // Note that we may be accessing this outside of a lock...
13140                // shouldn't be a big deal, if this is being called outside
13141                // of a locked context there is intrinsically a race with
13142                // the value the caller will receive and someone else changing it.
13143                userId = mCurrentUserId;
13144            }
13145            if (!allowAll && userId < 0) {
13146                throw new IllegalArgumentException(
13147                        "Call does not support special user #" + userId);
13148            }
13149        }
13150        return userId;
13151    }
13152
13153    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13154            String className, int flags) {
13155        boolean result = false;
13156        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13157            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13158                if (ActivityManager.checkUidPermission(
13159                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13160                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13161                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13162                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13163                            + " requests FLAG_SINGLE_USER, but app does not hold "
13164                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13165                    Slog.w(TAG, msg);
13166                    throw new SecurityException(msg);
13167                }
13168                result = true;
13169            }
13170        } else if (componentProcessName == aInfo.packageName) {
13171            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13172        } else if ("system".equals(componentProcessName)) {
13173            result = true;
13174        }
13175        if (DEBUG_MU) {
13176            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13177                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13178        }
13179        return result;
13180    }
13181
13182    public int bindService(IApplicationThread caller, IBinder token,
13183            Intent service, String resolvedType,
13184            IServiceConnection connection, int flags, int userId) {
13185        enforceNotIsolatedCaller("bindService");
13186        // Refuse possible leaked file descriptors
13187        if (service != null && service.hasFileDescriptors() == true) {
13188            throw new IllegalArgumentException("File descriptors passed in Intent");
13189        }
13190
13191        synchronized(this) {
13192            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13193                    connection, flags, userId);
13194        }
13195    }
13196
13197    public boolean unbindService(IServiceConnection connection) {
13198        synchronized (this) {
13199            return mServices.unbindServiceLocked(connection);
13200        }
13201    }
13202
13203    public void publishService(IBinder token, Intent intent, IBinder service) {
13204        // Refuse possible leaked file descriptors
13205        if (intent != null && intent.hasFileDescriptors() == true) {
13206            throw new IllegalArgumentException("File descriptors passed in Intent");
13207        }
13208
13209        synchronized(this) {
13210            if (!(token instanceof ServiceRecord)) {
13211                throw new IllegalArgumentException("Invalid service token");
13212            }
13213            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13214        }
13215    }
13216
13217    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13218        // Refuse possible leaked file descriptors
13219        if (intent != null && intent.hasFileDescriptors() == true) {
13220            throw new IllegalArgumentException("File descriptors passed in Intent");
13221        }
13222
13223        synchronized(this) {
13224            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13225        }
13226    }
13227
13228    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13229        synchronized(this) {
13230            if (!(token instanceof ServiceRecord)) {
13231                throw new IllegalArgumentException("Invalid service token");
13232            }
13233            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13234        }
13235    }
13236
13237    // =========================================================
13238    // BACKUP AND RESTORE
13239    // =========================================================
13240
13241    // Cause the target app to be launched if necessary and its backup agent
13242    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13243    // activity manager to announce its creation.
13244    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13245        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13246        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13247
13248        synchronized(this) {
13249            // !!! TODO: currently no check here that we're already bound
13250            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13251            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13252            synchronized (stats) {
13253                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13254            }
13255
13256            // Backup agent is now in use, its package can't be stopped.
13257            try {
13258                AppGlobals.getPackageManager().setPackageStoppedState(
13259                        app.packageName, false, UserHandle.getUserId(app.uid));
13260            } catch (RemoteException e) {
13261            } catch (IllegalArgumentException e) {
13262                Slog.w(TAG, "Failed trying to unstop package "
13263                        + app.packageName + ": " + e);
13264            }
13265
13266            BackupRecord r = new BackupRecord(ss, app, backupMode);
13267            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13268                    ? new ComponentName(app.packageName, app.backupAgentName)
13269                    : new ComponentName("android", "FullBackupAgent");
13270            // startProcessLocked() returns existing proc's record if it's already running
13271            ProcessRecord proc = startProcessLocked(app.processName, app,
13272                    false, 0, "backup", hostingName, false, false, false);
13273            if (proc == null) {
13274                Slog.e(TAG, "Unable to start backup agent process " + r);
13275                return false;
13276            }
13277
13278            r.app = proc;
13279            mBackupTarget = r;
13280            mBackupAppName = app.packageName;
13281
13282            // Try not to kill the process during backup
13283            updateOomAdjLocked(proc);
13284
13285            // If the process is already attached, schedule the creation of the backup agent now.
13286            // If it is not yet live, this will be done when it attaches to the framework.
13287            if (proc.thread != null) {
13288                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13289                try {
13290                    proc.thread.scheduleCreateBackupAgent(app,
13291                            compatibilityInfoForPackageLocked(app), backupMode);
13292                } catch (RemoteException e) {
13293                    // Will time out on the backup manager side
13294                }
13295            } else {
13296                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13297            }
13298            // Invariants: at this point, the target app process exists and the application
13299            // is either already running or in the process of coming up.  mBackupTarget and
13300            // mBackupAppName describe the app, so that when it binds back to the AM we
13301            // know that it's scheduled for a backup-agent operation.
13302        }
13303
13304        return true;
13305    }
13306
13307    @Override
13308    public void clearPendingBackup() {
13309        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13310        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13311
13312        synchronized (this) {
13313            mBackupTarget = null;
13314            mBackupAppName = null;
13315        }
13316    }
13317
13318    // A backup agent has just come up
13319    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13320        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13321                + " = " + agent);
13322
13323        synchronized(this) {
13324            if (!agentPackageName.equals(mBackupAppName)) {
13325                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13326                return;
13327            }
13328        }
13329
13330        long oldIdent = Binder.clearCallingIdentity();
13331        try {
13332            IBackupManager bm = IBackupManager.Stub.asInterface(
13333                    ServiceManager.getService(Context.BACKUP_SERVICE));
13334            bm.agentConnected(agentPackageName, agent);
13335        } catch (RemoteException e) {
13336            // can't happen; the backup manager service is local
13337        } catch (Exception e) {
13338            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13339            e.printStackTrace();
13340        } finally {
13341            Binder.restoreCallingIdentity(oldIdent);
13342        }
13343    }
13344
13345    // done with this agent
13346    public void unbindBackupAgent(ApplicationInfo appInfo) {
13347        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13348        if (appInfo == null) {
13349            Slog.w(TAG, "unbind backup agent for null app");
13350            return;
13351        }
13352
13353        synchronized(this) {
13354            try {
13355                if (mBackupAppName == null) {
13356                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13357                    return;
13358                }
13359
13360                if (!mBackupAppName.equals(appInfo.packageName)) {
13361                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13362                    return;
13363                }
13364
13365                // Not backing this app up any more; reset its OOM adjustment
13366                final ProcessRecord proc = mBackupTarget.app;
13367                updateOomAdjLocked(proc);
13368
13369                // If the app crashed during backup, 'thread' will be null here
13370                if (proc.thread != null) {
13371                    try {
13372                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13373                                compatibilityInfoForPackageLocked(appInfo));
13374                    } catch (Exception e) {
13375                        Slog.e(TAG, "Exception when unbinding backup agent:");
13376                        e.printStackTrace();
13377                    }
13378                }
13379            } finally {
13380                mBackupTarget = null;
13381                mBackupAppName = null;
13382            }
13383        }
13384    }
13385    // =========================================================
13386    // BROADCASTS
13387    // =========================================================
13388
13389    private final List getStickiesLocked(String action, IntentFilter filter,
13390            List cur, int userId) {
13391        final ContentResolver resolver = mContext.getContentResolver();
13392        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13393        if (stickies == null) {
13394            return cur;
13395        }
13396        final ArrayList<Intent> list = stickies.get(action);
13397        if (list == null) {
13398            return cur;
13399        }
13400        int N = list.size();
13401        for (int i=0; i<N; i++) {
13402            Intent intent = list.get(i);
13403            if (filter.match(resolver, intent, true, TAG) >= 0) {
13404                if (cur == null) {
13405                    cur = new ArrayList<Intent>();
13406                }
13407                cur.add(intent);
13408            }
13409        }
13410        return cur;
13411    }
13412
13413    boolean isPendingBroadcastProcessLocked(int pid) {
13414        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13415                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13416    }
13417
13418    void skipPendingBroadcastLocked(int pid) {
13419            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13420            for (BroadcastQueue queue : mBroadcastQueues) {
13421                queue.skipPendingBroadcastLocked(pid);
13422            }
13423    }
13424
13425    // The app just attached; send any pending broadcasts that it should receive
13426    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13427        boolean didSomething = false;
13428        for (BroadcastQueue queue : mBroadcastQueues) {
13429            didSomething |= queue.sendPendingBroadcastsLocked(app);
13430        }
13431        return didSomething;
13432    }
13433
13434    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13435            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13436        enforceNotIsolatedCaller("registerReceiver");
13437        int callingUid;
13438        int callingPid;
13439        synchronized(this) {
13440            ProcessRecord callerApp = null;
13441            if (caller != null) {
13442                callerApp = getRecordForAppLocked(caller);
13443                if (callerApp == null) {
13444                    throw new SecurityException(
13445                            "Unable to find app for caller " + caller
13446                            + " (pid=" + Binder.getCallingPid()
13447                            + ") when registering receiver " + receiver);
13448                }
13449                if (callerApp.info.uid != Process.SYSTEM_UID &&
13450                        !callerApp.pkgList.containsKey(callerPackage) &&
13451                        !"android".equals(callerPackage)) {
13452                    throw new SecurityException("Given caller package " + callerPackage
13453                            + " is not running in process " + callerApp);
13454                }
13455                callingUid = callerApp.info.uid;
13456                callingPid = callerApp.pid;
13457            } else {
13458                callerPackage = null;
13459                callingUid = Binder.getCallingUid();
13460                callingPid = Binder.getCallingPid();
13461            }
13462
13463            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13464                    true, true, "registerReceiver", callerPackage);
13465
13466            List allSticky = null;
13467
13468            // Look for any matching sticky broadcasts...
13469            Iterator actions = filter.actionsIterator();
13470            if (actions != null) {
13471                while (actions.hasNext()) {
13472                    String action = (String)actions.next();
13473                    allSticky = getStickiesLocked(action, filter, allSticky,
13474                            UserHandle.USER_ALL);
13475                    allSticky = getStickiesLocked(action, filter, allSticky,
13476                            UserHandle.getUserId(callingUid));
13477                }
13478            } else {
13479                allSticky = getStickiesLocked(null, filter, allSticky,
13480                        UserHandle.USER_ALL);
13481                allSticky = getStickiesLocked(null, filter, allSticky,
13482                        UserHandle.getUserId(callingUid));
13483            }
13484
13485            // The first sticky in the list is returned directly back to
13486            // the client.
13487            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13488
13489            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13490                    + ": " + sticky);
13491
13492            if (receiver == null) {
13493                return sticky;
13494            }
13495
13496            ReceiverList rl
13497                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13498            if (rl == null) {
13499                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13500                        userId, receiver);
13501                if (rl.app != null) {
13502                    rl.app.receivers.add(rl);
13503                } else {
13504                    try {
13505                        receiver.asBinder().linkToDeath(rl, 0);
13506                    } catch (RemoteException e) {
13507                        return sticky;
13508                    }
13509                    rl.linkedToDeath = true;
13510                }
13511                mRegisteredReceivers.put(receiver.asBinder(), rl);
13512            } else if (rl.uid != callingUid) {
13513                throw new IllegalArgumentException(
13514                        "Receiver requested to register for uid " + callingUid
13515                        + " was previously registered for uid " + rl.uid);
13516            } else if (rl.pid != callingPid) {
13517                throw new IllegalArgumentException(
13518                        "Receiver requested to register for pid " + callingPid
13519                        + " was previously registered for pid " + rl.pid);
13520            } else if (rl.userId != userId) {
13521                throw new IllegalArgumentException(
13522                        "Receiver requested to register for user " + userId
13523                        + " was previously registered for user " + rl.userId);
13524            }
13525            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13526                    permission, callingUid, userId);
13527            rl.add(bf);
13528            if (!bf.debugCheck()) {
13529                Slog.w(TAG, "==> For Dynamic broadast");
13530            }
13531            mReceiverResolver.addFilter(bf);
13532
13533            // Enqueue broadcasts for all existing stickies that match
13534            // this filter.
13535            if (allSticky != null) {
13536                ArrayList receivers = new ArrayList();
13537                receivers.add(bf);
13538
13539                int N = allSticky.size();
13540                for (int i=0; i<N; i++) {
13541                    Intent intent = (Intent)allSticky.get(i);
13542                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13543                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13544                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13545                            null, null, false, true, true, -1);
13546                    queue.enqueueParallelBroadcastLocked(r);
13547                    queue.scheduleBroadcastsLocked();
13548                }
13549            }
13550
13551            return sticky;
13552        }
13553    }
13554
13555    public void unregisterReceiver(IIntentReceiver receiver) {
13556        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13557
13558        final long origId = Binder.clearCallingIdentity();
13559        try {
13560            boolean doTrim = false;
13561
13562            synchronized(this) {
13563                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13564                if (rl != null) {
13565                    if (rl.curBroadcast != null) {
13566                        BroadcastRecord r = rl.curBroadcast;
13567                        final boolean doNext = finishReceiverLocked(
13568                                receiver.asBinder(), r.resultCode, r.resultData,
13569                                r.resultExtras, r.resultAbort);
13570                        if (doNext) {
13571                            doTrim = true;
13572                            r.queue.processNextBroadcast(false);
13573                        }
13574                    }
13575
13576                    if (rl.app != null) {
13577                        rl.app.receivers.remove(rl);
13578                    }
13579                    removeReceiverLocked(rl);
13580                    if (rl.linkedToDeath) {
13581                        rl.linkedToDeath = false;
13582                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13583                    }
13584                }
13585            }
13586
13587            // If we actually concluded any broadcasts, we might now be able
13588            // to trim the recipients' apps from our working set
13589            if (doTrim) {
13590                trimApplications();
13591                return;
13592            }
13593
13594        } finally {
13595            Binder.restoreCallingIdentity(origId);
13596        }
13597    }
13598
13599    void removeReceiverLocked(ReceiverList rl) {
13600        mRegisteredReceivers.remove(rl.receiver.asBinder());
13601        int N = rl.size();
13602        for (int i=0; i<N; i++) {
13603            mReceiverResolver.removeFilter(rl.get(i));
13604        }
13605    }
13606
13607    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13608        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13609            ProcessRecord r = mLruProcesses.get(i);
13610            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13611                try {
13612                    r.thread.dispatchPackageBroadcast(cmd, packages);
13613                } catch (RemoteException ex) {
13614                }
13615            }
13616        }
13617    }
13618
13619    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13620            int[] users) {
13621        List<ResolveInfo> receivers = null;
13622        try {
13623            HashSet<ComponentName> singleUserReceivers = null;
13624            boolean scannedFirstReceivers = false;
13625            for (int user : users) {
13626                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13627                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13628                if (user != 0 && newReceivers != null) {
13629                    // If this is not the primary user, we need to check for
13630                    // any receivers that should be filtered out.
13631                    for (int i=0; i<newReceivers.size(); i++) {
13632                        ResolveInfo ri = newReceivers.get(i);
13633                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13634                            newReceivers.remove(i);
13635                            i--;
13636                        }
13637                    }
13638                }
13639                if (newReceivers != null && newReceivers.size() == 0) {
13640                    newReceivers = null;
13641                }
13642                if (receivers == null) {
13643                    receivers = newReceivers;
13644                } else if (newReceivers != null) {
13645                    // We need to concatenate the additional receivers
13646                    // found with what we have do far.  This would be easy,
13647                    // but we also need to de-dup any receivers that are
13648                    // singleUser.
13649                    if (!scannedFirstReceivers) {
13650                        // Collect any single user receivers we had already retrieved.
13651                        scannedFirstReceivers = true;
13652                        for (int i=0; i<receivers.size(); i++) {
13653                            ResolveInfo ri = receivers.get(i);
13654                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13655                                ComponentName cn = new ComponentName(
13656                                        ri.activityInfo.packageName, ri.activityInfo.name);
13657                                if (singleUserReceivers == null) {
13658                                    singleUserReceivers = new HashSet<ComponentName>();
13659                                }
13660                                singleUserReceivers.add(cn);
13661                            }
13662                        }
13663                    }
13664                    // Add the new results to the existing results, tracking
13665                    // and de-dupping single user receivers.
13666                    for (int i=0; i<newReceivers.size(); i++) {
13667                        ResolveInfo ri = newReceivers.get(i);
13668                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13669                            ComponentName cn = new ComponentName(
13670                                    ri.activityInfo.packageName, ri.activityInfo.name);
13671                            if (singleUserReceivers == null) {
13672                                singleUserReceivers = new HashSet<ComponentName>();
13673                            }
13674                            if (!singleUserReceivers.contains(cn)) {
13675                                singleUserReceivers.add(cn);
13676                                receivers.add(ri);
13677                            }
13678                        } else {
13679                            receivers.add(ri);
13680                        }
13681                    }
13682                }
13683            }
13684        } catch (RemoteException ex) {
13685            // pm is in same process, this will never happen.
13686        }
13687        return receivers;
13688    }
13689
13690    private final int broadcastIntentLocked(ProcessRecord callerApp,
13691            String callerPackage, Intent intent, String resolvedType,
13692            IIntentReceiver resultTo, int resultCode, String resultData,
13693            Bundle map, String requiredPermission, int appOp,
13694            boolean ordered, boolean sticky, int callingPid, int callingUid,
13695            int userId) {
13696        intent = new Intent(intent);
13697
13698        // By default broadcasts do not go to stopped apps.
13699        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13700
13701        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13702            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13703            + " ordered=" + ordered + " userid=" + userId);
13704        if ((resultTo != null) && !ordered) {
13705            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13706        }
13707
13708        userId = handleIncomingUser(callingPid, callingUid, userId,
13709                true, false, "broadcast", callerPackage);
13710
13711        // Make sure that the user who is receiving this broadcast is started.
13712        // If not, we will just skip it.
13713        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13714            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13715                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13716                Slog.w(TAG, "Skipping broadcast of " + intent
13717                        + ": user " + userId + " is stopped");
13718                return ActivityManager.BROADCAST_SUCCESS;
13719            }
13720        }
13721
13722        /*
13723         * Prevent non-system code (defined here to be non-persistent
13724         * processes) from sending protected broadcasts.
13725         */
13726        int callingAppId = UserHandle.getAppId(callingUid);
13727        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13728            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13729            callingUid == 0) {
13730            // Always okay.
13731        } else if (callerApp == null || !callerApp.persistent) {
13732            try {
13733                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13734                        intent.getAction())) {
13735                    String msg = "Permission Denial: not allowed to send broadcast "
13736                            + intent.getAction() + " from pid="
13737                            + callingPid + ", uid=" + callingUid;
13738                    Slog.w(TAG, msg);
13739                    throw new SecurityException(msg);
13740                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13741                    // Special case for compatibility: we don't want apps to send this,
13742                    // but historically it has not been protected and apps may be using it
13743                    // to poke their own app widget.  So, instead of making it protected,
13744                    // just limit it to the caller.
13745                    if (callerApp == null) {
13746                        String msg = "Permission Denial: not allowed to send broadcast "
13747                                + intent.getAction() + " from unknown caller.";
13748                        Slog.w(TAG, msg);
13749                        throw new SecurityException(msg);
13750                    } else if (intent.getComponent() != null) {
13751                        // They are good enough to send to an explicit component...  verify
13752                        // it is being sent to the calling app.
13753                        if (!intent.getComponent().getPackageName().equals(
13754                                callerApp.info.packageName)) {
13755                            String msg = "Permission Denial: not allowed to send broadcast "
13756                                    + intent.getAction() + " to "
13757                                    + intent.getComponent().getPackageName() + " from "
13758                                    + callerApp.info.packageName;
13759                            Slog.w(TAG, msg);
13760                            throw new SecurityException(msg);
13761                        }
13762                    } else {
13763                        // Limit broadcast to their own package.
13764                        intent.setPackage(callerApp.info.packageName);
13765                    }
13766                }
13767            } catch (RemoteException e) {
13768                Slog.w(TAG, "Remote exception", e);
13769                return ActivityManager.BROADCAST_SUCCESS;
13770            }
13771        }
13772
13773        // Handle special intents: if this broadcast is from the package
13774        // manager about a package being removed, we need to remove all of
13775        // its activities from the history stack.
13776        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13777                intent.getAction());
13778        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13779                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13780                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13781                || uidRemoved) {
13782            if (checkComponentPermission(
13783                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13784                    callingPid, callingUid, -1, true)
13785                    == PackageManager.PERMISSION_GRANTED) {
13786                if (uidRemoved) {
13787                    final Bundle intentExtras = intent.getExtras();
13788                    final int uid = intentExtras != null
13789                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13790                    if (uid >= 0) {
13791                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13792                        synchronized (bs) {
13793                            bs.removeUidStatsLocked(uid);
13794                        }
13795                        mAppOpsService.uidRemoved(uid);
13796                    }
13797                } else {
13798                    // If resources are unavailable just force stop all
13799                    // those packages and flush the attribute cache as well.
13800                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13801                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13802                        if (list != null && (list.length > 0)) {
13803                            for (String pkg : list) {
13804                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13805                                        "storage unmount");
13806                            }
13807                            sendPackageBroadcastLocked(
13808                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13809                        }
13810                    } else {
13811                        Uri data = intent.getData();
13812                        String ssp;
13813                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13814                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13815                                    intent.getAction());
13816                            boolean fullUninstall = removed &&
13817                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13818                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13819                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13820                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13821                                        false, fullUninstall, userId,
13822                                        removed ? "pkg removed" : "pkg changed");
13823                            }
13824                            if (removed) {
13825                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13826                                        new String[] {ssp}, userId);
13827                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13828                                    mAppOpsService.packageRemoved(
13829                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13830
13831                                    // Remove all permissions granted from/to this package
13832                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13833                                }
13834                            }
13835                        }
13836                    }
13837                }
13838            } else {
13839                String msg = "Permission Denial: " + intent.getAction()
13840                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13841                        + ", uid=" + callingUid + ")"
13842                        + " requires "
13843                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13844                Slog.w(TAG, msg);
13845                throw new SecurityException(msg);
13846            }
13847
13848        // Special case for adding a package: by default turn on compatibility
13849        // mode.
13850        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13851            Uri data = intent.getData();
13852            String ssp;
13853            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13854                mCompatModePackages.handlePackageAddedLocked(ssp,
13855                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13856            }
13857        }
13858
13859        /*
13860         * If this is the time zone changed action, queue up a message that will reset the timezone
13861         * of all currently running processes. This message will get queued up before the broadcast
13862         * happens.
13863         */
13864        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13865            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13866        }
13867
13868        /*
13869         * If the user set the time, let all running processes know.
13870         */
13871        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13872            final int is24Hour = intent.getBooleanExtra(
13873                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13874            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13875        }
13876
13877        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13878            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13879        }
13880
13881        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13882            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13883            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13884        }
13885
13886        // Add to the sticky list if requested.
13887        if (sticky) {
13888            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13889                    callingPid, callingUid)
13890                    != PackageManager.PERMISSION_GRANTED) {
13891                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13892                        + callingPid + ", uid=" + callingUid
13893                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13894                Slog.w(TAG, msg);
13895                throw new SecurityException(msg);
13896            }
13897            if (requiredPermission != null) {
13898                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13899                        + " and enforce permission " + requiredPermission);
13900                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13901            }
13902            if (intent.getComponent() != null) {
13903                throw new SecurityException(
13904                        "Sticky broadcasts can't target a specific component");
13905            }
13906            // We use userId directly here, since the "all" target is maintained
13907            // as a separate set of sticky broadcasts.
13908            if (userId != UserHandle.USER_ALL) {
13909                // But first, if this is not a broadcast to all users, then
13910                // make sure it doesn't conflict with an existing broadcast to
13911                // all users.
13912                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13913                        UserHandle.USER_ALL);
13914                if (stickies != null) {
13915                    ArrayList<Intent> list = stickies.get(intent.getAction());
13916                    if (list != null) {
13917                        int N = list.size();
13918                        int i;
13919                        for (i=0; i<N; i++) {
13920                            if (intent.filterEquals(list.get(i))) {
13921                                throw new IllegalArgumentException(
13922                                        "Sticky broadcast " + intent + " for user "
13923                                        + userId + " conflicts with existing global broadcast");
13924                            }
13925                        }
13926                    }
13927                }
13928            }
13929            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13930            if (stickies == null) {
13931                stickies = new ArrayMap<String, ArrayList<Intent>>();
13932                mStickyBroadcasts.put(userId, stickies);
13933            }
13934            ArrayList<Intent> list = stickies.get(intent.getAction());
13935            if (list == null) {
13936                list = new ArrayList<Intent>();
13937                stickies.put(intent.getAction(), list);
13938            }
13939            int N = list.size();
13940            int i;
13941            for (i=0; i<N; i++) {
13942                if (intent.filterEquals(list.get(i))) {
13943                    // This sticky already exists, replace it.
13944                    list.set(i, new Intent(intent));
13945                    break;
13946                }
13947            }
13948            if (i >= N) {
13949                list.add(new Intent(intent));
13950            }
13951        }
13952
13953        int[] users;
13954        if (userId == UserHandle.USER_ALL) {
13955            // Caller wants broadcast to go to all started users.
13956            users = mStartedUserArray;
13957        } else {
13958            // Caller wants broadcast to go to one specific user.
13959            users = new int[] {userId};
13960        }
13961
13962        // Figure out who all will receive this broadcast.
13963        List receivers = null;
13964        List<BroadcastFilter> registeredReceivers = null;
13965        // Need to resolve the intent to interested receivers...
13966        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13967                 == 0) {
13968            receivers = collectReceiverComponents(intent, resolvedType, users);
13969        }
13970        if (intent.getComponent() == null) {
13971            registeredReceivers = mReceiverResolver.queryIntent(intent,
13972                    resolvedType, false, userId);
13973        }
13974
13975        final boolean replacePending =
13976                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13977
13978        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13979                + " replacePending=" + replacePending);
13980
13981        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13982        if (!ordered && NR > 0) {
13983            // If we are not serializing this broadcast, then send the
13984            // registered receivers separately so they don't wait for the
13985            // components to be launched.
13986            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13987            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13988                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13989                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13990                    ordered, sticky, false, userId);
13991            if (DEBUG_BROADCAST) Slog.v(
13992                    TAG, "Enqueueing parallel broadcast " + r);
13993            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13994            if (!replaced) {
13995                queue.enqueueParallelBroadcastLocked(r);
13996                queue.scheduleBroadcastsLocked();
13997            }
13998            registeredReceivers = null;
13999            NR = 0;
14000        }
14001
14002        // Merge into one list.
14003        int ir = 0;
14004        if (receivers != null) {
14005            // A special case for PACKAGE_ADDED: do not allow the package
14006            // being added to see this broadcast.  This prevents them from
14007            // using this as a back door to get run as soon as they are
14008            // installed.  Maybe in the future we want to have a special install
14009            // broadcast or such for apps, but we'd like to deliberately make
14010            // this decision.
14011            String skipPackages[] = null;
14012            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14013                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14014                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14015                Uri data = intent.getData();
14016                if (data != null) {
14017                    String pkgName = data.getSchemeSpecificPart();
14018                    if (pkgName != null) {
14019                        skipPackages = new String[] { pkgName };
14020                    }
14021                }
14022            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14023                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14024            }
14025            if (skipPackages != null && (skipPackages.length > 0)) {
14026                for (String skipPackage : skipPackages) {
14027                    if (skipPackage != null) {
14028                        int NT = receivers.size();
14029                        for (int it=0; it<NT; it++) {
14030                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14031                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14032                                receivers.remove(it);
14033                                it--;
14034                                NT--;
14035                            }
14036                        }
14037                    }
14038                }
14039            }
14040
14041            int NT = receivers != null ? receivers.size() : 0;
14042            int it = 0;
14043            ResolveInfo curt = null;
14044            BroadcastFilter curr = null;
14045            while (it < NT && ir < NR) {
14046                if (curt == null) {
14047                    curt = (ResolveInfo)receivers.get(it);
14048                }
14049                if (curr == null) {
14050                    curr = registeredReceivers.get(ir);
14051                }
14052                if (curr.getPriority() >= curt.priority) {
14053                    // Insert this broadcast record into the final list.
14054                    receivers.add(it, curr);
14055                    ir++;
14056                    curr = null;
14057                    it++;
14058                    NT++;
14059                } else {
14060                    // Skip to the next ResolveInfo in the final list.
14061                    it++;
14062                    curt = null;
14063                }
14064            }
14065        }
14066        while (ir < NR) {
14067            if (receivers == null) {
14068                receivers = new ArrayList();
14069            }
14070            receivers.add(registeredReceivers.get(ir));
14071            ir++;
14072        }
14073
14074        if ((receivers != null && receivers.size() > 0)
14075                || resultTo != null) {
14076            BroadcastQueue queue = broadcastQueueForIntent(intent);
14077            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14078                    callerPackage, callingPid, callingUid, resolvedType,
14079                    requiredPermission, appOp, receivers, resultTo, resultCode,
14080                    resultData, map, ordered, sticky, false, userId);
14081            if (DEBUG_BROADCAST) Slog.v(
14082                    TAG, "Enqueueing ordered broadcast " + r
14083                    + ": prev had " + queue.mOrderedBroadcasts.size());
14084            if (DEBUG_BROADCAST) {
14085                int seq = r.intent.getIntExtra("seq", -1);
14086                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14087            }
14088            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14089            if (!replaced) {
14090                queue.enqueueOrderedBroadcastLocked(r);
14091                queue.scheduleBroadcastsLocked();
14092            }
14093        }
14094
14095        return ActivityManager.BROADCAST_SUCCESS;
14096    }
14097
14098    final Intent verifyBroadcastLocked(Intent intent) {
14099        // Refuse possible leaked file descriptors
14100        if (intent != null && intent.hasFileDescriptors() == true) {
14101            throw new IllegalArgumentException("File descriptors passed in Intent");
14102        }
14103
14104        int flags = intent.getFlags();
14105
14106        if (!mProcessesReady) {
14107            // if the caller really truly claims to know what they're doing, go
14108            // ahead and allow the broadcast without launching any receivers
14109            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14110                intent = new Intent(intent);
14111                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14112            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14113                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14114                        + " before boot completion");
14115                throw new IllegalStateException("Cannot broadcast before boot completed");
14116            }
14117        }
14118
14119        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14120            throw new IllegalArgumentException(
14121                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14122        }
14123
14124        return intent;
14125    }
14126
14127    public final int broadcastIntent(IApplicationThread caller,
14128            Intent intent, String resolvedType, IIntentReceiver resultTo,
14129            int resultCode, String resultData, Bundle map,
14130            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14131        enforceNotIsolatedCaller("broadcastIntent");
14132        synchronized(this) {
14133            intent = verifyBroadcastLocked(intent);
14134
14135            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14136            final int callingPid = Binder.getCallingPid();
14137            final int callingUid = Binder.getCallingUid();
14138            final long origId = Binder.clearCallingIdentity();
14139            int res = broadcastIntentLocked(callerApp,
14140                    callerApp != null ? callerApp.info.packageName : null,
14141                    intent, resolvedType, resultTo,
14142                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14143                    callingPid, callingUid, userId);
14144            Binder.restoreCallingIdentity(origId);
14145            return res;
14146        }
14147    }
14148
14149    int broadcastIntentInPackage(String packageName, int uid,
14150            Intent intent, String resolvedType, IIntentReceiver resultTo,
14151            int resultCode, String resultData, Bundle map,
14152            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14153        synchronized(this) {
14154            intent = verifyBroadcastLocked(intent);
14155
14156            final long origId = Binder.clearCallingIdentity();
14157            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14158                    resultTo, resultCode, resultData, map, requiredPermission,
14159                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14160            Binder.restoreCallingIdentity(origId);
14161            return res;
14162        }
14163    }
14164
14165    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14166        // Refuse possible leaked file descriptors
14167        if (intent != null && intent.hasFileDescriptors() == true) {
14168            throw new IllegalArgumentException("File descriptors passed in Intent");
14169        }
14170
14171        userId = handleIncomingUser(Binder.getCallingPid(),
14172                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14173
14174        synchronized(this) {
14175            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14176                    != PackageManager.PERMISSION_GRANTED) {
14177                String msg = "Permission Denial: unbroadcastIntent() from pid="
14178                        + Binder.getCallingPid()
14179                        + ", uid=" + Binder.getCallingUid()
14180                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14181                Slog.w(TAG, msg);
14182                throw new SecurityException(msg);
14183            }
14184            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14185            if (stickies != null) {
14186                ArrayList<Intent> list = stickies.get(intent.getAction());
14187                if (list != null) {
14188                    int N = list.size();
14189                    int i;
14190                    for (i=0; i<N; i++) {
14191                        if (intent.filterEquals(list.get(i))) {
14192                            list.remove(i);
14193                            break;
14194                        }
14195                    }
14196                    if (list.size() <= 0) {
14197                        stickies.remove(intent.getAction());
14198                    }
14199                }
14200                if (stickies.size() <= 0) {
14201                    mStickyBroadcasts.remove(userId);
14202                }
14203            }
14204        }
14205    }
14206
14207    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14208            String resultData, Bundle resultExtras, boolean resultAbort) {
14209        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14210        if (r == null) {
14211            Slog.w(TAG, "finishReceiver called but not found on queue");
14212            return false;
14213        }
14214
14215        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14216    }
14217
14218    void backgroundServicesFinishedLocked(int userId) {
14219        for (BroadcastQueue queue : mBroadcastQueues) {
14220            queue.backgroundServicesFinishedLocked(userId);
14221        }
14222    }
14223
14224    public void finishReceiver(IBinder who, int resultCode, String resultData,
14225            Bundle resultExtras, boolean resultAbort) {
14226        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14227
14228        // Refuse possible leaked file descriptors
14229        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14230            throw new IllegalArgumentException("File descriptors passed in Bundle");
14231        }
14232
14233        final long origId = Binder.clearCallingIdentity();
14234        try {
14235            boolean doNext = false;
14236            BroadcastRecord r;
14237
14238            synchronized(this) {
14239                r = broadcastRecordForReceiverLocked(who);
14240                if (r != null) {
14241                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14242                        resultData, resultExtras, resultAbort, true);
14243                }
14244            }
14245
14246            if (doNext) {
14247                r.queue.processNextBroadcast(false);
14248            }
14249            trimApplications();
14250        } finally {
14251            Binder.restoreCallingIdentity(origId);
14252        }
14253    }
14254
14255    // =========================================================
14256    // INSTRUMENTATION
14257    // =========================================================
14258
14259    public boolean startInstrumentation(ComponentName className,
14260            String profileFile, int flags, Bundle arguments,
14261            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14262            int userId) {
14263        enforceNotIsolatedCaller("startInstrumentation");
14264        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14265                userId, false, true, "startInstrumentation", null);
14266        // Refuse possible leaked file descriptors
14267        if (arguments != null && arguments.hasFileDescriptors()) {
14268            throw new IllegalArgumentException("File descriptors passed in Bundle");
14269        }
14270
14271        synchronized(this) {
14272            InstrumentationInfo ii = null;
14273            ApplicationInfo ai = null;
14274            try {
14275                ii = mContext.getPackageManager().getInstrumentationInfo(
14276                    className, STOCK_PM_FLAGS);
14277                ai = AppGlobals.getPackageManager().getApplicationInfo(
14278                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14279            } catch (PackageManager.NameNotFoundException e) {
14280            } catch (RemoteException e) {
14281            }
14282            if (ii == null) {
14283                reportStartInstrumentationFailure(watcher, className,
14284                        "Unable to find instrumentation info for: " + className);
14285                return false;
14286            }
14287            if (ai == null) {
14288                reportStartInstrumentationFailure(watcher, className,
14289                        "Unable to find instrumentation target package: " + ii.targetPackage);
14290                return false;
14291            }
14292
14293            int match = mContext.getPackageManager().checkSignatures(
14294                    ii.targetPackage, ii.packageName);
14295            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14296                String msg = "Permission Denial: starting instrumentation "
14297                        + className + " from pid="
14298                        + Binder.getCallingPid()
14299                        + ", uid=" + Binder.getCallingPid()
14300                        + " not allowed because package " + ii.packageName
14301                        + " does not have a signature matching the target "
14302                        + ii.targetPackage;
14303                reportStartInstrumentationFailure(watcher, className, msg);
14304                throw new SecurityException(msg);
14305            }
14306
14307            final long origId = Binder.clearCallingIdentity();
14308            // Instrumentation can kill and relaunch even persistent processes
14309            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14310                    "start instr");
14311            ProcessRecord app = addAppLocked(ai, false);
14312            app.instrumentationClass = className;
14313            app.instrumentationInfo = ai;
14314            app.instrumentationProfileFile = profileFile;
14315            app.instrumentationArguments = arguments;
14316            app.instrumentationWatcher = watcher;
14317            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14318            app.instrumentationResultClass = className;
14319            Binder.restoreCallingIdentity(origId);
14320        }
14321
14322        return true;
14323    }
14324
14325    /**
14326     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14327     * error to the logs, but if somebody is watching, send the report there too.  This enables
14328     * the "am" command to report errors with more information.
14329     *
14330     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14331     * @param cn The component name of the instrumentation.
14332     * @param report The error report.
14333     */
14334    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14335            ComponentName cn, String report) {
14336        Slog.w(TAG, report);
14337        try {
14338            if (watcher != null) {
14339                Bundle results = new Bundle();
14340                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14341                results.putString("Error", report);
14342                watcher.instrumentationStatus(cn, -1, results);
14343            }
14344        } catch (RemoteException e) {
14345            Slog.w(TAG, e);
14346        }
14347    }
14348
14349    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14350        if (app.instrumentationWatcher != null) {
14351            try {
14352                // NOTE:  IInstrumentationWatcher *must* be oneway here
14353                app.instrumentationWatcher.instrumentationFinished(
14354                    app.instrumentationClass,
14355                    resultCode,
14356                    results);
14357            } catch (RemoteException e) {
14358            }
14359        }
14360        if (app.instrumentationUiAutomationConnection != null) {
14361            try {
14362                app.instrumentationUiAutomationConnection.shutdown();
14363            } catch (RemoteException re) {
14364                /* ignore */
14365            }
14366            // Only a UiAutomation can set this flag and now that
14367            // it is finished we make sure it is reset to its default.
14368            mUserIsMonkey = false;
14369        }
14370        app.instrumentationWatcher = null;
14371        app.instrumentationUiAutomationConnection = null;
14372        app.instrumentationClass = null;
14373        app.instrumentationInfo = null;
14374        app.instrumentationProfileFile = null;
14375        app.instrumentationArguments = null;
14376
14377        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14378                "finished inst");
14379    }
14380
14381    public void finishInstrumentation(IApplicationThread target,
14382            int resultCode, Bundle results) {
14383        int userId = UserHandle.getCallingUserId();
14384        // Refuse possible leaked file descriptors
14385        if (results != null && results.hasFileDescriptors()) {
14386            throw new IllegalArgumentException("File descriptors passed in Intent");
14387        }
14388
14389        synchronized(this) {
14390            ProcessRecord app = getRecordForAppLocked(target);
14391            if (app == null) {
14392                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14393                return;
14394            }
14395            final long origId = Binder.clearCallingIdentity();
14396            finishInstrumentationLocked(app, resultCode, results);
14397            Binder.restoreCallingIdentity(origId);
14398        }
14399    }
14400
14401    // =========================================================
14402    // CONFIGURATION
14403    // =========================================================
14404
14405    public ConfigurationInfo getDeviceConfigurationInfo() {
14406        ConfigurationInfo config = new ConfigurationInfo();
14407        synchronized (this) {
14408            config.reqTouchScreen = mConfiguration.touchscreen;
14409            config.reqKeyboardType = mConfiguration.keyboard;
14410            config.reqNavigation = mConfiguration.navigation;
14411            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14412                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14413                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14414            }
14415            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14416                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14417                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14418            }
14419            config.reqGlEsVersion = GL_ES_VERSION;
14420        }
14421        return config;
14422    }
14423
14424    ActivityStack getFocusedStack() {
14425        return mStackSupervisor.getFocusedStack();
14426    }
14427
14428    public Configuration getConfiguration() {
14429        Configuration ci;
14430        synchronized(this) {
14431            ci = new Configuration(mConfiguration);
14432        }
14433        return ci;
14434    }
14435
14436    public void updatePersistentConfiguration(Configuration values) {
14437        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14438                "updateConfiguration()");
14439        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14440                "updateConfiguration()");
14441        if (values == null) {
14442            throw new NullPointerException("Configuration must not be null");
14443        }
14444
14445        synchronized(this) {
14446            final long origId = Binder.clearCallingIdentity();
14447            updateConfigurationLocked(values, null, true, false);
14448            Binder.restoreCallingIdentity(origId);
14449        }
14450    }
14451
14452    public void updateConfiguration(Configuration values) {
14453        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14454                "updateConfiguration()");
14455
14456        synchronized(this) {
14457            if (values == null && mWindowManager != null) {
14458                // sentinel: fetch the current configuration from the window manager
14459                values = mWindowManager.computeNewConfiguration();
14460            }
14461
14462            if (mWindowManager != null) {
14463                mProcessList.applyDisplaySize(mWindowManager);
14464            }
14465
14466            final long origId = Binder.clearCallingIdentity();
14467            if (values != null) {
14468                Settings.System.clearConfiguration(values);
14469            }
14470            updateConfigurationLocked(values, null, false, false);
14471            Binder.restoreCallingIdentity(origId);
14472        }
14473    }
14474
14475    /**
14476     * Do either or both things: (1) change the current configuration, and (2)
14477     * make sure the given activity is running with the (now) current
14478     * configuration.  Returns true if the activity has been left running, or
14479     * false if <var>starting</var> is being destroyed to match the new
14480     * configuration.
14481     * @param persistent TODO
14482     */
14483    boolean updateConfigurationLocked(Configuration values,
14484            ActivityRecord starting, boolean persistent, boolean initLocale) {
14485        int changes = 0;
14486
14487        if (values != null) {
14488            Configuration newConfig = new Configuration(mConfiguration);
14489            changes = newConfig.updateFrom(values);
14490            if (changes != 0) {
14491                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14492                    Slog.i(TAG, "Updating configuration to: " + values);
14493                }
14494
14495                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14496
14497                if (values.locale != null && !initLocale) {
14498                    saveLocaleLocked(values.locale,
14499                                     !values.locale.equals(mConfiguration.locale),
14500                                     values.userSetLocale);
14501                }
14502
14503                mConfigurationSeq++;
14504                if (mConfigurationSeq <= 0) {
14505                    mConfigurationSeq = 1;
14506                }
14507                newConfig.seq = mConfigurationSeq;
14508                mConfiguration = newConfig;
14509                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14510                mUsageStatsService.noteStartConfig(newConfig);
14511
14512                final Configuration configCopy = new Configuration(mConfiguration);
14513
14514                // TODO: If our config changes, should we auto dismiss any currently
14515                // showing dialogs?
14516                mShowDialogs = shouldShowDialogs(newConfig);
14517
14518                AttributeCache ac = AttributeCache.instance();
14519                if (ac != null) {
14520                    ac.updateConfiguration(configCopy);
14521                }
14522
14523                // Make sure all resources in our process are updated
14524                // right now, so that anyone who is going to retrieve
14525                // resource values after we return will be sure to get
14526                // the new ones.  This is especially important during
14527                // boot, where the first config change needs to guarantee
14528                // all resources have that config before following boot
14529                // code is executed.
14530                mSystemThread.applyConfigurationToResources(configCopy);
14531
14532                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14533                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14534                    msg.obj = new Configuration(configCopy);
14535                    mHandler.sendMessage(msg);
14536                }
14537
14538                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14539                    ProcessRecord app = mLruProcesses.get(i);
14540                    try {
14541                        if (app.thread != null) {
14542                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14543                                    + app.processName + " new config " + mConfiguration);
14544                            app.thread.scheduleConfigurationChanged(configCopy);
14545                        }
14546                    } catch (Exception e) {
14547                    }
14548                }
14549                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14550                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14551                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14552                        | Intent.FLAG_RECEIVER_FOREGROUND);
14553                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14554                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14555                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14556                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14557                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14558                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14559                    broadcastIntentLocked(null, null, intent,
14560                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14561                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14562                }
14563            }
14564        }
14565
14566        boolean kept = true;
14567        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14568        // mainStack is null during startup.
14569        if (mainStack != null) {
14570            if (changes != 0 && starting == null) {
14571                // If the configuration changed, and the caller is not already
14572                // in the process of starting an activity, then find the top
14573                // activity to check if its configuration needs to change.
14574                starting = mainStack.topRunningActivityLocked(null);
14575            }
14576
14577            if (starting != null) {
14578                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14579                // And we need to make sure at this point that all other activities
14580                // are made visible with the correct configuration.
14581                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14582            }
14583        }
14584
14585        if (values != null && mWindowManager != null) {
14586            mWindowManager.setNewConfiguration(mConfiguration);
14587        }
14588
14589        return kept;
14590    }
14591
14592    /**
14593     * Decide based on the configuration whether we should shouw the ANR,
14594     * crash, etc dialogs.  The idea is that if there is no affordnace to
14595     * press the on-screen buttons, we shouldn't show the dialog.
14596     *
14597     * A thought: SystemUI might also want to get told about this, the Power
14598     * dialog / global actions also might want different behaviors.
14599     */
14600    private static final boolean shouldShowDialogs(Configuration config) {
14601        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14602                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14603    }
14604
14605    /**
14606     * Save the locale.  You must be inside a synchronized (this) block.
14607     */
14608    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14609        if(isDiff) {
14610            SystemProperties.set("user.language", l.getLanguage());
14611            SystemProperties.set("user.region", l.getCountry());
14612        }
14613
14614        if(isPersist) {
14615            SystemProperties.set("persist.sys.language", l.getLanguage());
14616            SystemProperties.set("persist.sys.country", l.getCountry());
14617            SystemProperties.set("persist.sys.localevar", l.getVariant());
14618        }
14619    }
14620
14621    @Override
14622    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14623        ActivityRecord srec = ActivityRecord.forToken(token);
14624        return srec != null && srec.task.affinity != null &&
14625                srec.task.affinity.equals(destAffinity);
14626    }
14627
14628    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14629            Intent resultData) {
14630
14631        synchronized (this) {
14632            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14633            if (stack != null) {
14634                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14635            }
14636            return false;
14637        }
14638    }
14639
14640    public int getLaunchedFromUid(IBinder activityToken) {
14641        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14642        if (srec == null) {
14643            return -1;
14644        }
14645        return srec.launchedFromUid;
14646    }
14647
14648    public String getLaunchedFromPackage(IBinder activityToken) {
14649        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14650        if (srec == null) {
14651            return null;
14652        }
14653        return srec.launchedFromPackage;
14654    }
14655
14656    // =========================================================
14657    // LIFETIME MANAGEMENT
14658    // =========================================================
14659
14660    // Returns which broadcast queue the app is the current [or imminent] receiver
14661    // on, or 'null' if the app is not an active broadcast recipient.
14662    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14663        BroadcastRecord r = app.curReceiver;
14664        if (r != null) {
14665            return r.queue;
14666        }
14667
14668        // It's not the current receiver, but it might be starting up to become one
14669        synchronized (this) {
14670            for (BroadcastQueue queue : mBroadcastQueues) {
14671                r = queue.mPendingBroadcast;
14672                if (r != null && r.curApp == app) {
14673                    // found it; report which queue it's in
14674                    return queue;
14675                }
14676            }
14677        }
14678
14679        return null;
14680    }
14681
14682    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14683            boolean doingAll, long now) {
14684        if (mAdjSeq == app.adjSeq) {
14685            // This adjustment has already been computed.
14686            return app.curRawAdj;
14687        }
14688
14689        if (app.thread == null) {
14690            app.adjSeq = mAdjSeq;
14691            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14692            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14693            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14694        }
14695
14696        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14697        app.adjSource = null;
14698        app.adjTarget = null;
14699        app.empty = false;
14700        app.cached = false;
14701
14702        final int activitiesSize = app.activities.size();
14703
14704        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14705            // The max adjustment doesn't allow this app to be anything
14706            // below foreground, so it is not worth doing work for it.
14707            app.adjType = "fixed";
14708            app.adjSeq = mAdjSeq;
14709            app.curRawAdj = app.maxAdj;
14710            app.foregroundActivities = false;
14711            app.keeping = true;
14712            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14713            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14714            // System processes can do UI, and when they do we want to have
14715            // them trim their memory after the user leaves the UI.  To
14716            // facilitate this, here we need to determine whether or not it
14717            // is currently showing UI.
14718            app.systemNoUi = true;
14719            if (app == TOP_APP) {
14720                app.systemNoUi = false;
14721            } else if (activitiesSize > 0) {
14722                for (int j = 0; j < activitiesSize; j++) {
14723                    final ActivityRecord r = app.activities.get(j);
14724                    if (r.visible) {
14725                        app.systemNoUi = false;
14726                    }
14727                }
14728            }
14729            if (!app.systemNoUi) {
14730                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14731            }
14732            return (app.curAdj=app.maxAdj);
14733        }
14734
14735        app.keeping = false;
14736        app.systemNoUi = false;
14737
14738        // Determine the importance of the process, starting with most
14739        // important to least, and assign an appropriate OOM adjustment.
14740        int adj;
14741        int schedGroup;
14742        int procState;
14743        boolean foregroundActivities = false;
14744        boolean interesting = false;
14745        BroadcastQueue queue;
14746        if (app == TOP_APP) {
14747            // The last app on the list is the foreground app.
14748            adj = ProcessList.FOREGROUND_APP_ADJ;
14749            schedGroup = Process.THREAD_GROUP_DEFAULT;
14750            app.adjType = "top-activity";
14751            foregroundActivities = true;
14752            interesting = true;
14753            procState = ActivityManager.PROCESS_STATE_TOP;
14754        } else if (app.instrumentationClass != null) {
14755            // Don't want to kill running instrumentation.
14756            adj = ProcessList.FOREGROUND_APP_ADJ;
14757            schedGroup = Process.THREAD_GROUP_DEFAULT;
14758            app.adjType = "instrumentation";
14759            interesting = true;
14760            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14761        } else if ((queue = isReceivingBroadcast(app)) != null) {
14762            // An app that is currently receiving a broadcast also
14763            // counts as being in the foreground for OOM killer purposes.
14764            // It's placed in a sched group based on the nature of the
14765            // broadcast as reflected by which queue it's active in.
14766            adj = ProcessList.FOREGROUND_APP_ADJ;
14767            schedGroup = (queue == mFgBroadcastQueue)
14768                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14769            app.adjType = "broadcast";
14770            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14771        } else if (app.executingServices.size() > 0) {
14772            // An app that is currently executing a service callback also
14773            // counts as being in the foreground.
14774            adj = ProcessList.FOREGROUND_APP_ADJ;
14775            schedGroup = app.execServicesFg ?
14776                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14777            app.adjType = "exec-service";
14778            procState = ActivityManager.PROCESS_STATE_SERVICE;
14779            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14780        } else {
14781            // As far as we know the process is empty.  We may change our mind later.
14782            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14783            // At this point we don't actually know the adjustment.  Use the cached adj
14784            // value that the caller wants us to.
14785            adj = cachedAdj;
14786            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14787            app.cached = true;
14788            app.empty = true;
14789            app.adjType = "cch-empty";
14790        }
14791
14792        // Examine all activities if not already foreground.
14793        if (!foregroundActivities && activitiesSize > 0) {
14794            for (int j = 0; j < activitiesSize; j++) {
14795                final ActivityRecord r = app.activities.get(j);
14796                if (r.app != app) {
14797                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14798                            + app + "?!?");
14799                    continue;
14800                }
14801                if (r.visible) {
14802                    // App has a visible activity; only upgrade adjustment.
14803                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14804                        adj = ProcessList.VISIBLE_APP_ADJ;
14805                        app.adjType = "visible";
14806                    }
14807                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14808                        procState = ActivityManager.PROCESS_STATE_TOP;
14809                    }
14810                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14811                    app.cached = false;
14812                    app.empty = false;
14813                    foregroundActivities = true;
14814                    break;
14815                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14816                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14817                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14818                        app.adjType = "pausing";
14819                    }
14820                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14821                        procState = ActivityManager.PROCESS_STATE_TOP;
14822                    }
14823                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14824                    app.cached = false;
14825                    app.empty = false;
14826                    foregroundActivities = true;
14827                } else if (r.state == ActivityState.STOPPING) {
14828                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14829                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14830                        app.adjType = "stopping";
14831                    }
14832                    // For the process state, we will at this point consider the
14833                    // process to be cached.  It will be cached either as an activity
14834                    // or empty depending on whether the activity is finishing.  We do
14835                    // this so that we can treat the process as cached for purposes of
14836                    // memory trimming (determing current memory level, trim command to
14837                    // send to process) since there can be an arbitrary number of stopping
14838                    // processes and they should soon all go into the cached state.
14839                    if (!r.finishing) {
14840                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14841                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14842                        }
14843                    }
14844                    app.cached = false;
14845                    app.empty = false;
14846                    foregroundActivities = true;
14847                } else {
14848                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14849                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14850                        app.adjType = "cch-act";
14851                    }
14852                }
14853            }
14854        }
14855
14856        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14857            if (app.foregroundServices) {
14858                // The user is aware of this app, so make it visible.
14859                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14860                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14861                app.cached = false;
14862                app.adjType = "fg-service";
14863                schedGroup = Process.THREAD_GROUP_DEFAULT;
14864            } else if (app.forcingToForeground != null) {
14865                // The user is aware of this app, so make it visible.
14866                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14867                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14868                app.cached = false;
14869                app.adjType = "force-fg";
14870                app.adjSource = app.forcingToForeground;
14871                schedGroup = Process.THREAD_GROUP_DEFAULT;
14872            }
14873        }
14874
14875        if (app.foregroundServices) {
14876            interesting = true;
14877        }
14878
14879        if (app == mHeavyWeightProcess) {
14880            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14881                // We don't want to kill the current heavy-weight process.
14882                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14883                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14884                app.cached = false;
14885                app.adjType = "heavy";
14886            }
14887            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14888                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14889            }
14890        }
14891
14892        if (app == mHomeProcess) {
14893            if (adj > ProcessList.HOME_APP_ADJ) {
14894                // This process is hosting what we currently consider to be the
14895                // home app, so we don't want to let it go into the background.
14896                adj = ProcessList.HOME_APP_ADJ;
14897                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14898                app.cached = false;
14899                app.adjType = "home";
14900            }
14901            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14902                procState = ActivityManager.PROCESS_STATE_HOME;
14903            }
14904        }
14905
14906        if (app == mPreviousProcess && app.activities.size() > 0) {
14907            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14908                // This was the previous process that showed UI to the user.
14909                // We want to try to keep it around more aggressively, to give
14910                // a good experience around switching between two apps.
14911                adj = ProcessList.PREVIOUS_APP_ADJ;
14912                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14913                app.cached = false;
14914                app.adjType = "previous";
14915            }
14916            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14917                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14918            }
14919        }
14920
14921        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14922                + " reason=" + app.adjType);
14923
14924        // By default, we use the computed adjustment.  It may be changed if
14925        // there are applications dependent on our services or providers, but
14926        // this gives us a baseline and makes sure we don't get into an
14927        // infinite recursion.
14928        app.adjSeq = mAdjSeq;
14929        app.curRawAdj = adj;
14930        app.hasStartedServices = false;
14931
14932        if (mBackupTarget != null && app == mBackupTarget.app) {
14933            // If possible we want to avoid killing apps while they're being backed up
14934            if (adj > ProcessList.BACKUP_APP_ADJ) {
14935                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14936                adj = ProcessList.BACKUP_APP_ADJ;
14937                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14938                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14939                }
14940                app.adjType = "backup";
14941                app.cached = false;
14942            }
14943            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14944                procState = ActivityManager.PROCESS_STATE_BACKUP;
14945            }
14946        }
14947
14948        boolean mayBeTop = false;
14949
14950        for (int is = app.services.size()-1;
14951                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14952                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14953                        || procState > ActivityManager.PROCESS_STATE_TOP);
14954                is--) {
14955            ServiceRecord s = app.services.valueAt(is);
14956            if (s.startRequested) {
14957                app.hasStartedServices = true;
14958                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14959                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14960                }
14961                if (app.hasShownUi && app != mHomeProcess) {
14962                    // If this process has shown some UI, let it immediately
14963                    // go to the LRU list because it may be pretty heavy with
14964                    // UI stuff.  We'll tag it with a label just to help
14965                    // debug and understand what is going on.
14966                    if (adj > ProcessList.SERVICE_ADJ) {
14967                        app.adjType = "cch-started-ui-services";
14968                    }
14969                } else {
14970                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14971                        // This service has seen some activity within
14972                        // recent memory, so we will keep its process ahead
14973                        // of the background processes.
14974                        if (adj > ProcessList.SERVICE_ADJ) {
14975                            adj = ProcessList.SERVICE_ADJ;
14976                            app.adjType = "started-services";
14977                            app.cached = false;
14978                        }
14979                    }
14980                    // If we have let the service slide into the background
14981                    // state, still have some text describing what it is doing
14982                    // even though the service no longer has an impact.
14983                    if (adj > ProcessList.SERVICE_ADJ) {
14984                        app.adjType = "cch-started-services";
14985                    }
14986                }
14987                // Don't kill this process because it is doing work; it
14988                // has said it is doing work.
14989                app.keeping = true;
14990            }
14991            for (int conni = s.connections.size()-1;
14992                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14993                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14994                            || procState > ActivityManager.PROCESS_STATE_TOP);
14995                    conni--) {
14996                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14997                for (int i = 0;
14998                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14999                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15000                                || procState > ActivityManager.PROCESS_STATE_TOP);
15001                        i++) {
15002                    // XXX should compute this based on the max of
15003                    // all connected clients.
15004                    ConnectionRecord cr = clist.get(i);
15005                    if (cr.binding.client == app) {
15006                        // Binding to ourself is not interesting.
15007                        continue;
15008                    }
15009                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15010                        ProcessRecord client = cr.binding.client;
15011                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15012                                TOP_APP, doingAll, now);
15013                        int clientProcState = client.curProcState;
15014                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15015                            // If the other app is cached for any reason, for purposes here
15016                            // we are going to consider it empty.  The specific cached state
15017                            // doesn't propagate except under certain conditions.
15018                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15019                        }
15020                        String adjType = null;
15021                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15022                            // Not doing bind OOM management, so treat
15023                            // this guy more like a started service.
15024                            if (app.hasShownUi && app != mHomeProcess) {
15025                                // If this process has shown some UI, let it immediately
15026                                // go to the LRU list because it may be pretty heavy with
15027                                // UI stuff.  We'll tag it with a label just to help
15028                                // debug and understand what is going on.
15029                                if (adj > clientAdj) {
15030                                    adjType = "cch-bound-ui-services";
15031                                }
15032                                app.cached = false;
15033                                clientAdj = adj;
15034                                clientProcState = procState;
15035                            } else {
15036                                if (now >= (s.lastActivity
15037                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15038                                    // This service has not seen activity within
15039                                    // recent memory, so allow it to drop to the
15040                                    // LRU list if there is no other reason to keep
15041                                    // it around.  We'll also tag it with a label just
15042                                    // to help debug and undertand what is going on.
15043                                    if (adj > clientAdj) {
15044                                        adjType = "cch-bound-services";
15045                                    }
15046                                    clientAdj = adj;
15047                                }
15048                            }
15049                        }
15050                        if (adj > clientAdj) {
15051                            // If this process has recently shown UI, and
15052                            // the process that is binding to it is less
15053                            // important than being visible, then we don't
15054                            // care about the binding as much as we care
15055                            // about letting this process get into the LRU
15056                            // list to be killed and restarted if needed for
15057                            // memory.
15058                            if (app.hasShownUi && app != mHomeProcess
15059                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15060                                adjType = "cch-bound-ui-services";
15061                            } else {
15062                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15063                                        |Context.BIND_IMPORTANT)) != 0) {
15064                                    adj = clientAdj;
15065                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15066                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15067                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15068                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15069                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15070                                    adj = clientAdj;
15071                                } else {
15072                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15073                                        adj = ProcessList.VISIBLE_APP_ADJ;
15074                                    }
15075                                }
15076                                if (!client.cached) {
15077                                    app.cached = false;
15078                                }
15079                                if (client.keeping) {
15080                                    app.keeping = true;
15081                                }
15082                                adjType = "service";
15083                            }
15084                        }
15085                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15086                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15087                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15088                            }
15089                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15090                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15091                                    // Special handling of clients who are in the top state.
15092                                    // We *may* want to consider this process to be in the
15093                                    // top state as well, but only if there is not another
15094                                    // reason for it to be running.  Being on the top is a
15095                                    // special state, meaning you are specifically running
15096                                    // for the current top app.  If the process is already
15097                                    // running in the background for some other reason, it
15098                                    // is more important to continue considering it to be
15099                                    // in the background state.
15100                                    mayBeTop = true;
15101                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15102                                } else {
15103                                    // Special handling for above-top states (persistent
15104                                    // processes).  These should not bring the current process
15105                                    // into the top state, since they are not on top.  Instead
15106                                    // give them the best state after that.
15107                                    clientProcState =
15108                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15109                                }
15110                            }
15111                        } else {
15112                            if (clientProcState <
15113                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15114                                clientProcState =
15115                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15116                            }
15117                        }
15118                        if (procState > clientProcState) {
15119                            procState = clientProcState;
15120                        }
15121                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15122                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15123                            app.pendingUiClean = true;
15124                        }
15125                        if (adjType != null) {
15126                            app.adjType = adjType;
15127                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15128                                    .REASON_SERVICE_IN_USE;
15129                            app.adjSource = cr.binding.client;
15130                            app.adjSourceOom = clientAdj;
15131                            app.adjTarget = s.name;
15132                        }
15133                    }
15134                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15135                        app.treatLikeActivity = true;
15136                    }
15137                    final ActivityRecord a = cr.activity;
15138                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15139                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15140                                (a.visible || a.state == ActivityState.RESUMED
15141                                 || a.state == ActivityState.PAUSING)) {
15142                            adj = ProcessList.FOREGROUND_APP_ADJ;
15143                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15144                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15145                            }
15146                            app.cached = false;
15147                            app.adjType = "service";
15148                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15149                                    .REASON_SERVICE_IN_USE;
15150                            app.adjSource = a;
15151                            app.adjSourceOom = adj;
15152                            app.adjTarget = s.name;
15153                        }
15154                    }
15155                }
15156            }
15157        }
15158
15159        for (int provi = app.pubProviders.size()-1;
15160                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15161                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15162                        || procState > ActivityManager.PROCESS_STATE_TOP);
15163                provi--) {
15164            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15165            for (int i = cpr.connections.size()-1;
15166                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15167                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15168                            || procState > ActivityManager.PROCESS_STATE_TOP);
15169                    i--) {
15170                ContentProviderConnection conn = cpr.connections.get(i);
15171                ProcessRecord client = conn.client;
15172                if (client == app) {
15173                    // Being our own client is not interesting.
15174                    continue;
15175                }
15176                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15177                int clientProcState = client.curProcState;
15178                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15179                    // If the other app is cached for any reason, for purposes here
15180                    // we are going to consider it empty.
15181                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15182                }
15183                if (adj > clientAdj) {
15184                    if (app.hasShownUi && app != mHomeProcess
15185                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15186                        app.adjType = "cch-ui-provider";
15187                    } else {
15188                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15189                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15190                        app.adjType = "provider";
15191                    }
15192                    app.cached &= client.cached;
15193                    app.keeping |= client.keeping;
15194                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15195                            .REASON_PROVIDER_IN_USE;
15196                    app.adjSource = client;
15197                    app.adjSourceOom = clientAdj;
15198                    app.adjTarget = cpr.name;
15199                }
15200                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15201                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15202                        // Special handling of clients who are in the top state.
15203                        // We *may* want to consider this process to be in the
15204                        // top state as well, but only if there is not another
15205                        // reason for it to be running.  Being on the top is a
15206                        // special state, meaning you are specifically running
15207                        // for the current top app.  If the process is already
15208                        // running in the background for some other reason, it
15209                        // is more important to continue considering it to be
15210                        // in the background state.
15211                        mayBeTop = true;
15212                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15213                    } else {
15214                        // Special handling for above-top states (persistent
15215                        // processes).  These should not bring the current process
15216                        // into the top state, since they are not on top.  Instead
15217                        // give them the best state after that.
15218                        clientProcState =
15219                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15220                    }
15221                }
15222                if (procState > clientProcState) {
15223                    procState = clientProcState;
15224                }
15225                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15226                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15227                }
15228            }
15229            // If the provider has external (non-framework) process
15230            // dependencies, ensure that its adjustment is at least
15231            // FOREGROUND_APP_ADJ.
15232            if (cpr.hasExternalProcessHandles()) {
15233                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15234                    adj = ProcessList.FOREGROUND_APP_ADJ;
15235                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15236                    app.cached = false;
15237                    app.keeping = true;
15238                    app.adjType = "provider";
15239                    app.adjTarget = cpr.name;
15240                }
15241                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15242                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15243                }
15244            }
15245        }
15246
15247        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15248            // A client of one of our services or providers is in the top state.  We
15249            // *may* want to be in the top state, but not if we are already running in
15250            // the background for some other reason.  For the decision here, we are going
15251            // to pick out a few specific states that we want to remain in when a client
15252            // is top (states that tend to be longer-term) and otherwise allow it to go
15253            // to the top state.
15254            switch (procState) {
15255                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15256                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15257                case ActivityManager.PROCESS_STATE_SERVICE:
15258                    // These all are longer-term states, so pull them up to the top
15259                    // of the background states, but not all the way to the top state.
15260                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15261                    break;
15262                default:
15263                    // Otherwise, top is a better choice, so take it.
15264                    procState = ActivityManager.PROCESS_STATE_TOP;
15265                    break;
15266            }
15267        }
15268
15269        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15270            if (app.hasClientActivities) {
15271                // This is a cached process, but with client activities.  Mark it so.
15272                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15273                app.adjType = "cch-client-act";
15274            } else if (app.treatLikeActivity) {
15275                // This is a cached process, but somebody wants us to treat it like it has
15276                // an activity, okay!
15277                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15278                app.adjType = "cch-as-act";
15279            }
15280        }
15281
15282        if (adj == ProcessList.SERVICE_ADJ) {
15283            if (doingAll) {
15284                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15285                mNewNumServiceProcs++;
15286                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15287                if (!app.serviceb) {
15288                    // This service isn't far enough down on the LRU list to
15289                    // normally be a B service, but if we are low on RAM and it
15290                    // is large we want to force it down since we would prefer to
15291                    // keep launcher over it.
15292                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15293                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15294                        app.serviceHighRam = true;
15295                        app.serviceb = true;
15296                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15297                    } else {
15298                        mNewNumAServiceProcs++;
15299                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15300                    }
15301                } else {
15302                    app.serviceHighRam = false;
15303                }
15304            }
15305            if (app.serviceb) {
15306                adj = ProcessList.SERVICE_B_ADJ;
15307            }
15308        }
15309
15310        app.curRawAdj = adj;
15311
15312        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15313        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15314        if (adj > app.maxAdj) {
15315            adj = app.maxAdj;
15316            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15317                schedGroup = Process.THREAD_GROUP_DEFAULT;
15318            }
15319        }
15320        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15321            app.keeping = true;
15322        }
15323
15324        // Do final modification to adj.  Everything we do between here and applying
15325        // the final setAdj must be done in this function, because we will also use
15326        // it when computing the final cached adj later.  Note that we don't need to
15327        // worry about this for max adj above, since max adj will always be used to
15328        // keep it out of the cached vaues.
15329        app.curAdj = app.modifyRawOomAdj(adj);
15330        app.curSchedGroup = schedGroup;
15331        app.curProcState = procState;
15332        app.foregroundActivities = foregroundActivities;
15333
15334        return app.curRawAdj;
15335    }
15336
15337    /**
15338     * Schedule PSS collection of a process.
15339     */
15340    void requestPssLocked(ProcessRecord proc, int procState) {
15341        if (mPendingPssProcesses.contains(proc)) {
15342            return;
15343        }
15344        if (mPendingPssProcesses.size() == 0) {
15345            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15346        }
15347        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15348        proc.pssProcState = procState;
15349        mPendingPssProcesses.add(proc);
15350    }
15351
15352    /**
15353     * Schedule PSS collection of all processes.
15354     */
15355    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15356        if (!always) {
15357            if (now < (mLastFullPssTime +
15358                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15359                return;
15360            }
15361        }
15362        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15363        mLastFullPssTime = now;
15364        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15365        mPendingPssProcesses.clear();
15366        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15367            ProcessRecord app = mLruProcesses.get(i);
15368            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15369                app.pssProcState = app.setProcState;
15370                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15371                        isSleeping(), now);
15372                mPendingPssProcesses.add(app);
15373            }
15374        }
15375        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15376    }
15377
15378    /**
15379     * Ask a given process to GC right now.
15380     */
15381    final void performAppGcLocked(ProcessRecord app) {
15382        try {
15383            app.lastRequestedGc = SystemClock.uptimeMillis();
15384            if (app.thread != null) {
15385                if (app.reportLowMemory) {
15386                    app.reportLowMemory = false;
15387                    app.thread.scheduleLowMemory();
15388                } else {
15389                    app.thread.processInBackground();
15390                }
15391            }
15392        } catch (Exception e) {
15393            // whatever.
15394        }
15395    }
15396
15397    /**
15398     * Returns true if things are idle enough to perform GCs.
15399     */
15400    private final boolean canGcNowLocked() {
15401        boolean processingBroadcasts = false;
15402        for (BroadcastQueue q : mBroadcastQueues) {
15403            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15404                processingBroadcasts = true;
15405            }
15406        }
15407        return !processingBroadcasts
15408                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15409    }
15410
15411    /**
15412     * Perform GCs on all processes that are waiting for it, but only
15413     * if things are idle.
15414     */
15415    final void performAppGcsLocked() {
15416        final int N = mProcessesToGc.size();
15417        if (N <= 0) {
15418            return;
15419        }
15420        if (canGcNowLocked()) {
15421            while (mProcessesToGc.size() > 0) {
15422                ProcessRecord proc = mProcessesToGc.remove(0);
15423                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15424                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15425                            <= SystemClock.uptimeMillis()) {
15426                        // To avoid spamming the system, we will GC processes one
15427                        // at a time, waiting a few seconds between each.
15428                        performAppGcLocked(proc);
15429                        scheduleAppGcsLocked();
15430                        return;
15431                    } else {
15432                        // It hasn't been long enough since we last GCed this
15433                        // process...  put it in the list to wait for its time.
15434                        addProcessToGcListLocked(proc);
15435                        break;
15436                    }
15437                }
15438            }
15439
15440            scheduleAppGcsLocked();
15441        }
15442    }
15443
15444    /**
15445     * If all looks good, perform GCs on all processes waiting for them.
15446     */
15447    final void performAppGcsIfAppropriateLocked() {
15448        if (canGcNowLocked()) {
15449            performAppGcsLocked();
15450            return;
15451        }
15452        // Still not idle, wait some more.
15453        scheduleAppGcsLocked();
15454    }
15455
15456    /**
15457     * Schedule the execution of all pending app GCs.
15458     */
15459    final void scheduleAppGcsLocked() {
15460        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15461
15462        if (mProcessesToGc.size() > 0) {
15463            // Schedule a GC for the time to the next process.
15464            ProcessRecord proc = mProcessesToGc.get(0);
15465            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15466
15467            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15468            long now = SystemClock.uptimeMillis();
15469            if (when < (now+GC_TIMEOUT)) {
15470                when = now + GC_TIMEOUT;
15471            }
15472            mHandler.sendMessageAtTime(msg, when);
15473        }
15474    }
15475
15476    /**
15477     * Add a process to the array of processes waiting to be GCed.  Keeps the
15478     * list in sorted order by the last GC time.  The process can't already be
15479     * on the list.
15480     */
15481    final void addProcessToGcListLocked(ProcessRecord proc) {
15482        boolean added = false;
15483        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15484            if (mProcessesToGc.get(i).lastRequestedGc <
15485                    proc.lastRequestedGc) {
15486                added = true;
15487                mProcessesToGc.add(i+1, proc);
15488                break;
15489            }
15490        }
15491        if (!added) {
15492            mProcessesToGc.add(0, proc);
15493        }
15494    }
15495
15496    /**
15497     * Set up to ask a process to GC itself.  This will either do it
15498     * immediately, or put it on the list of processes to gc the next
15499     * time things are idle.
15500     */
15501    final void scheduleAppGcLocked(ProcessRecord app) {
15502        long now = SystemClock.uptimeMillis();
15503        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15504            return;
15505        }
15506        if (!mProcessesToGc.contains(app)) {
15507            addProcessToGcListLocked(app);
15508            scheduleAppGcsLocked();
15509        }
15510    }
15511
15512    final void checkExcessivePowerUsageLocked(boolean doKills) {
15513        updateCpuStatsNow();
15514
15515        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15516        boolean doWakeKills = doKills;
15517        boolean doCpuKills = doKills;
15518        if (mLastPowerCheckRealtime == 0) {
15519            doWakeKills = false;
15520        }
15521        if (mLastPowerCheckUptime == 0) {
15522            doCpuKills = false;
15523        }
15524        if (stats.isScreenOn()) {
15525            doWakeKills = false;
15526        }
15527        final long curRealtime = SystemClock.elapsedRealtime();
15528        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15529        final long curUptime = SystemClock.uptimeMillis();
15530        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15531        mLastPowerCheckRealtime = curRealtime;
15532        mLastPowerCheckUptime = curUptime;
15533        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15534            doWakeKills = false;
15535        }
15536        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15537            doCpuKills = false;
15538        }
15539        int i = mLruProcesses.size();
15540        while (i > 0) {
15541            i--;
15542            ProcessRecord app = mLruProcesses.get(i);
15543            if (!app.keeping) {
15544                long wtime;
15545                synchronized (stats) {
15546                    wtime = stats.getProcessWakeTime(app.info.uid,
15547                            app.pid, curRealtime);
15548                }
15549                long wtimeUsed = wtime - app.lastWakeTime;
15550                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15551                if (DEBUG_POWER) {
15552                    StringBuilder sb = new StringBuilder(128);
15553                    sb.append("Wake for ");
15554                    app.toShortString(sb);
15555                    sb.append(": over ");
15556                    TimeUtils.formatDuration(realtimeSince, sb);
15557                    sb.append(" used ");
15558                    TimeUtils.formatDuration(wtimeUsed, sb);
15559                    sb.append(" (");
15560                    sb.append((wtimeUsed*100)/realtimeSince);
15561                    sb.append("%)");
15562                    Slog.i(TAG, sb.toString());
15563                    sb.setLength(0);
15564                    sb.append("CPU for ");
15565                    app.toShortString(sb);
15566                    sb.append(": over ");
15567                    TimeUtils.formatDuration(uptimeSince, sb);
15568                    sb.append(" used ");
15569                    TimeUtils.formatDuration(cputimeUsed, sb);
15570                    sb.append(" (");
15571                    sb.append((cputimeUsed*100)/uptimeSince);
15572                    sb.append("%)");
15573                    Slog.i(TAG, sb.toString());
15574                }
15575                // If a process has held a wake lock for more
15576                // than 50% of the time during this period,
15577                // that sounds bad.  Kill!
15578                if (doWakeKills && realtimeSince > 0
15579                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15580                    synchronized (stats) {
15581                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15582                                realtimeSince, wtimeUsed);
15583                    }
15584                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15585                            + " during " + realtimeSince);
15586                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15587                } else if (doCpuKills && uptimeSince > 0
15588                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15589                    synchronized (stats) {
15590                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15591                                uptimeSince, cputimeUsed);
15592                    }
15593                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15594                            + " during " + uptimeSince);
15595                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15596                } else {
15597                    app.lastWakeTime = wtime;
15598                    app.lastCpuTime = app.curCpuTime;
15599                }
15600            }
15601        }
15602    }
15603
15604    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15605            ProcessRecord TOP_APP, boolean doingAll, long now) {
15606        boolean success = true;
15607
15608        if (app.curRawAdj != app.setRawAdj) {
15609            if (wasKeeping && !app.keeping) {
15610                // This app is no longer something we want to keep.  Note
15611                // its current wake lock time to later know to kill it if
15612                // it is not behaving well.
15613                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15614                synchronized (stats) {
15615                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15616                            app.pid, SystemClock.elapsedRealtime());
15617                }
15618                app.lastCpuTime = app.curCpuTime;
15619            }
15620
15621            app.setRawAdj = app.curRawAdj;
15622        }
15623
15624        int changes = 0;
15625
15626        if (app.curAdj != app.setAdj) {
15627            ProcessList.setOomAdj(app.pid, app.curAdj);
15628            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15629                TAG, "Set " + app.pid + " " + app.processName +
15630                " adj " + app.curAdj + ": " + app.adjType);
15631            app.setAdj = app.curAdj;
15632        }
15633
15634        if (app.setSchedGroup != app.curSchedGroup) {
15635            app.setSchedGroup = app.curSchedGroup;
15636            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15637                    "Setting process group of " + app.processName
15638                    + " to " + app.curSchedGroup);
15639            if (app.waitingToKill != null &&
15640                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15641                killUnneededProcessLocked(app, app.waitingToKill);
15642                success = false;
15643            } else {
15644                if (true) {
15645                    long oldId = Binder.clearCallingIdentity();
15646                    try {
15647                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15648                    } catch (Exception e) {
15649                        Slog.w(TAG, "Failed setting process group of " + app.pid
15650                                + " to " + app.curSchedGroup);
15651                        e.printStackTrace();
15652                    } finally {
15653                        Binder.restoreCallingIdentity(oldId);
15654                    }
15655                } else {
15656                    if (app.thread != null) {
15657                        try {
15658                            app.thread.setSchedulingGroup(app.curSchedGroup);
15659                        } catch (RemoteException e) {
15660                        }
15661                    }
15662                }
15663                Process.setSwappiness(app.pid,
15664                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15665            }
15666        }
15667        if (app.repForegroundActivities != app.foregroundActivities) {
15668            app.repForegroundActivities = app.foregroundActivities;
15669            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15670        }
15671        if (app.repProcState != app.curProcState) {
15672            app.repProcState = app.curProcState;
15673            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15674            if (app.thread != null) {
15675                try {
15676                    if (false) {
15677                        //RuntimeException h = new RuntimeException("here");
15678                        Slog.i(TAG, "Sending new process state " + app.repProcState
15679                                + " to " + app /*, h*/);
15680                    }
15681                    app.thread.setProcessState(app.repProcState);
15682                } catch (RemoteException e) {
15683                }
15684            }
15685        }
15686        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15687                app.setProcState)) {
15688            app.lastStateTime = now;
15689            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15690                    isSleeping(), now);
15691            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15692                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15693                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15694                    + (app.nextPssTime-now) + ": " + app);
15695        } else {
15696            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15697                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15698                requestPssLocked(app, app.setProcState);
15699                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15700                        isSleeping(), now);
15701            } else if (false && DEBUG_PSS) {
15702                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15703            }
15704        }
15705        if (app.setProcState != app.curProcState) {
15706            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15707                    "Proc state change of " + app.processName
15708                    + " to " + app.curProcState);
15709            app.setProcState = app.curProcState;
15710            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15711                app.notCachedSinceIdle = false;
15712            }
15713            if (!doingAll) {
15714                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15715            } else {
15716                app.procStateChanged = true;
15717            }
15718        }
15719
15720        if (changes != 0) {
15721            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15722            int i = mPendingProcessChanges.size()-1;
15723            ProcessChangeItem item = null;
15724            while (i >= 0) {
15725                item = mPendingProcessChanges.get(i);
15726                if (item.pid == app.pid) {
15727                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15728                    break;
15729                }
15730                i--;
15731            }
15732            if (i < 0) {
15733                // No existing item in pending changes; need a new one.
15734                final int NA = mAvailProcessChanges.size();
15735                if (NA > 0) {
15736                    item = mAvailProcessChanges.remove(NA-1);
15737                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15738                } else {
15739                    item = new ProcessChangeItem();
15740                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15741                }
15742                item.changes = 0;
15743                item.pid = app.pid;
15744                item.uid = app.info.uid;
15745                if (mPendingProcessChanges.size() == 0) {
15746                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15747                            "*** Enqueueing dispatch processes changed!");
15748                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15749                }
15750                mPendingProcessChanges.add(item);
15751            }
15752            item.changes |= changes;
15753            item.processState = app.repProcState;
15754            item.foregroundActivities = app.repForegroundActivities;
15755            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15756                    + Integer.toHexString(System.identityHashCode(item))
15757                    + " " + app.toShortString() + ": changes=" + item.changes
15758                    + " procState=" + item.processState
15759                    + " foreground=" + item.foregroundActivities
15760                    + " type=" + app.adjType + " source=" + app.adjSource
15761                    + " target=" + app.adjTarget);
15762        }
15763
15764        return success;
15765    }
15766
15767    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15768        if (proc.thread != null && proc.baseProcessTracker != null) {
15769            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15770        }
15771    }
15772
15773    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15774            ProcessRecord TOP_APP, boolean doingAll, long now) {
15775        if (app.thread == null) {
15776            return false;
15777        }
15778
15779        final boolean wasKeeping = app.keeping;
15780
15781        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15782
15783        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15784    }
15785
15786    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15787            boolean oomAdj) {
15788        if (isForeground != proc.foregroundServices) {
15789            proc.foregroundServices = isForeground;
15790            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15791                    proc.info.uid);
15792            if (isForeground) {
15793                if (curProcs == null) {
15794                    curProcs = new ArrayList<ProcessRecord>();
15795                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15796                }
15797                if (!curProcs.contains(proc)) {
15798                    curProcs.add(proc);
15799                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15800                            proc.info.packageName, proc.info.uid);
15801                }
15802            } else {
15803                if (curProcs != null) {
15804                    if (curProcs.remove(proc)) {
15805                        mBatteryStatsService.noteEvent(
15806                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15807                                proc.info.packageName, proc.info.uid);
15808                        if (curProcs.size() <= 0) {
15809                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15810                        }
15811                    }
15812                }
15813            }
15814            if (oomAdj) {
15815                updateOomAdjLocked();
15816            }
15817        }
15818    }
15819
15820    private final ActivityRecord resumedAppLocked() {
15821        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15822        String pkg;
15823        int uid;
15824        if (act != null && !act.sleeping) {
15825            pkg = act.packageName;
15826            uid = act.info.applicationInfo.uid;
15827        } else {
15828            pkg = null;
15829            uid = -1;
15830        }
15831        // Has the UID or resumed package name changed?
15832        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15833                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15834            if (mCurResumedPackage != null) {
15835                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15836                        mCurResumedPackage, mCurResumedUid);
15837            }
15838            mCurResumedPackage = pkg;
15839            mCurResumedUid = uid;
15840            if (mCurResumedPackage != null) {
15841                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15842                        mCurResumedPackage, mCurResumedUid);
15843            }
15844        }
15845        return act;
15846    }
15847
15848    final boolean updateOomAdjLocked(ProcessRecord app) {
15849        final ActivityRecord TOP_ACT = resumedAppLocked();
15850        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15851        final boolean wasCached = app.cached;
15852
15853        mAdjSeq++;
15854
15855        // This is the desired cached adjusment we want to tell it to use.
15856        // If our app is currently cached, we know it, and that is it.  Otherwise,
15857        // we don't know it yet, and it needs to now be cached we will then
15858        // need to do a complete oom adj.
15859        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15860                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15861        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15862                SystemClock.uptimeMillis());
15863        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15864            // Changed to/from cached state, so apps after it in the LRU
15865            // list may also be changed.
15866            updateOomAdjLocked();
15867        }
15868        return success;
15869    }
15870
15871    final void updateOomAdjLocked() {
15872        final ActivityRecord TOP_ACT = resumedAppLocked();
15873        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15874        final long now = SystemClock.uptimeMillis();
15875        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15876        final int N = mLruProcesses.size();
15877
15878        if (false) {
15879            RuntimeException e = new RuntimeException();
15880            e.fillInStackTrace();
15881            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15882        }
15883
15884        mAdjSeq++;
15885        mNewNumServiceProcs = 0;
15886        mNewNumAServiceProcs = 0;
15887
15888        final int emptyProcessLimit;
15889        final int cachedProcessLimit;
15890        if (mProcessLimit <= 0) {
15891            emptyProcessLimit = cachedProcessLimit = 0;
15892        } else if (mProcessLimit == 1) {
15893            emptyProcessLimit = 1;
15894            cachedProcessLimit = 0;
15895        } else {
15896            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15897            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15898        }
15899
15900        // Let's determine how many processes we have running vs.
15901        // how many slots we have for background processes; we may want
15902        // to put multiple processes in a slot of there are enough of
15903        // them.
15904        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15905                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15906        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15907        if (numEmptyProcs > cachedProcessLimit) {
15908            // If there are more empty processes than our limit on cached
15909            // processes, then use the cached process limit for the factor.
15910            // This ensures that the really old empty processes get pushed
15911            // down to the bottom, so if we are running low on memory we will
15912            // have a better chance at keeping around more cached processes
15913            // instead of a gazillion empty processes.
15914            numEmptyProcs = cachedProcessLimit;
15915        }
15916        int emptyFactor = numEmptyProcs/numSlots;
15917        if (emptyFactor < 1) emptyFactor = 1;
15918        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15919        if (cachedFactor < 1) cachedFactor = 1;
15920        int stepCached = 0;
15921        int stepEmpty = 0;
15922        int numCached = 0;
15923        int numEmpty = 0;
15924        int numTrimming = 0;
15925
15926        mNumNonCachedProcs = 0;
15927        mNumCachedHiddenProcs = 0;
15928
15929        // First update the OOM adjustment for each of the
15930        // application processes based on their current state.
15931        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15932        int nextCachedAdj = curCachedAdj+1;
15933        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15934        int nextEmptyAdj = curEmptyAdj+2;
15935        for (int i=N-1; i>=0; i--) {
15936            ProcessRecord app = mLruProcesses.get(i);
15937            if (!app.killedByAm && app.thread != null) {
15938                app.procStateChanged = false;
15939                final boolean wasKeeping = app.keeping;
15940                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15941
15942                // If we haven't yet assigned the final cached adj
15943                // to the process, do that now.
15944                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15945                    switch (app.curProcState) {
15946                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15947                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15948                            // This process is a cached process holding activities...
15949                            // assign it the next cached value for that type, and then
15950                            // step that cached level.
15951                            app.curRawAdj = curCachedAdj;
15952                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15953                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15954                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15955                                    + ")");
15956                            if (curCachedAdj != nextCachedAdj) {
15957                                stepCached++;
15958                                if (stepCached >= cachedFactor) {
15959                                    stepCached = 0;
15960                                    curCachedAdj = nextCachedAdj;
15961                                    nextCachedAdj += 2;
15962                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15963                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15964                                    }
15965                                }
15966                            }
15967                            break;
15968                        default:
15969                            // For everything else, assign next empty cached process
15970                            // level and bump that up.  Note that this means that
15971                            // long-running services that have dropped down to the
15972                            // cached level will be treated as empty (since their process
15973                            // state is still as a service), which is what we want.
15974                            app.curRawAdj = curEmptyAdj;
15975                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15976                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15977                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15978                                    + ")");
15979                            if (curEmptyAdj != nextEmptyAdj) {
15980                                stepEmpty++;
15981                                if (stepEmpty >= emptyFactor) {
15982                                    stepEmpty = 0;
15983                                    curEmptyAdj = nextEmptyAdj;
15984                                    nextEmptyAdj += 2;
15985                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15986                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15987                                    }
15988                                }
15989                            }
15990                            break;
15991                    }
15992                }
15993
15994                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15995
15996                // Count the number of process types.
15997                switch (app.curProcState) {
15998                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15999                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16000                        mNumCachedHiddenProcs++;
16001                        numCached++;
16002                        if (numCached > cachedProcessLimit) {
16003                            killUnneededProcessLocked(app, "cached #" + numCached);
16004                        }
16005                        break;
16006                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16007                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16008                                && app.lastActivityTime < oldTime) {
16009                            killUnneededProcessLocked(app, "empty for "
16010                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16011                                    / 1000) + "s");
16012                        } else {
16013                            numEmpty++;
16014                            if (numEmpty > emptyProcessLimit) {
16015                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16016                            }
16017                        }
16018                        break;
16019                    default:
16020                        mNumNonCachedProcs++;
16021                        break;
16022                }
16023
16024                if (app.isolated && app.services.size() <= 0) {
16025                    // If this is an isolated process, and there are no
16026                    // services running in it, then the process is no longer
16027                    // needed.  We agressively kill these because we can by
16028                    // definition not re-use the same process again, and it is
16029                    // good to avoid having whatever code was running in them
16030                    // left sitting around after no longer needed.
16031                    killUnneededProcessLocked(app, "isolated not needed");
16032                }
16033
16034                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16035                        && !app.killedByAm) {
16036                    numTrimming++;
16037                }
16038            }
16039        }
16040
16041        mNumServiceProcs = mNewNumServiceProcs;
16042
16043        // Now determine the memory trimming level of background processes.
16044        // Unfortunately we need to start at the back of the list to do this
16045        // properly.  We only do this if the number of background apps we
16046        // are managing to keep around is less than half the maximum we desire;
16047        // if we are keeping a good number around, we'll let them use whatever
16048        // memory they want.
16049        final int numCachedAndEmpty = numCached + numEmpty;
16050        int memFactor;
16051        if (numCached <= ProcessList.TRIM_CACHED_APPS
16052                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16053            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16054                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16055            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16056                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16057            } else {
16058                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16059            }
16060        } else {
16061            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16062        }
16063        // We always allow the memory level to go up (better).  We only allow it to go
16064        // down if we are in a state where that is allowed, *and* the total number of processes
16065        // has gone down since last time.
16066        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16067                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16068                + " last=" + mLastNumProcesses);
16069        if (memFactor > mLastMemoryLevel) {
16070            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16071                memFactor = mLastMemoryLevel;
16072                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16073            }
16074        }
16075        mLastMemoryLevel = memFactor;
16076        mLastNumProcesses = mLruProcesses.size();
16077        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16078        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16079        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16080            if (mLowRamStartTime == 0) {
16081                mLowRamStartTime = now;
16082            }
16083            int step = 0;
16084            int fgTrimLevel;
16085            switch (memFactor) {
16086                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16087                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16088                    break;
16089                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16090                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16091                    break;
16092                default:
16093                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16094                    break;
16095            }
16096            int factor = numTrimming/3;
16097            int minFactor = 2;
16098            if (mHomeProcess != null) minFactor++;
16099            if (mPreviousProcess != null) minFactor++;
16100            if (factor < minFactor) factor = minFactor;
16101            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16102            for (int i=N-1; i>=0; i--) {
16103                ProcessRecord app = mLruProcesses.get(i);
16104                if (allChanged || app.procStateChanged) {
16105                    setProcessTrackerState(app, trackerMemFactor, now);
16106                    app.procStateChanged = false;
16107                }
16108                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16109                        && !app.killedByAm) {
16110                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16111                        try {
16112                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16113                                    "Trimming memory of " + app.processName
16114                                    + " to " + curLevel);
16115                            app.thread.scheduleTrimMemory(curLevel);
16116                        } catch (RemoteException e) {
16117                        }
16118                        if (false) {
16119                            // For now we won't do this; our memory trimming seems
16120                            // to be good enough at this point that destroying
16121                            // activities causes more harm than good.
16122                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16123                                    && app != mHomeProcess && app != mPreviousProcess) {
16124                                // Need to do this on its own message because the stack may not
16125                                // be in a consistent state at this point.
16126                                // For these apps we will also finish their activities
16127                                // to help them free memory.
16128                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16129                            }
16130                        }
16131                    }
16132                    app.trimMemoryLevel = curLevel;
16133                    step++;
16134                    if (step >= factor) {
16135                        step = 0;
16136                        switch (curLevel) {
16137                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16138                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16139                                break;
16140                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16141                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16142                                break;
16143                        }
16144                    }
16145                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16146                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16147                            && app.thread != null) {
16148                        try {
16149                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16150                                    "Trimming memory of heavy-weight " + app.processName
16151                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16152                            app.thread.scheduleTrimMemory(
16153                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16154                        } catch (RemoteException e) {
16155                        }
16156                    }
16157                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16158                } else {
16159                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16160                            || app.systemNoUi) && app.pendingUiClean) {
16161                        // If this application is now in the background and it
16162                        // had done UI, then give it the special trim level to
16163                        // have it free UI resources.
16164                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16165                        if (app.trimMemoryLevel < level && app.thread != null) {
16166                            try {
16167                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16168                                        "Trimming memory of bg-ui " + app.processName
16169                                        + " to " + level);
16170                                app.thread.scheduleTrimMemory(level);
16171                            } catch (RemoteException e) {
16172                            }
16173                        }
16174                        app.pendingUiClean = false;
16175                    }
16176                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16177                        try {
16178                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16179                                    "Trimming memory of fg " + app.processName
16180                                    + " to " + fgTrimLevel);
16181                            app.thread.scheduleTrimMemory(fgTrimLevel);
16182                        } catch (RemoteException e) {
16183                        }
16184                    }
16185                    app.trimMemoryLevel = fgTrimLevel;
16186                }
16187            }
16188        } else {
16189            if (mLowRamStartTime != 0) {
16190                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16191                mLowRamStartTime = 0;
16192            }
16193            for (int i=N-1; i>=0; i--) {
16194                ProcessRecord app = mLruProcesses.get(i);
16195                if (allChanged || app.procStateChanged) {
16196                    setProcessTrackerState(app, trackerMemFactor, now);
16197                    app.procStateChanged = false;
16198                }
16199                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16200                        || app.systemNoUi) && app.pendingUiClean) {
16201                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16202                            && app.thread != null) {
16203                        try {
16204                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16205                                    "Trimming memory of ui hidden " + app.processName
16206                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16207                            app.thread.scheduleTrimMemory(
16208                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16209                        } catch (RemoteException e) {
16210                        }
16211                    }
16212                    app.pendingUiClean = false;
16213                }
16214                app.trimMemoryLevel = 0;
16215            }
16216        }
16217
16218        if (mAlwaysFinishActivities) {
16219            // Need to do this on its own message because the stack may not
16220            // be in a consistent state at this point.
16221            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16222        }
16223
16224        if (allChanged) {
16225            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16226        }
16227
16228        if (mProcessStats.shouldWriteNowLocked(now)) {
16229            mHandler.post(new Runnable() {
16230                @Override public void run() {
16231                    synchronized (ActivityManagerService.this) {
16232                        mProcessStats.writeStateAsyncLocked();
16233                    }
16234                }
16235            });
16236        }
16237
16238        if (DEBUG_OOM_ADJ) {
16239            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16240        }
16241    }
16242
16243    final void trimApplications() {
16244        synchronized (this) {
16245            int i;
16246
16247            // First remove any unused application processes whose package
16248            // has been removed.
16249            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16250                final ProcessRecord app = mRemovedProcesses.get(i);
16251                if (app.activities.size() == 0
16252                        && app.curReceiver == null && app.services.size() == 0) {
16253                    Slog.i(
16254                        TAG, "Exiting empty application process "
16255                        + app.processName + " ("
16256                        + (app.thread != null ? app.thread.asBinder() : null)
16257                        + ")\n");
16258                    if (app.pid > 0 && app.pid != MY_PID) {
16259                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16260                                app.processName, app.setAdj, "empty");
16261                        app.killedByAm = true;
16262                        Process.killProcessQuiet(app.pid);
16263                    } else {
16264                        try {
16265                            app.thread.scheduleExit();
16266                        } catch (Exception e) {
16267                            // Ignore exceptions.
16268                        }
16269                    }
16270                    cleanUpApplicationRecordLocked(app, false, true, -1);
16271                    mRemovedProcesses.remove(i);
16272
16273                    if (app.persistent) {
16274                        if (app.persistent) {
16275                            addAppLocked(app.info, false);
16276                        }
16277                    }
16278                }
16279            }
16280
16281            // Now update the oom adj for all processes.
16282            updateOomAdjLocked();
16283        }
16284    }
16285
16286    /** This method sends the specified signal to each of the persistent apps */
16287    public void signalPersistentProcesses(int sig) throws RemoteException {
16288        if (sig != Process.SIGNAL_USR1) {
16289            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16290        }
16291
16292        synchronized (this) {
16293            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16294                    != PackageManager.PERMISSION_GRANTED) {
16295                throw new SecurityException("Requires permission "
16296                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16297            }
16298
16299            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16300                ProcessRecord r = mLruProcesses.get(i);
16301                if (r.thread != null && r.persistent) {
16302                    Process.sendSignal(r.pid, sig);
16303                }
16304            }
16305        }
16306    }
16307
16308    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16309        if (proc == null || proc == mProfileProc) {
16310            proc = mProfileProc;
16311            path = mProfileFile;
16312            profileType = mProfileType;
16313            clearProfilerLocked();
16314        }
16315        if (proc == null) {
16316            return;
16317        }
16318        try {
16319            proc.thread.profilerControl(false, path, null, profileType);
16320        } catch (RemoteException e) {
16321            throw new IllegalStateException("Process disappeared");
16322        }
16323    }
16324
16325    private void clearProfilerLocked() {
16326        if (mProfileFd != null) {
16327            try {
16328                mProfileFd.close();
16329            } catch (IOException e) {
16330            }
16331        }
16332        mProfileApp = null;
16333        mProfileProc = null;
16334        mProfileFile = null;
16335        mProfileType = 0;
16336        mAutoStopProfiler = false;
16337    }
16338
16339    public boolean profileControl(String process, int userId, boolean start,
16340            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16341
16342        try {
16343            synchronized (this) {
16344                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16345                // its own permission.
16346                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16347                        != PackageManager.PERMISSION_GRANTED) {
16348                    throw new SecurityException("Requires permission "
16349                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16350                }
16351
16352                if (start && fd == null) {
16353                    throw new IllegalArgumentException("null fd");
16354                }
16355
16356                ProcessRecord proc = null;
16357                if (process != null) {
16358                    proc = findProcessLocked(process, userId, "profileControl");
16359                }
16360
16361                if (start && (proc == null || proc.thread == null)) {
16362                    throw new IllegalArgumentException("Unknown process: " + process);
16363                }
16364
16365                if (start) {
16366                    stopProfilerLocked(null, null, 0);
16367                    setProfileApp(proc.info, proc.processName, path, fd, false);
16368                    mProfileProc = proc;
16369                    mProfileType = profileType;
16370                    try {
16371                        fd = fd.dup();
16372                    } catch (IOException e) {
16373                        fd = null;
16374                    }
16375                    proc.thread.profilerControl(start, path, fd, profileType);
16376                    fd = null;
16377                    mProfileFd = null;
16378                } else {
16379                    stopProfilerLocked(proc, path, profileType);
16380                    if (fd != null) {
16381                        try {
16382                            fd.close();
16383                        } catch (IOException e) {
16384                        }
16385                    }
16386                }
16387
16388                return true;
16389            }
16390        } catch (RemoteException e) {
16391            throw new IllegalStateException("Process disappeared");
16392        } finally {
16393            if (fd != null) {
16394                try {
16395                    fd.close();
16396                } catch (IOException e) {
16397                }
16398            }
16399        }
16400    }
16401
16402    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16403        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16404                userId, true, true, callName, null);
16405        ProcessRecord proc = null;
16406        try {
16407            int pid = Integer.parseInt(process);
16408            synchronized (mPidsSelfLocked) {
16409                proc = mPidsSelfLocked.get(pid);
16410            }
16411        } catch (NumberFormatException e) {
16412        }
16413
16414        if (proc == null) {
16415            ArrayMap<String, SparseArray<ProcessRecord>> all
16416                    = mProcessNames.getMap();
16417            SparseArray<ProcessRecord> procs = all.get(process);
16418            if (procs != null && procs.size() > 0) {
16419                proc = procs.valueAt(0);
16420                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16421                    for (int i=1; i<procs.size(); i++) {
16422                        ProcessRecord thisProc = procs.valueAt(i);
16423                        if (thisProc.userId == userId) {
16424                            proc = thisProc;
16425                            break;
16426                        }
16427                    }
16428                }
16429            }
16430        }
16431
16432        return proc;
16433    }
16434
16435    public boolean dumpHeap(String process, int userId, boolean managed,
16436            String path, ParcelFileDescriptor fd) throws RemoteException {
16437
16438        try {
16439            synchronized (this) {
16440                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16441                // its own permission (same as profileControl).
16442                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16443                        != PackageManager.PERMISSION_GRANTED) {
16444                    throw new SecurityException("Requires permission "
16445                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16446                }
16447
16448                if (fd == null) {
16449                    throw new IllegalArgumentException("null fd");
16450                }
16451
16452                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16453                if (proc == null || proc.thread == null) {
16454                    throw new IllegalArgumentException("Unknown process: " + process);
16455                }
16456
16457                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16458                if (!isDebuggable) {
16459                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16460                        throw new SecurityException("Process not debuggable: " + proc);
16461                    }
16462                }
16463
16464                proc.thread.dumpHeap(managed, path, fd);
16465                fd = null;
16466                return true;
16467            }
16468        } catch (RemoteException e) {
16469            throw new IllegalStateException("Process disappeared");
16470        } finally {
16471            if (fd != null) {
16472                try {
16473                    fd.close();
16474                } catch (IOException e) {
16475                }
16476            }
16477        }
16478    }
16479
16480    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16481    public void monitor() {
16482        synchronized (this) { }
16483    }
16484
16485    void onCoreSettingsChange(Bundle settings) {
16486        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16487            ProcessRecord processRecord = mLruProcesses.get(i);
16488            try {
16489                if (processRecord.thread != null) {
16490                    processRecord.thread.setCoreSettings(settings);
16491                }
16492            } catch (RemoteException re) {
16493                /* ignore */
16494            }
16495        }
16496    }
16497
16498    // Multi-user methods
16499
16500    /**
16501     * Start user, if its not already running, but don't bring it to foreground.
16502     */
16503    @Override
16504    public boolean startUserInBackground(final int userId) {
16505        return startUser(userId, /* foreground */ false);
16506    }
16507
16508    /**
16509     * Refreshes the list of users related to the current user when either a
16510     * user switch happens or when a new related user is started in the
16511     * background.
16512     */
16513    private void updateCurrentProfileIdsLocked() {
16514        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16515                mCurrentUserId, false /* enabledOnly */);
16516        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16517        for (int i = 0; i < currentProfileIds.length; i++) {
16518            currentProfileIds[i] = profiles.get(i).id;
16519        }
16520        mCurrentProfileIds = currentProfileIds;
16521    }
16522
16523    private Set getProfileIdsLocked(int userId) {
16524        Set userIds = new HashSet<Integer>();
16525        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16526                userId, false /* enabledOnly */);
16527        for (UserInfo user : profiles) {
16528            userIds.add(Integer.valueOf(user.id));
16529        }
16530        return userIds;
16531    }
16532
16533    @Override
16534    public boolean switchUser(final int userId) {
16535        return startUser(userId, /* foregound */ true);
16536    }
16537
16538    private boolean startUser(final int userId, boolean foreground) {
16539        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16540                != PackageManager.PERMISSION_GRANTED) {
16541            String msg = "Permission Denial: switchUser() from pid="
16542                    + Binder.getCallingPid()
16543                    + ", uid=" + Binder.getCallingUid()
16544                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16545            Slog.w(TAG, msg);
16546            throw new SecurityException(msg);
16547        }
16548
16549        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16550
16551        final long ident = Binder.clearCallingIdentity();
16552        try {
16553            synchronized (this) {
16554                final int oldUserId = mCurrentUserId;
16555                if (oldUserId == userId) {
16556                    return true;
16557                }
16558
16559                mStackSupervisor.setLockTaskModeLocked(null);
16560
16561                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16562                if (userInfo == null) {
16563                    Slog.w(TAG, "No user info for user #" + userId);
16564                    return false;
16565                }
16566
16567                if (foreground) {
16568                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16569                            R.anim.screen_user_enter);
16570                }
16571
16572                boolean needStart = false;
16573
16574                // If the user we are switching to is not currently started, then
16575                // we need to start it now.
16576                if (mStartedUsers.get(userId) == null) {
16577                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16578                    updateStartedUserArrayLocked();
16579                    needStart = true;
16580                }
16581
16582                final Integer userIdInt = Integer.valueOf(userId);
16583                mUserLru.remove(userIdInt);
16584                mUserLru.add(userIdInt);
16585
16586                if (foreground) {
16587                    mCurrentUserId = userId;
16588                    updateCurrentProfileIdsLocked();
16589                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16590                    // Once the internal notion of the active user has switched, we lock the device
16591                    // with the option to show the user switcher on the keyguard.
16592                    mWindowManager.lockNow(null);
16593                } else {
16594                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16595                    updateCurrentProfileIdsLocked();
16596                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16597                    mUserLru.remove(currentUserIdInt);
16598                    mUserLru.add(currentUserIdInt);
16599                }
16600
16601                final UserStartedState uss = mStartedUsers.get(userId);
16602
16603                // Make sure user is in the started state.  If it is currently
16604                // stopping, we need to knock that off.
16605                if (uss.mState == UserStartedState.STATE_STOPPING) {
16606                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16607                    // so we can just fairly silently bring the user back from
16608                    // the almost-dead.
16609                    uss.mState = UserStartedState.STATE_RUNNING;
16610                    updateStartedUserArrayLocked();
16611                    needStart = true;
16612                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16613                    // This means ACTION_SHUTDOWN has been sent, so we will
16614                    // need to treat this as a new boot of the user.
16615                    uss.mState = UserStartedState.STATE_BOOTING;
16616                    updateStartedUserArrayLocked();
16617                    needStart = true;
16618                }
16619
16620                if (uss.mState == UserStartedState.STATE_BOOTING) {
16621                    // Booting up a new user, need to tell system services about it.
16622                    // Note that this is on the same handler as scheduling of broadcasts,
16623                    // which is important because it needs to go first.
16624                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16625                }
16626
16627                if (foreground) {
16628                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16629                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16630                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16631                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16632                            oldUserId, userId, uss));
16633                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16634                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16635                }
16636
16637                if (needStart) {
16638                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16639                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16640                            | Intent.FLAG_RECEIVER_FOREGROUND);
16641                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16642                    broadcastIntentLocked(null, null, intent,
16643                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16644                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16645                }
16646
16647                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16648                    if (userId != UserHandle.USER_OWNER) {
16649                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16650                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16651                        broadcastIntentLocked(null, null, intent, null,
16652                                new IIntentReceiver.Stub() {
16653                                    public void performReceive(Intent intent, int resultCode,
16654                                            String data, Bundle extras, boolean ordered,
16655                                            boolean sticky, int sendingUser) {
16656                                        userInitialized(uss, userId);
16657                                    }
16658                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16659                                true, false, MY_PID, Process.SYSTEM_UID,
16660                                userId);
16661                        uss.initializing = true;
16662                    } else {
16663                        getUserManagerLocked().makeInitialized(userInfo.id);
16664                    }
16665                }
16666
16667                if (foreground) {
16668                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16669                    if (homeInFront) {
16670                        startHomeActivityLocked(userId);
16671                    } else {
16672                        mStackSupervisor.resumeTopActivitiesLocked();
16673                    }
16674                    EventLogTags.writeAmSwitchUser(userId);
16675                    getUserManagerLocked().userForeground(userId);
16676                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16677                } else {
16678                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16679                }
16680
16681                if (needStart) {
16682                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16683                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16684                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16685                    broadcastIntentLocked(null, null, intent,
16686                            null, new IIntentReceiver.Stub() {
16687                                @Override
16688                                public void performReceive(Intent intent, int resultCode, String data,
16689                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16690                                        throws RemoteException {
16691                                }
16692                            }, 0, null, null,
16693                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16694                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16695                }
16696            }
16697        } finally {
16698            Binder.restoreCallingIdentity(ident);
16699        }
16700
16701        return true;
16702    }
16703
16704    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16705        long ident = Binder.clearCallingIdentity();
16706        try {
16707            Intent intent;
16708            if (oldUserId >= 0) {
16709                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16710                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16711                        | Intent.FLAG_RECEIVER_FOREGROUND);
16712                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16713                broadcastIntentLocked(null, null, intent,
16714                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16715                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16716            }
16717            if (newUserId >= 0) {
16718                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16719                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16720                        | Intent.FLAG_RECEIVER_FOREGROUND);
16721                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16722                broadcastIntentLocked(null, null, intent,
16723                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16724                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16725                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16726                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16727                        | Intent.FLAG_RECEIVER_FOREGROUND);
16728                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16729                broadcastIntentLocked(null, null, intent,
16730                        null, null, 0, null, null,
16731                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16732                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16733            }
16734        } finally {
16735            Binder.restoreCallingIdentity(ident);
16736        }
16737    }
16738
16739    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16740            final int newUserId) {
16741        final int N = mUserSwitchObservers.beginBroadcast();
16742        if (N > 0) {
16743            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16744                int mCount = 0;
16745                @Override
16746                public void sendResult(Bundle data) throws RemoteException {
16747                    synchronized (ActivityManagerService.this) {
16748                        if (mCurUserSwitchCallback == this) {
16749                            mCount++;
16750                            if (mCount == N) {
16751                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16752                            }
16753                        }
16754                    }
16755                }
16756            };
16757            synchronized (this) {
16758                uss.switching = true;
16759                mCurUserSwitchCallback = callback;
16760            }
16761            for (int i=0; i<N; i++) {
16762                try {
16763                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16764                            newUserId, callback);
16765                } catch (RemoteException e) {
16766                }
16767            }
16768        } else {
16769            synchronized (this) {
16770                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16771            }
16772        }
16773        mUserSwitchObservers.finishBroadcast();
16774    }
16775
16776    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16777        synchronized (this) {
16778            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16779            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16780        }
16781    }
16782
16783    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16784        mCurUserSwitchCallback = null;
16785        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16786        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16787                oldUserId, newUserId, uss));
16788    }
16789
16790    void userInitialized(UserStartedState uss, int newUserId) {
16791        completeSwitchAndInitalize(uss, newUserId, true, false);
16792    }
16793
16794    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16795        completeSwitchAndInitalize(uss, newUserId, false, true);
16796    }
16797
16798    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16799            boolean clearInitializing, boolean clearSwitching) {
16800        boolean unfrozen = false;
16801        synchronized (this) {
16802            if (clearInitializing) {
16803                uss.initializing = false;
16804                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16805            }
16806            if (clearSwitching) {
16807                uss.switching = false;
16808            }
16809            if (!uss.switching && !uss.initializing) {
16810                mWindowManager.stopFreezingScreen();
16811                unfrozen = true;
16812            }
16813        }
16814        if (unfrozen) {
16815            final int N = mUserSwitchObservers.beginBroadcast();
16816            for (int i=0; i<N; i++) {
16817                try {
16818                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16819                } catch (RemoteException e) {
16820                }
16821            }
16822            mUserSwitchObservers.finishBroadcast();
16823        }
16824    }
16825
16826    void scheduleStartProfilesLocked() {
16827        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16828            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16829                    DateUtils.SECOND_IN_MILLIS);
16830        }
16831    }
16832
16833    void startProfilesLocked() {
16834        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16835        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16836                mCurrentUserId, false /* enabledOnly */);
16837        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16838        for (UserInfo user : profiles) {
16839            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16840                    && user.id != mCurrentUserId) {
16841                toStart.add(user);
16842            }
16843        }
16844        final int n = toStart.size();
16845        int i = 0;
16846        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16847            startUserInBackground(toStart.get(i).id);
16848        }
16849        if (i < n) {
16850            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16851        }
16852    }
16853
16854    void finishUserBoot(UserStartedState uss) {
16855        synchronized (this) {
16856            if (uss.mState == UserStartedState.STATE_BOOTING
16857                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16858                uss.mState = UserStartedState.STATE_RUNNING;
16859                final int userId = uss.mHandle.getIdentifier();
16860                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16861                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16862                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16863                broadcastIntentLocked(null, null, intent,
16864                        null, null, 0, null, null,
16865                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16866                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16867            }
16868        }
16869    }
16870
16871    void finishUserSwitch(UserStartedState uss) {
16872        synchronized (this) {
16873            finishUserBoot(uss);
16874
16875            startProfilesLocked();
16876
16877            int num = mUserLru.size();
16878            int i = 0;
16879            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16880                Integer oldUserId = mUserLru.get(i);
16881                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16882                if (oldUss == null) {
16883                    // Shouldn't happen, but be sane if it does.
16884                    mUserLru.remove(i);
16885                    num--;
16886                    continue;
16887                }
16888                if (oldUss.mState == UserStartedState.STATE_STOPPING
16889                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16890                    // This user is already stopping, doesn't count.
16891                    num--;
16892                    i++;
16893                    continue;
16894                }
16895                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16896                    // Owner and current can't be stopped, but count as running.
16897                    i++;
16898                    continue;
16899                }
16900                // This is a user to be stopped.
16901                stopUserLocked(oldUserId, null);
16902                num--;
16903                i++;
16904            }
16905        }
16906    }
16907
16908    @Override
16909    public int stopUser(final int userId, final IStopUserCallback callback) {
16910        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16911                != PackageManager.PERMISSION_GRANTED) {
16912            String msg = "Permission Denial: switchUser() from pid="
16913                    + Binder.getCallingPid()
16914                    + ", uid=" + Binder.getCallingUid()
16915                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16916            Slog.w(TAG, msg);
16917            throw new SecurityException(msg);
16918        }
16919        if (userId <= 0) {
16920            throw new IllegalArgumentException("Can't stop primary user " + userId);
16921        }
16922        synchronized (this) {
16923            return stopUserLocked(userId, callback);
16924        }
16925    }
16926
16927    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16928        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16929        if (mCurrentUserId == userId) {
16930            return ActivityManager.USER_OP_IS_CURRENT;
16931        }
16932
16933        final UserStartedState uss = mStartedUsers.get(userId);
16934        if (uss == null) {
16935            // User is not started, nothing to do...  but we do need to
16936            // callback if requested.
16937            if (callback != null) {
16938                mHandler.post(new Runnable() {
16939                    @Override
16940                    public void run() {
16941                        try {
16942                            callback.userStopped(userId);
16943                        } catch (RemoteException e) {
16944                        }
16945                    }
16946                });
16947            }
16948            return ActivityManager.USER_OP_SUCCESS;
16949        }
16950
16951        if (callback != null) {
16952            uss.mStopCallbacks.add(callback);
16953        }
16954
16955        if (uss.mState != UserStartedState.STATE_STOPPING
16956                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16957            uss.mState = UserStartedState.STATE_STOPPING;
16958            updateStartedUserArrayLocked();
16959
16960            long ident = Binder.clearCallingIdentity();
16961            try {
16962                // We are going to broadcast ACTION_USER_STOPPING and then
16963                // once that is done send a final ACTION_SHUTDOWN and then
16964                // stop the user.
16965                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16966                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16967                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16968                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16969                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16970                // This is the result receiver for the final shutdown broadcast.
16971                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16972                    @Override
16973                    public void performReceive(Intent intent, int resultCode, String data,
16974                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16975                        finishUserStop(uss);
16976                    }
16977                };
16978                // This is the result receiver for the initial stopping broadcast.
16979                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16980                    @Override
16981                    public void performReceive(Intent intent, int resultCode, String data,
16982                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16983                        // On to the next.
16984                        synchronized (ActivityManagerService.this) {
16985                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16986                                // Whoops, we are being started back up.  Abort, abort!
16987                                return;
16988                            }
16989                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16990                        }
16991                        mSystemServiceManager.stopUser(userId);
16992                        broadcastIntentLocked(null, null, shutdownIntent,
16993                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16994                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16995                    }
16996                };
16997                // Kick things off.
16998                broadcastIntentLocked(null, null, stoppingIntent,
16999                        null, stoppingReceiver, 0, null, null,
17000                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17001                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17002            } finally {
17003                Binder.restoreCallingIdentity(ident);
17004            }
17005        }
17006
17007        return ActivityManager.USER_OP_SUCCESS;
17008    }
17009
17010    void finishUserStop(UserStartedState uss) {
17011        final int userId = uss.mHandle.getIdentifier();
17012        boolean stopped;
17013        ArrayList<IStopUserCallback> callbacks;
17014        synchronized (this) {
17015            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17016            if (mStartedUsers.get(userId) != uss) {
17017                stopped = false;
17018            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17019                stopped = false;
17020            } else {
17021                stopped = true;
17022                // User can no longer run.
17023                mStartedUsers.remove(userId);
17024                mUserLru.remove(Integer.valueOf(userId));
17025                updateStartedUserArrayLocked();
17026
17027                // Clean up all state and processes associated with the user.
17028                // Kill all the processes for the user.
17029                forceStopUserLocked(userId, "finish user");
17030            }
17031        }
17032
17033        for (int i=0; i<callbacks.size(); i++) {
17034            try {
17035                if (stopped) callbacks.get(i).userStopped(userId);
17036                else callbacks.get(i).userStopAborted(userId);
17037            } catch (RemoteException e) {
17038            }
17039        }
17040
17041        if (stopped) {
17042            mSystemServiceManager.cleanupUser(userId);
17043            synchronized (this) {
17044                mStackSupervisor.removeUserLocked(userId);
17045            }
17046        }
17047    }
17048
17049    @Override
17050    public UserInfo getCurrentUser() {
17051        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17052                != PackageManager.PERMISSION_GRANTED) && (
17053                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17054                != PackageManager.PERMISSION_GRANTED)) {
17055            String msg = "Permission Denial: getCurrentUser() from pid="
17056                    + Binder.getCallingPid()
17057                    + ", uid=" + Binder.getCallingUid()
17058                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17059            Slog.w(TAG, msg);
17060            throw new SecurityException(msg);
17061        }
17062        synchronized (this) {
17063            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17064        }
17065    }
17066
17067    int getCurrentUserIdLocked() {
17068        return mCurrentUserId;
17069    }
17070
17071    @Override
17072    public boolean isUserRunning(int userId, boolean orStopped) {
17073        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17074                != PackageManager.PERMISSION_GRANTED) {
17075            String msg = "Permission Denial: isUserRunning() from pid="
17076                    + Binder.getCallingPid()
17077                    + ", uid=" + Binder.getCallingUid()
17078                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17079            Slog.w(TAG, msg);
17080            throw new SecurityException(msg);
17081        }
17082        synchronized (this) {
17083            return isUserRunningLocked(userId, orStopped);
17084        }
17085    }
17086
17087    boolean isUserRunningLocked(int userId, boolean orStopped) {
17088        UserStartedState state = mStartedUsers.get(userId);
17089        if (state == null) {
17090            return false;
17091        }
17092        if (orStopped) {
17093            return true;
17094        }
17095        return state.mState != UserStartedState.STATE_STOPPING
17096                && state.mState != UserStartedState.STATE_SHUTDOWN;
17097    }
17098
17099    @Override
17100    public int[] getRunningUserIds() {
17101        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17102                != PackageManager.PERMISSION_GRANTED) {
17103            String msg = "Permission Denial: isUserRunning() from pid="
17104                    + Binder.getCallingPid()
17105                    + ", uid=" + Binder.getCallingUid()
17106                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17107            Slog.w(TAG, msg);
17108            throw new SecurityException(msg);
17109        }
17110        synchronized (this) {
17111            return mStartedUserArray;
17112        }
17113    }
17114
17115    private void updateStartedUserArrayLocked() {
17116        int num = 0;
17117        for (int i=0; i<mStartedUsers.size();  i++) {
17118            UserStartedState uss = mStartedUsers.valueAt(i);
17119            // This list does not include stopping users.
17120            if (uss.mState != UserStartedState.STATE_STOPPING
17121                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17122                num++;
17123            }
17124        }
17125        mStartedUserArray = new int[num];
17126        num = 0;
17127        for (int i=0; i<mStartedUsers.size();  i++) {
17128            UserStartedState uss = mStartedUsers.valueAt(i);
17129            if (uss.mState != UserStartedState.STATE_STOPPING
17130                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17131                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17132                num++;
17133            }
17134        }
17135    }
17136
17137    @Override
17138    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17139        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17140                != PackageManager.PERMISSION_GRANTED) {
17141            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17142                    + Binder.getCallingPid()
17143                    + ", uid=" + Binder.getCallingUid()
17144                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17145            Slog.w(TAG, msg);
17146            throw new SecurityException(msg);
17147        }
17148
17149        mUserSwitchObservers.register(observer);
17150    }
17151
17152    @Override
17153    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17154        mUserSwitchObservers.unregister(observer);
17155    }
17156
17157    private boolean userExists(int userId) {
17158        if (userId == 0) {
17159            return true;
17160        }
17161        UserManagerService ums = getUserManagerLocked();
17162        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17163    }
17164
17165    int[] getUsersLocked() {
17166        UserManagerService ums = getUserManagerLocked();
17167        return ums != null ? ums.getUserIds() : new int[] { 0 };
17168    }
17169
17170    UserManagerService getUserManagerLocked() {
17171        if (mUserManager == null) {
17172            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17173            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17174        }
17175        return mUserManager;
17176    }
17177
17178    private int applyUserId(int uid, int userId) {
17179        return UserHandle.getUid(userId, uid);
17180    }
17181
17182    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17183        if (info == null) return null;
17184        ApplicationInfo newInfo = new ApplicationInfo(info);
17185        newInfo.uid = applyUserId(info.uid, userId);
17186        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17187                + info.packageName;
17188        return newInfo;
17189    }
17190
17191    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17192        if (aInfo == null
17193                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17194            return aInfo;
17195        }
17196
17197        ActivityInfo info = new ActivityInfo(aInfo);
17198        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17199        return info;
17200    }
17201
17202    private final class LocalService extends ActivityManagerInternal {
17203        @Override
17204        public void goingToSleep() {
17205            ActivityManagerService.this.goingToSleep();
17206        }
17207
17208        @Override
17209        public void wakingUp() {
17210            ActivityManagerService.this.wakingUp();
17211        }
17212    }
17213
17214    /**
17215     * An implementation of IAppTask, that allows an app to manage its own tasks via
17216     * {@link android.app.ActivityManager#AppTask}.  We keep track of the callingUid to ensure that
17217     * only the process that calls getAppTasks() can call the AppTask methods.
17218     */
17219    class AppTaskImpl extends IAppTask.Stub {
17220        private int mTaskId;
17221        private int mCallingUid;
17222
17223        public AppTaskImpl(int taskId, int callingUid) {
17224            mTaskId = taskId;
17225            mCallingUid = callingUid;
17226        }
17227
17228        @Override
17229        public void finishAndRemoveTask() {
17230            // Ensure that we are called from the same process that created this AppTask
17231            if (mCallingUid != Binder.getCallingUid()) {
17232                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17233                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17234                return;
17235            }
17236
17237            synchronized (ActivityManagerService.this) {
17238                long origId = Binder.clearCallingIdentity();
17239                try {
17240                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17241                    if (tr != null) {
17242                        // Only kill the process if we are not a new document
17243                        int flags = tr.getBaseIntent().getFlags();
17244                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17245                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17246                        removeTaskByIdLocked(mTaskId,
17247                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17248                    }
17249                } finally {
17250                    Binder.restoreCallingIdentity(origId);
17251                }
17252            }
17253        }
17254
17255        @Override
17256        public ActivityManager.RecentTaskInfo getTaskInfo() {
17257            // Ensure that we are called from the same process that created this AppTask
17258            if (mCallingUid != Binder.getCallingUid()) {
17259                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17260                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17261                return null;
17262            }
17263
17264            synchronized (ActivityManagerService.this) {
17265                long origId = Binder.clearCallingIdentity();
17266                try {
17267                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17268                    if (tr != null) {
17269                        return createRecentTaskInfoFromTaskRecord(tr);
17270                    }
17271                } finally {
17272                    Binder.restoreCallingIdentity(origId);
17273                }
17274                return null;
17275            }
17276        }
17277    }
17278}
17279