ActivityManagerService.java revision e22b3b143240f0f18e3d6d3c06686ad3c23b131b
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.appwidget.AppWidgetManager;
36import android.graphics.Rect;
37import android.os.BatteryStats;
38import android.service.voice.IVoiceInteractionSession;
39import android.util.ArrayMap;
40
41import com.android.internal.R;
42import com.android.internal.annotations.GuardedBy;
43import com.android.internal.app.IAppOpsService;
44import com.android.internal.app.IVoiceInteractor;
45import com.android.internal.app.ProcessMap;
46import com.android.internal.app.ProcessStats;
47import com.android.internal.content.PackageMonitor;
48import com.android.internal.os.BackgroundThread;
49import com.android.internal.os.BatteryStatsImpl;
50import com.android.internal.os.ProcessCpuTracker;
51import com.android.internal.os.TransferPipe;
52import com.android.internal.os.Zygote;
53import com.android.internal.util.FastPrintWriter;
54import com.android.internal.util.FastXmlSerializer;
55import com.android.internal.util.MemInfoReader;
56import com.android.internal.util.Preconditions;
57import com.android.server.AppOpsService;
58import com.android.server.AttributeCache;
59import com.android.server.IntentResolver;
60import com.android.server.LocalServices;
61import com.android.server.ServiceThread;
62import com.android.server.SystemService;
63import com.android.server.SystemServiceManager;
64import com.android.server.Watchdog;
65import com.android.server.am.ActivityStack.ActivityState;
66import com.android.server.firewall.IntentFirewall;
67import com.android.server.pm.UserManagerService;
68import com.android.server.wm.AppTransition;
69import com.android.server.wm.WindowManagerService;
70import com.google.android.collect.Lists;
71import com.google.android.collect.Maps;
72
73import libcore.io.IoUtils;
74
75import org.xmlpull.v1.XmlPullParser;
76import org.xmlpull.v1.XmlPullParserException;
77import org.xmlpull.v1.XmlSerializer;
78
79import android.app.Activity;
80import android.app.ActivityManager;
81import android.app.ActivityManager.RunningTaskInfo;
82import android.app.ActivityManager.StackInfo;
83import android.app.ActivityManagerInternal;
84import android.app.ActivityManagerNative;
85import android.app.ActivityOptions;
86import android.app.ActivityThread;
87import android.app.AlertDialog;
88import android.app.AppGlobals;
89import android.app.ApplicationErrorReport;
90import android.app.Dialog;
91import android.app.IActivityController;
92import android.app.IApplicationThread;
93import android.app.IInstrumentationWatcher;
94import android.app.INotificationManager;
95import android.app.IProcessObserver;
96import android.app.IServiceConnection;
97import android.app.IStopUserCallback;
98import android.app.IUiAutomationConnection;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.backup.IBackupManager;
105import android.content.ActivityNotFoundException;
106import android.content.BroadcastReceiver;
107import android.content.ClipData;
108import android.content.ComponentCallbacks2;
109import android.content.ComponentName;
110import android.content.ContentProvider;
111import android.content.ContentResolver;
112import android.content.Context;
113import android.content.DialogInterface;
114import android.content.IContentProvider;
115import android.content.IIntentReceiver;
116import android.content.IIntentSender;
117import android.content.Intent;
118import android.content.IntentFilter;
119import android.content.IntentSender;
120import android.content.pm.ActivityInfo;
121import android.content.pm.ApplicationInfo;
122import android.content.pm.ConfigurationInfo;
123import android.content.pm.IPackageDataObserver;
124import android.content.pm.IPackageManager;
125import android.content.pm.InstrumentationInfo;
126import android.content.pm.PackageInfo;
127import android.content.pm.PackageManager;
128import android.content.pm.ParceledListSlice;
129import android.content.pm.UserInfo;
130import android.content.pm.PackageManager.NameNotFoundException;
131import android.content.pm.PathPermission;
132import android.content.pm.ProviderInfo;
133import android.content.pm.ResolveInfo;
134import android.content.pm.ServiceInfo;
135import android.content.res.CompatibilityInfo;
136import android.content.res.Configuration;
137import android.graphics.Bitmap;
138import android.net.Proxy;
139import android.net.ProxyInfo;
140import android.net.Uri;
141import android.os.Binder;
142import android.os.Build;
143import android.os.Bundle;
144import android.os.Debug;
145import android.os.DropBoxManager;
146import android.os.Environment;
147import android.os.FactoryTest;
148import android.os.FileObserver;
149import android.os.FileUtils;
150import android.os.Handler;
151import android.os.IBinder;
152import android.os.IPermissionController;
153import android.os.IRemoteCallback;
154import android.os.IUserManager;
155import android.os.Looper;
156import android.os.Message;
157import android.os.Parcel;
158import android.os.ParcelFileDescriptor;
159import android.os.Process;
160import android.os.RemoteCallbackList;
161import android.os.RemoteException;
162import android.os.SELinux;
163import android.os.ServiceManager;
164import android.os.StrictMode;
165import android.os.SystemClock;
166import android.os.SystemProperties;
167import android.os.UpdateLock;
168import android.os.UserHandle;
169import android.provider.Settings;
170import android.text.format.DateUtils;
171import android.text.format.Time;
172import android.util.AtomicFile;
173import android.util.EventLog;
174import android.util.Log;
175import android.util.Pair;
176import android.util.PrintWriterPrinter;
177import android.util.Slog;
178import android.util.SparseArray;
179import android.util.TimeUtils;
180import android.util.Xml;
181import android.view.Gravity;
182import android.view.LayoutInflater;
183import android.view.View;
184import android.view.WindowManager;
185
186import java.io.BufferedInputStream;
187import java.io.BufferedOutputStream;
188import java.io.DataInputStream;
189import java.io.DataOutputStream;
190import java.io.File;
191import java.io.FileDescriptor;
192import java.io.FileInputStream;
193import java.io.FileNotFoundException;
194import java.io.FileOutputStream;
195import java.io.IOException;
196import java.io.InputStreamReader;
197import java.io.PrintWriter;
198import java.io.StringWriter;
199import java.lang.ref.WeakReference;
200import java.util.ArrayList;
201import java.util.Arrays;
202import java.util.Collections;
203import java.util.Comparator;
204import java.util.HashMap;
205import java.util.HashSet;
206import java.util.Iterator;
207import java.util.List;
208import java.util.Locale;
209import java.util.Map;
210import java.util.Set;
211import java.util.concurrent.atomic.AtomicBoolean;
212import java.util.concurrent.atomic.AtomicLong;
213
214public final class ActivityManagerService extends ActivityManagerNative
215        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
216    private static final String USER_DATA_DIR = "/data/user/";
217    static final String TAG = "ActivityManager";
218    static final String TAG_MU = "ActivityManagerServiceMU";
219    static final boolean DEBUG = false;
220    static final boolean localLOGV = DEBUG;
221    static final boolean DEBUG_BACKUP = localLOGV || false;
222    static final boolean DEBUG_BROADCAST = localLOGV || false;
223    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
224    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
225    static final boolean DEBUG_CLEANUP = localLOGV || false;
226    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
227    static final boolean DEBUG_FOCUS = false;
228    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
229    static final boolean DEBUG_MU = localLOGV || false;
230    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
231    static final boolean DEBUG_LRU = localLOGV || false;
232    static final boolean DEBUG_PAUSE = localLOGV || false;
233    static final boolean DEBUG_POWER = localLOGV || false;
234    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
235    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
236    static final boolean DEBUG_PROCESSES = localLOGV || false;
237    static final boolean DEBUG_PROVIDER = localLOGV || false;
238    static final boolean DEBUG_RESULTS = localLOGV || false;
239    static final boolean DEBUG_SERVICE = localLOGV || false;
240    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
241    static final boolean DEBUG_STACK = localLOGV || false;
242    static final boolean DEBUG_SWITCH = localLOGV || false;
243    static final boolean DEBUG_TASKS = localLOGV || false;
244    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
245    static final boolean DEBUG_TRANSITION = localLOGV || false;
246    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
247    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
248    static final boolean DEBUG_VISBILITY = localLOGV || false;
249    static final boolean DEBUG_PSS = localLOGV || false;
250    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
251    static final boolean VALIDATE_TOKENS = false;
252    static final boolean SHOW_ACTIVITY_START_TIME = true;
253
254    // Control over CPU and battery monitoring.
255    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
256    static final boolean MONITOR_CPU_USAGE = true;
257    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
258    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
259    static final boolean MONITOR_THREAD_CPU_USAGE = false;
260
261    // The flags that are set for all calls we make to the package manager.
262    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
263
264    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
265
266    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
267
268    // Maximum number of recent tasks that we can remember.
269    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
270
271    // Amount of time after a call to stopAppSwitches() during which we will
272    // prevent further untrusted switches from happening.
273    static final long APP_SWITCH_DELAY_TIME = 5*1000;
274
275    // How long we wait for a launched process to attach to the activity manager
276    // before we decide it's never going to come up for real.
277    static final int PROC_START_TIMEOUT = 10*1000;
278
279    // How long we wait for a launched process to attach to the activity manager
280    // before we decide it's never going to come up for real, when the process was
281    // started with a wrapper for instrumentation (such as Valgrind) because it
282    // could take much longer than usual.
283    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
284
285    // How long to wait after going idle before forcing apps to GC.
286    static final int GC_TIMEOUT = 5*1000;
287
288    // The minimum amount of time between successive GC requests for a process.
289    static final int GC_MIN_INTERVAL = 60*1000;
290
291    // The minimum amount of time between successive PSS requests for a process.
292    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
293
294    // The minimum amount of time between successive PSS requests for a process
295    // when the request is due to the memory state being lowered.
296    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
297
298    // The rate at which we check for apps using excessive power -- 15 mins.
299    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
300
301    // The minimum sample duration we will allow before deciding we have
302    // enough data on wake locks to start killing things.
303    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
304
305    // The minimum sample duration we will allow before deciding we have
306    // enough data on CPU usage to start killing things.
307    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
308
309    // How long we allow a receiver to run before giving up on it.
310    static final int BROADCAST_FG_TIMEOUT = 10*1000;
311    static final int BROADCAST_BG_TIMEOUT = 60*1000;
312
313    // How long we wait until we timeout on key dispatching.
314    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
315
316    // How long we wait until we timeout on key dispatching during instrumentation.
317    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
318
319    // Amount of time we wait for observers to handle a user switch before
320    // giving up on them and unfreezing the screen.
321    static final int USER_SWITCH_TIMEOUT = 2*1000;
322
323    // Maximum number of users we allow to be running at a time.
324    static final int MAX_RUNNING_USERS = 3;
325
326    // How long to wait in getAssistContextExtras for the activity and foreground services
327    // to respond with the result.
328    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
329
330    // Maximum number of persisted Uri grants a package is allowed
331    static final int MAX_PERSISTED_URI_GRANTS = 128;
332
333    static final int MY_PID = Process.myPid();
334
335    static final String[] EMPTY_STRING_ARRAY = new String[0];
336
337    // How many bytes to write into the dropbox log before truncating
338    static final int DROPBOX_MAX_SIZE = 256 * 1024;
339
340    /** All system services */
341    SystemServiceManager mSystemServiceManager;
342
343    /** Run all ActivityStacks through this */
344    ActivityStackSupervisor mStackSupervisor;
345
346    public IntentFirewall mIntentFirewall;
347
348    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
349    // default actuion automatically.  Important for devices without direct input
350    // devices.
351    private boolean mShowDialogs = true;
352
353    /**
354     * Description of a request to start a new activity, which has been held
355     * due to app switches being disabled.
356     */
357    static class PendingActivityLaunch {
358        final ActivityRecord r;
359        final ActivityRecord sourceRecord;
360        final int startFlags;
361        final ActivityStack stack;
362
363        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
364                int _startFlags, ActivityStack _stack) {
365            r = _r;
366            sourceRecord = _sourceRecord;
367            startFlags = _startFlags;
368            stack = _stack;
369        }
370    }
371
372    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
373            = new ArrayList<PendingActivityLaunch>();
374
375    BroadcastQueue mFgBroadcastQueue;
376    BroadcastQueue mBgBroadcastQueue;
377    // Convenient for easy iteration over the queues. Foreground is first
378    // so that dispatch of foreground broadcasts gets precedence.
379    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
380
381    BroadcastQueue broadcastQueueForIntent(Intent intent) {
382        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
383        if (DEBUG_BACKGROUND_BROADCAST) {
384            Slog.i(TAG, "Broadcast intent " + intent + " on "
385                    + (isFg ? "foreground" : "background")
386                    + " queue");
387        }
388        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
389    }
390
391    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
392        for (BroadcastQueue queue : mBroadcastQueues) {
393            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
394            if (r != null) {
395                return r;
396            }
397        }
398        return null;
399    }
400
401    /**
402     * Activity we have told the window manager to have key focus.
403     */
404    ActivityRecord mFocusedActivity = null;
405
406    /**
407     * List of intents that were used to start the most recent tasks.
408     */
409    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
410
411    public class PendingAssistExtras extends Binder implements Runnable {
412        public final ActivityRecord activity;
413        public boolean haveResult = false;
414        public Bundle result = null;
415        public PendingAssistExtras(ActivityRecord _activity) {
416            activity = _activity;
417        }
418        @Override
419        public void run() {
420            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
421            synchronized (this) {
422                haveResult = true;
423                notifyAll();
424            }
425        }
426    }
427
428    final ArrayList<PendingAssistExtras> mPendingAssistExtras
429            = new ArrayList<PendingAssistExtras>();
430
431    /**
432     * Process management.
433     */
434    final ProcessList mProcessList = new ProcessList();
435
436    /**
437     * All of the applications we currently have running organized by name.
438     * The keys are strings of the application package name (as
439     * returned by the package manager), and the keys are ApplicationRecord
440     * objects.
441     */
442    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
443
444    /**
445     * Tracking long-term execution of processes to look for abuse and other
446     * bad app behavior.
447     */
448    final ProcessStatsService mProcessStats;
449
450    /**
451     * The currently running isolated processes.
452     */
453    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
454
455    /**
456     * Counter for assigning isolated process uids, to avoid frequently reusing the
457     * same ones.
458     */
459    int mNextIsolatedProcessUid = 0;
460
461    /**
462     * The currently running heavy-weight process, if any.
463     */
464    ProcessRecord mHeavyWeightProcess = null;
465
466    /**
467     * The last time that various processes have crashed.
468     */
469    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
470
471    /**
472     * Information about a process that is currently marked as bad.
473     */
474    static final class BadProcessInfo {
475        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
476            this.time = time;
477            this.shortMsg = shortMsg;
478            this.longMsg = longMsg;
479            this.stack = stack;
480        }
481
482        final long time;
483        final String shortMsg;
484        final String longMsg;
485        final String stack;
486    }
487
488    /**
489     * Set of applications that we consider to be bad, and will reject
490     * incoming broadcasts from (which the user has no control over).
491     * Processes are added to this set when they have crashed twice within
492     * a minimum amount of time; they are removed from it when they are
493     * later restarted (hopefully due to some user action).  The value is the
494     * time it was added to the list.
495     */
496    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
497
498    /**
499     * All of the processes we currently have running organized by pid.
500     * The keys are the pid running the application.
501     *
502     * <p>NOTE: This object is protected by its own lock, NOT the global
503     * activity manager lock!
504     */
505    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
506
507    /**
508     * All of the processes that have been forced to be foreground.  The key
509     * is the pid of the caller who requested it (we hold a death
510     * link on it).
511     */
512    abstract class ForegroundToken implements IBinder.DeathRecipient {
513        int pid;
514        IBinder token;
515    }
516    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
517
518    /**
519     * List of records for processes that someone had tried to start before the
520     * system was ready.  We don't start them at that point, but ensure they
521     * are started by the time booting is complete.
522     */
523    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
524
525    /**
526     * List of persistent applications that are in the process
527     * of being started.
528     */
529    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
530
531    /**
532     * Processes that are being forcibly torn down.
533     */
534    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
535
536    /**
537     * List of running applications, sorted by recent usage.
538     * The first entry in the list is the least recently used.
539     */
540    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
541
542    /**
543     * Where in mLruProcesses that the processes hosting activities start.
544     */
545    int mLruProcessActivityStart = 0;
546
547    /**
548     * Where in mLruProcesses that the processes hosting services start.
549     * This is after (lower index) than mLruProcessesActivityStart.
550     */
551    int mLruProcessServiceStart = 0;
552
553    /**
554     * List of processes that should gc as soon as things are idle.
555     */
556    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
557
558    /**
559     * Processes we want to collect PSS data from.
560     */
561    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
562
563    /**
564     * Last time we requested PSS data of all processes.
565     */
566    long mLastFullPssTime = SystemClock.uptimeMillis();
567
568    /**
569     * This is the process holding what we currently consider to be
570     * the "home" activity.
571     */
572    ProcessRecord mHomeProcess;
573
574    /**
575     * This is the process holding the activity the user last visited that
576     * is in a different process from the one they are currently in.
577     */
578    ProcessRecord mPreviousProcess;
579
580    /**
581     * The time at which the previous process was last visible.
582     */
583    long mPreviousProcessVisibleTime;
584
585    /**
586     * Which uses have been started, so are allowed to run code.
587     */
588    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
589
590    /**
591     * LRU list of history of current users.  Most recently current is at the end.
592     */
593    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
594
595    /**
596     * Constant array of the users that are currently started.
597     */
598    int[] mStartedUserArray = new int[] { 0 };
599
600    /**
601     * Registered observers of the user switching mechanics.
602     */
603    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
604            = new RemoteCallbackList<IUserSwitchObserver>();
605
606    /**
607     * Currently active user switch.
608     */
609    Object mCurUserSwitchCallback;
610
611    /**
612     * Packages that the user has asked to have run in screen size
613     * compatibility mode instead of filling the screen.
614     */
615    final CompatModePackages mCompatModePackages;
616
617    /**
618     * Set of IntentSenderRecord objects that are currently active.
619     */
620    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
621            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
622
623    /**
624     * Fingerprints (hashCode()) of stack traces that we've
625     * already logged DropBox entries for.  Guarded by itself.  If
626     * something (rogue user app) forces this over
627     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
628     */
629    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
630    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
631
632    /**
633     * Strict Mode background batched logging state.
634     *
635     * The string buffer is guarded by itself, and its lock is also
636     * used to determine if another batched write is already
637     * in-flight.
638     */
639    private final StringBuilder mStrictModeBuffer = new StringBuilder();
640
641    /**
642     * Keeps track of all IIntentReceivers that have been registered for
643     * broadcasts.  Hash keys are the receiver IBinder, hash value is
644     * a ReceiverList.
645     */
646    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
647            new HashMap<IBinder, ReceiverList>();
648
649    /**
650     * Resolver for broadcast intents to registered receivers.
651     * Holds BroadcastFilter (subclass of IntentFilter).
652     */
653    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
654            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
655        @Override
656        protected boolean allowFilterResult(
657                BroadcastFilter filter, List<BroadcastFilter> dest) {
658            IBinder target = filter.receiverList.receiver.asBinder();
659            for (int i=dest.size()-1; i>=0; i--) {
660                if (dest.get(i).receiverList.receiver.asBinder() == target) {
661                    return false;
662                }
663            }
664            return true;
665        }
666
667        @Override
668        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
669            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
670                    || userId == filter.owningUserId) {
671                return super.newResult(filter, match, userId);
672            }
673            return null;
674        }
675
676        @Override
677        protected BroadcastFilter[] newArray(int size) {
678            return new BroadcastFilter[size];
679        }
680
681        @Override
682        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
683            return packageName.equals(filter.packageName);
684        }
685    };
686
687    /**
688     * State of all active sticky broadcasts per user.  Keys are the action of the
689     * sticky Intent, values are an ArrayList of all broadcasted intents with
690     * that action (which should usually be one).  The SparseArray is keyed
691     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
692     * for stickies that are sent to all users.
693     */
694    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
695            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
696
697    final ActiveServices mServices;
698
699    /**
700     * Backup/restore process management
701     */
702    String mBackupAppName = null;
703    BackupRecord mBackupTarget = null;
704
705    final ProviderMap mProviderMap;
706
707    /**
708     * List of content providers who have clients waiting for them.  The
709     * application is currently being launched and the provider will be
710     * removed from this list once it is published.
711     */
712    final ArrayList<ContentProviderRecord> mLaunchingProviders
713            = new ArrayList<ContentProviderRecord>();
714
715    /**
716     * File storing persisted {@link #mGrantedUriPermissions}.
717     */
718    private final AtomicFile mGrantFile;
719
720    /** XML constants used in {@link #mGrantFile} */
721    private static final String TAG_URI_GRANTS = "uri-grants";
722    private static final String TAG_URI_GRANT = "uri-grant";
723    private static final String ATTR_USER_HANDLE = "userHandle";
724    private static final String ATTR_SOURCE_PKG = "sourcePkg";
725    private static final String ATTR_TARGET_PKG = "targetPkg";
726    private static final String ATTR_URI = "uri";
727    private static final String ATTR_MODE_FLAGS = "modeFlags";
728    private static final String ATTR_CREATED_TIME = "createdTime";
729    private static final String ATTR_PREFIX = "prefix";
730
731    /**
732     * Global set of specific {@link Uri} permissions that have been granted.
733     * This optimized lookup structure maps from {@link UriPermission#targetUid}
734     * to {@link UriPermission#uri} to {@link UriPermission}.
735     */
736    @GuardedBy("this")
737    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
738            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
739
740    public static class GrantUri {
741        public final Uri uri;
742        public final boolean prefix;
743
744        public GrantUri(Uri uri, boolean prefix) {
745            this.uri = uri;
746            this.prefix = prefix;
747        }
748
749        @Override
750        public int hashCode() {
751            return toString().hashCode();
752        }
753
754        @Override
755        public boolean equals(Object o) {
756            if (o instanceof GrantUri) {
757                GrantUri other = (GrantUri) o;
758                return uri.equals(other.uri) && prefix == other.prefix;
759            }
760            return false;
761        }
762
763        @Override
764        public String toString() {
765            if (prefix) {
766                return uri.toString() + " [prefix]";
767            } else {
768                return uri.toString();
769            }
770        }
771    }
772
773    CoreSettingsObserver mCoreSettingsObserver;
774
775    /**
776     * Thread-local storage used to carry caller permissions over through
777     * indirect content-provider access.
778     */
779    private class Identity {
780        public int pid;
781        public int uid;
782
783        Identity(int _pid, int _uid) {
784            pid = _pid;
785            uid = _uid;
786        }
787    }
788
789    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
790
791    /**
792     * All information we have collected about the runtime performance of
793     * any user id that can impact battery performance.
794     */
795    final BatteryStatsService mBatteryStatsService;
796
797    /**
798     * Information about component usage
799     */
800    final UsageStatsService mUsageStatsService;
801
802    /**
803     * Information about and control over application operations
804     */
805    final AppOpsService mAppOpsService;
806
807    /**
808     * Current configuration information.  HistoryRecord objects are given
809     * a reference to this object to indicate which configuration they are
810     * currently running in, so this object must be kept immutable.
811     */
812    Configuration mConfiguration = new Configuration();
813
814    /**
815     * Current sequencing integer of the configuration, for skipping old
816     * configurations.
817     */
818    int mConfigurationSeq = 0;
819
820    /**
821     * Hardware-reported OpenGLES version.
822     */
823    final int GL_ES_VERSION;
824
825    /**
826     * List of initialization arguments to pass to all processes when binding applications to them.
827     * For example, references to the commonly used services.
828     */
829    HashMap<String, IBinder> mAppBindArgs;
830
831    /**
832     * Temporary to avoid allocations.  Protected by main lock.
833     */
834    final StringBuilder mStringBuilder = new StringBuilder(256);
835
836    /**
837     * Used to control how we initialize the service.
838     */
839    ComponentName mTopComponent;
840    String mTopAction = Intent.ACTION_MAIN;
841    String mTopData;
842    boolean mProcessesReady = false;
843    boolean mSystemReady = false;
844    boolean mBooting = false;
845    boolean mWaitingUpdate = false;
846    boolean mDidUpdate = false;
847    boolean mOnBattery = false;
848    boolean mLaunchWarningShown = false;
849
850    Context mContext;
851
852    int mFactoryTest;
853
854    boolean mCheckedForSetup;
855
856    /**
857     * The time at which we will allow normal application switches again,
858     * after a call to {@link #stopAppSwitches()}.
859     */
860    long mAppSwitchesAllowedTime;
861
862    /**
863     * This is set to true after the first switch after mAppSwitchesAllowedTime
864     * is set; any switches after that will clear the time.
865     */
866    boolean mDidAppSwitch;
867
868    /**
869     * Last time (in realtime) at which we checked for power usage.
870     */
871    long mLastPowerCheckRealtime;
872
873    /**
874     * Last time (in uptime) at which we checked for power usage.
875     */
876    long mLastPowerCheckUptime;
877
878    /**
879     * Set while we are wanting to sleep, to prevent any
880     * activities from being started/resumed.
881     */
882    private boolean mSleeping = false;
883
884    /**
885     * Set while we are running a voice interaction.  This overrides
886     * sleeping while it is active.
887     */
888    private boolean mRunningVoice = false;
889
890    /**
891     * State of external calls telling us if the device is asleep.
892     */
893    private boolean mWentToSleep = false;
894
895    /**
896     * State of external call telling us if the lock screen is shown.
897     */
898    private boolean mLockScreenShown = false;
899
900    /**
901     * Set if we are shutting down the system, similar to sleeping.
902     */
903    boolean mShuttingDown = false;
904
905    /**
906     * Current sequence id for oom_adj computation traversal.
907     */
908    int mAdjSeq = 0;
909
910    /**
911     * Current sequence id for process LRU updating.
912     */
913    int mLruSeq = 0;
914
915    /**
916     * Keep track of the non-cached/empty process we last found, to help
917     * determine how to distribute cached/empty processes next time.
918     */
919    int mNumNonCachedProcs = 0;
920
921    /**
922     * Keep track of the number of cached hidden procs, to balance oom adj
923     * distribution between those and empty procs.
924     */
925    int mNumCachedHiddenProcs = 0;
926
927    /**
928     * Keep track of the number of service processes we last found, to
929     * determine on the next iteration which should be B services.
930     */
931    int mNumServiceProcs = 0;
932    int mNewNumAServiceProcs = 0;
933    int mNewNumServiceProcs = 0;
934
935    /**
936     * Allow the current computed overall memory level of the system to go down?
937     * This is set to false when we are killing processes for reasons other than
938     * memory management, so that the now smaller process list will not be taken as
939     * an indication that memory is tighter.
940     */
941    boolean mAllowLowerMemLevel = false;
942
943    /**
944     * The last computed memory level, for holding when we are in a state that
945     * processes are going away for other reasons.
946     */
947    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
948
949    /**
950     * The last total number of process we have, to determine if changes actually look
951     * like a shrinking number of process due to lower RAM.
952     */
953    int mLastNumProcesses;
954
955    /**
956     * The uptime of the last time we performed idle maintenance.
957     */
958    long mLastIdleTime = SystemClock.uptimeMillis();
959
960    /**
961     * Total time spent with RAM that has been added in the past since the last idle time.
962     */
963    long mLowRamTimeSinceLastIdle = 0;
964
965    /**
966     * If RAM is currently low, when that horrible situation started.
967     */
968    long mLowRamStartTime = 0;
969
970    /**
971     * For reporting to battery stats the current top application.
972     */
973    private String mCurResumedPackage = null;
974    private int mCurResumedUid = -1;
975
976    /**
977     * For reporting to battery stats the apps currently running foreground
978     * service.  The ProcessMap is package/uid tuples; each of these contain
979     * an array of the currently foreground processes.
980     */
981    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
982            = new ProcessMap<ArrayList<ProcessRecord>>();
983
984    /**
985     * This is set if we had to do a delayed dexopt of an app before launching
986     * it, to increase the ANR timeouts in that case.
987     */
988    boolean mDidDexOpt;
989
990    /**
991     * Set if the systemServer made a call to enterSafeMode.
992     */
993    boolean mSafeMode;
994
995    String mDebugApp = null;
996    boolean mWaitForDebugger = false;
997    boolean mDebugTransient = false;
998    String mOrigDebugApp = null;
999    boolean mOrigWaitForDebugger = false;
1000    boolean mAlwaysFinishActivities = false;
1001    IActivityController mController = null;
1002    String mProfileApp = null;
1003    ProcessRecord mProfileProc = null;
1004    String mProfileFile;
1005    ParcelFileDescriptor mProfileFd;
1006    int mProfileType = 0;
1007    boolean mAutoStopProfiler = false;
1008    String mOpenGlTraceApp = null;
1009
1010    static class ProcessChangeItem {
1011        static final int CHANGE_ACTIVITIES = 1<<0;
1012        static final int CHANGE_PROCESS_STATE = 1<<1;
1013        int changes;
1014        int uid;
1015        int pid;
1016        int processState;
1017        boolean foregroundActivities;
1018    }
1019
1020    final RemoteCallbackList<IProcessObserver> mProcessObservers
1021            = new RemoteCallbackList<IProcessObserver>();
1022    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1023
1024    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1025            = new ArrayList<ProcessChangeItem>();
1026    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1027            = new ArrayList<ProcessChangeItem>();
1028
1029    /**
1030     * Runtime CPU use collection thread.  This object's lock is used to
1031     * protect all related state.
1032     */
1033    final Thread mProcessCpuThread;
1034
1035    /**
1036     * Used to collect process stats when showing not responding dialog.
1037     * Protected by mProcessCpuThread.
1038     */
1039    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1040            MONITOR_THREAD_CPU_USAGE);
1041    final AtomicLong mLastCpuTime = new AtomicLong(0);
1042    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1043
1044    long mLastWriteTime = 0;
1045
1046    /**
1047     * Used to retain an update lock when the foreground activity is in
1048     * immersive mode.
1049     */
1050    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1051
1052    /**
1053     * Set to true after the system has finished booting.
1054     */
1055    boolean mBooted = false;
1056
1057    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1058    int mProcessLimitOverride = -1;
1059
1060    WindowManagerService mWindowManager;
1061
1062    final ActivityThread mSystemThread;
1063
1064    int mCurrentUserId = 0;
1065    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1066    private UserManagerService mUserManager;
1067
1068    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1069        final ProcessRecord mApp;
1070        final int mPid;
1071        final IApplicationThread mAppThread;
1072
1073        AppDeathRecipient(ProcessRecord app, int pid,
1074                IApplicationThread thread) {
1075            if (localLOGV) Slog.v(
1076                TAG, "New death recipient " + this
1077                + " for thread " + thread.asBinder());
1078            mApp = app;
1079            mPid = pid;
1080            mAppThread = thread;
1081        }
1082
1083        @Override
1084        public void binderDied() {
1085            if (localLOGV) Slog.v(
1086                TAG, "Death received in " + this
1087                + " for thread " + mAppThread.asBinder());
1088            synchronized(ActivityManagerService.this) {
1089                appDiedLocked(mApp, mPid, mAppThread);
1090            }
1091        }
1092    }
1093
1094    static final int SHOW_ERROR_MSG = 1;
1095    static final int SHOW_NOT_RESPONDING_MSG = 2;
1096    static final int SHOW_FACTORY_ERROR_MSG = 3;
1097    static final int UPDATE_CONFIGURATION_MSG = 4;
1098    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1099    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1100    static final int SERVICE_TIMEOUT_MSG = 12;
1101    static final int UPDATE_TIME_ZONE = 13;
1102    static final int SHOW_UID_ERROR_MSG = 14;
1103    static final int IM_FEELING_LUCKY_MSG = 15;
1104    static final int PROC_START_TIMEOUT_MSG = 20;
1105    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1106    static final int KILL_APPLICATION_MSG = 22;
1107    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1108    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1109    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1110    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1111    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1112    static final int CLEAR_DNS_CACHE_MSG = 28;
1113    static final int UPDATE_HTTP_PROXY_MSG = 29;
1114    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1115    static final int DISPATCH_PROCESSES_CHANGED = 31;
1116    static final int DISPATCH_PROCESS_DIED = 32;
1117    static final int REPORT_MEM_USAGE_MSG = 33;
1118    static final int REPORT_USER_SWITCH_MSG = 34;
1119    static final int CONTINUE_USER_SWITCH_MSG = 35;
1120    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1121    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1122    static final int PERSIST_URI_GRANTS_MSG = 38;
1123    static final int REQUEST_ALL_PSS_MSG = 39;
1124    static final int START_PROFILES_MSG = 40;
1125    static final int UPDATE_TIME = 41;
1126    static final int SYSTEM_USER_START_MSG = 42;
1127    static final int SYSTEM_USER_CURRENT_MSG = 43;
1128
1129    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1130    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1131    static final int FIRST_COMPAT_MODE_MSG = 300;
1132    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1133
1134    AlertDialog mUidAlert;
1135    CompatModeDialog mCompatModeDialog;
1136    long mLastMemUsageReportTime = 0;
1137
1138    /**
1139     * Flag whether the current user is a "monkey", i.e. whether
1140     * the UI is driven by a UI automation tool.
1141     */
1142    private boolean mUserIsMonkey;
1143
1144    final ServiceThread mHandlerThread;
1145    final MainHandler mHandler;
1146
1147    final class MainHandler extends Handler {
1148        public MainHandler(Looper looper) {
1149            super(looper, null, true);
1150        }
1151
1152        @Override
1153        public void handleMessage(Message msg) {
1154            switch (msg.what) {
1155            case SHOW_ERROR_MSG: {
1156                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1157                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1158                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1159                synchronized (ActivityManagerService.this) {
1160                    ProcessRecord proc = (ProcessRecord)data.get("app");
1161                    AppErrorResult res = (AppErrorResult) data.get("result");
1162                    if (proc != null && proc.crashDialog != null) {
1163                        Slog.e(TAG, "App already has crash dialog: " + proc);
1164                        if (res != null) {
1165                            res.set(0);
1166                        }
1167                        return;
1168                    }
1169                    if (!showBackground && UserHandle.getAppId(proc.uid)
1170                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1171                            && proc.pid != MY_PID) {
1172                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1173                        if (res != null) {
1174                            res.set(0);
1175                        }
1176                        return;
1177                    }
1178                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1179                        Dialog d = new AppErrorDialog(mContext,
1180                                ActivityManagerService.this, res, proc);
1181                        d.show();
1182                        proc.crashDialog = d;
1183                    } else {
1184                        // The device is asleep, so just pretend that the user
1185                        // saw a crash dialog and hit "force quit".
1186                        if (res != null) {
1187                            res.set(0);
1188                        }
1189                    }
1190                }
1191
1192                ensureBootCompleted();
1193            } break;
1194            case SHOW_NOT_RESPONDING_MSG: {
1195                synchronized (ActivityManagerService.this) {
1196                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                    ProcessRecord proc = (ProcessRecord)data.get("app");
1198                    if (proc != null && proc.anrDialog != null) {
1199                        Slog.e(TAG, "App already has anr dialog: " + proc);
1200                        return;
1201                    }
1202
1203                    Intent intent = new Intent("android.intent.action.ANR");
1204                    if (!mProcessesReady) {
1205                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1206                                | Intent.FLAG_RECEIVER_FOREGROUND);
1207                    }
1208                    broadcastIntentLocked(null, null, intent,
1209                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1210                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1211
1212                    if (mShowDialogs) {
1213                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1214                                mContext, proc, (ActivityRecord)data.get("activity"),
1215                                msg.arg1 != 0);
1216                        d.show();
1217                        proc.anrDialog = d;
1218                    } else {
1219                        // Just kill the app if there is no dialog to be shown.
1220                        killAppAtUsersRequest(proc, null);
1221                    }
1222                }
1223
1224                ensureBootCompleted();
1225            } break;
1226            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1227                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1228                synchronized (ActivityManagerService.this) {
1229                    ProcessRecord proc = (ProcessRecord) data.get("app");
1230                    if (proc == null) {
1231                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1232                        break;
1233                    }
1234                    if (proc.crashDialog != null) {
1235                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1236                        return;
1237                    }
1238                    AppErrorResult res = (AppErrorResult) data.get("result");
1239                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1240                        Dialog d = new StrictModeViolationDialog(mContext,
1241                                ActivityManagerService.this, res, proc);
1242                        d.show();
1243                        proc.crashDialog = d;
1244                    } else {
1245                        // The device is asleep, so just pretend that the user
1246                        // saw a crash dialog and hit "force quit".
1247                        res.set(0);
1248                    }
1249                }
1250                ensureBootCompleted();
1251            } break;
1252            case SHOW_FACTORY_ERROR_MSG: {
1253                Dialog d = new FactoryErrorDialog(
1254                    mContext, msg.getData().getCharSequence("msg"));
1255                d.show();
1256                ensureBootCompleted();
1257            } break;
1258            case UPDATE_CONFIGURATION_MSG: {
1259                final ContentResolver resolver = mContext.getContentResolver();
1260                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1261            } break;
1262            case GC_BACKGROUND_PROCESSES_MSG: {
1263                synchronized (ActivityManagerService.this) {
1264                    performAppGcsIfAppropriateLocked();
1265                }
1266            } break;
1267            case WAIT_FOR_DEBUGGER_MSG: {
1268                synchronized (ActivityManagerService.this) {
1269                    ProcessRecord app = (ProcessRecord)msg.obj;
1270                    if (msg.arg1 != 0) {
1271                        if (!app.waitedForDebugger) {
1272                            Dialog d = new AppWaitingForDebuggerDialog(
1273                                    ActivityManagerService.this,
1274                                    mContext, app);
1275                            app.waitDialog = d;
1276                            app.waitedForDebugger = true;
1277                            d.show();
1278                        }
1279                    } else {
1280                        if (app.waitDialog != null) {
1281                            app.waitDialog.dismiss();
1282                            app.waitDialog = null;
1283                        }
1284                    }
1285                }
1286            } break;
1287            case SERVICE_TIMEOUT_MSG: {
1288                if (mDidDexOpt) {
1289                    mDidDexOpt = false;
1290                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1291                    nmsg.obj = msg.obj;
1292                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1293                    return;
1294                }
1295                mServices.serviceTimeout((ProcessRecord)msg.obj);
1296            } break;
1297            case UPDATE_TIME_ZONE: {
1298                synchronized (ActivityManagerService.this) {
1299                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1300                        ProcessRecord r = mLruProcesses.get(i);
1301                        if (r.thread != null) {
1302                            try {
1303                                r.thread.updateTimeZone();
1304                            } catch (RemoteException ex) {
1305                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1306                            }
1307                        }
1308                    }
1309                }
1310            } break;
1311            case CLEAR_DNS_CACHE_MSG: {
1312                synchronized (ActivityManagerService.this) {
1313                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1314                        ProcessRecord r = mLruProcesses.get(i);
1315                        if (r.thread != null) {
1316                            try {
1317                                r.thread.clearDnsCache();
1318                            } catch (RemoteException ex) {
1319                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1320                            }
1321                        }
1322                    }
1323                }
1324            } break;
1325            case UPDATE_HTTP_PROXY_MSG: {
1326                ProxyInfo proxy = (ProxyInfo)msg.obj;
1327                String host = "";
1328                String port = "";
1329                String exclList = "";
1330                String pacFileUrl = null;
1331                if (proxy != null) {
1332                    host = proxy.getHost();
1333                    port = Integer.toString(proxy.getPort());
1334                    exclList = proxy.getExclusionListAsString();
1335                    pacFileUrl = proxy.getPacFileUrl().toString();
1336                }
1337                synchronized (ActivityManagerService.this) {
1338                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1339                        ProcessRecord r = mLruProcesses.get(i);
1340                        if (r.thread != null) {
1341                            try {
1342                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1343                            } catch (RemoteException ex) {
1344                                Slog.w(TAG, "Failed to update http proxy for: " +
1345                                        r.info.processName);
1346                            }
1347                        }
1348                    }
1349                }
1350            } break;
1351            case SHOW_UID_ERROR_MSG: {
1352                String title = "System UIDs Inconsistent";
1353                String text = "UIDs on the system are inconsistent, you need to wipe your"
1354                        + " data partition or your device will be unstable.";
1355                Log.e(TAG, title + ": " + text);
1356                if (mShowDialogs) {
1357                    // XXX This is a temporary dialog, no need to localize.
1358                    AlertDialog d = new BaseErrorDialog(mContext);
1359                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1360                    d.setCancelable(false);
1361                    d.setTitle(title);
1362                    d.setMessage(text);
1363                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1364                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1365                    mUidAlert = d;
1366                    d.show();
1367                }
1368            } break;
1369            case IM_FEELING_LUCKY_MSG: {
1370                if (mUidAlert != null) {
1371                    mUidAlert.dismiss();
1372                    mUidAlert = null;
1373                }
1374            } break;
1375            case PROC_START_TIMEOUT_MSG: {
1376                if (mDidDexOpt) {
1377                    mDidDexOpt = false;
1378                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1379                    nmsg.obj = msg.obj;
1380                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1381                    return;
1382                }
1383                ProcessRecord app = (ProcessRecord)msg.obj;
1384                synchronized (ActivityManagerService.this) {
1385                    processStartTimedOutLocked(app);
1386                }
1387            } break;
1388            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1389                synchronized (ActivityManagerService.this) {
1390                    doPendingActivityLaunchesLocked(true);
1391                }
1392            } break;
1393            case KILL_APPLICATION_MSG: {
1394                synchronized (ActivityManagerService.this) {
1395                    int appid = msg.arg1;
1396                    boolean restart = (msg.arg2 == 1);
1397                    Bundle bundle = (Bundle)msg.obj;
1398                    String pkg = bundle.getString("pkg");
1399                    String reason = bundle.getString("reason");
1400                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1401                            false, UserHandle.USER_ALL, reason);
1402                }
1403            } break;
1404            case FINALIZE_PENDING_INTENT_MSG: {
1405                ((PendingIntentRecord)msg.obj).completeFinalize();
1406            } break;
1407            case POST_HEAVY_NOTIFICATION_MSG: {
1408                INotificationManager inm = NotificationManager.getService();
1409                if (inm == null) {
1410                    return;
1411                }
1412
1413                ActivityRecord root = (ActivityRecord)msg.obj;
1414                ProcessRecord process = root.app;
1415                if (process == null) {
1416                    return;
1417                }
1418
1419                try {
1420                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1421                    String text = mContext.getString(R.string.heavy_weight_notification,
1422                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1423                    Notification notification = new Notification();
1424                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1425                    notification.when = 0;
1426                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1427                    notification.tickerText = text;
1428                    notification.defaults = 0; // please be quiet
1429                    notification.sound = null;
1430                    notification.vibrate = null;
1431                    notification.setLatestEventInfo(context, text,
1432                            mContext.getText(R.string.heavy_weight_notification_detail),
1433                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1434                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1435                                    new UserHandle(root.userId)));
1436
1437                    try {
1438                        int[] outId = new int[1];
1439                        inm.enqueueNotificationWithTag("android", "android", null,
1440                                R.string.heavy_weight_notification,
1441                                notification, outId, root.userId);
1442                    } catch (RuntimeException e) {
1443                        Slog.w(ActivityManagerService.TAG,
1444                                "Error showing notification for heavy-weight app", e);
1445                    } catch (RemoteException e) {
1446                    }
1447                } catch (NameNotFoundException e) {
1448                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1449                }
1450            } break;
1451            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1452                INotificationManager inm = NotificationManager.getService();
1453                if (inm == null) {
1454                    return;
1455                }
1456                try {
1457                    inm.cancelNotificationWithTag("android", null,
1458                            R.string.heavy_weight_notification,  msg.arg1);
1459                } catch (RuntimeException e) {
1460                    Slog.w(ActivityManagerService.TAG,
1461                            "Error canceling notification for service", e);
1462                } catch (RemoteException e) {
1463                }
1464            } break;
1465            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1466                synchronized (ActivityManagerService.this) {
1467                    checkExcessivePowerUsageLocked(true);
1468                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1469                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1470                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1471                }
1472            } break;
1473            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1474                synchronized (ActivityManagerService.this) {
1475                    ActivityRecord ar = (ActivityRecord)msg.obj;
1476                    if (mCompatModeDialog != null) {
1477                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1478                                ar.info.applicationInfo.packageName)) {
1479                            return;
1480                        }
1481                        mCompatModeDialog.dismiss();
1482                        mCompatModeDialog = null;
1483                    }
1484                    if (ar != null && false) {
1485                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1486                                ar.packageName)) {
1487                            int mode = mCompatModePackages.computeCompatModeLocked(
1488                                    ar.info.applicationInfo);
1489                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1490                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1491                                mCompatModeDialog = new CompatModeDialog(
1492                                        ActivityManagerService.this, mContext,
1493                                        ar.info.applicationInfo);
1494                                mCompatModeDialog.show();
1495                            }
1496                        }
1497                    }
1498                }
1499                break;
1500            }
1501            case DISPATCH_PROCESSES_CHANGED: {
1502                dispatchProcessesChanged();
1503                break;
1504            }
1505            case DISPATCH_PROCESS_DIED: {
1506                final int pid = msg.arg1;
1507                final int uid = msg.arg2;
1508                dispatchProcessDied(pid, uid);
1509                break;
1510            }
1511            case REPORT_MEM_USAGE_MSG: {
1512                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1513                Thread thread = new Thread() {
1514                    @Override public void run() {
1515                        final SparseArray<ProcessMemInfo> infoMap
1516                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1517                        for (int i=0, N=memInfos.size(); i<N; i++) {
1518                            ProcessMemInfo mi = memInfos.get(i);
1519                            infoMap.put(mi.pid, mi);
1520                        }
1521                        updateCpuStatsNow();
1522                        synchronized (mProcessCpuThread) {
1523                            final int N = mProcessCpuTracker.countStats();
1524                            for (int i=0; i<N; i++) {
1525                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1526                                if (st.vsize > 0) {
1527                                    long pss = Debug.getPss(st.pid, null);
1528                                    if (pss > 0) {
1529                                        if (infoMap.indexOfKey(st.pid) < 0) {
1530                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1531                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1532                                            mi.pss = pss;
1533                                            memInfos.add(mi);
1534                                        }
1535                                    }
1536                                }
1537                            }
1538                        }
1539
1540                        long totalPss = 0;
1541                        for (int i=0, N=memInfos.size(); i<N; i++) {
1542                            ProcessMemInfo mi = memInfos.get(i);
1543                            if (mi.pss == 0) {
1544                                mi.pss = Debug.getPss(mi.pid, null);
1545                            }
1546                            totalPss += mi.pss;
1547                        }
1548                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1549                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1550                                if (lhs.oomAdj != rhs.oomAdj) {
1551                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1552                                }
1553                                if (lhs.pss != rhs.pss) {
1554                                    return lhs.pss < rhs.pss ? 1 : -1;
1555                                }
1556                                return 0;
1557                            }
1558                        });
1559
1560                        StringBuilder tag = new StringBuilder(128);
1561                        StringBuilder stack = new StringBuilder(128);
1562                        tag.append("Low on memory -- ");
1563                        appendMemBucket(tag, totalPss, "total", false);
1564                        appendMemBucket(stack, totalPss, "total", true);
1565
1566                        StringBuilder logBuilder = new StringBuilder(1024);
1567                        logBuilder.append("Low on memory:\n");
1568
1569                        boolean firstLine = true;
1570                        int lastOomAdj = Integer.MIN_VALUE;
1571                        for (int i=0, N=memInfos.size(); i<N; i++) {
1572                            ProcessMemInfo mi = memInfos.get(i);
1573
1574                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1575                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1576                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1577                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1578                                if (lastOomAdj != mi.oomAdj) {
1579                                    lastOomAdj = mi.oomAdj;
1580                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1581                                        tag.append(" / ");
1582                                    }
1583                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1584                                        if (firstLine) {
1585                                            stack.append(":");
1586                                            firstLine = false;
1587                                        }
1588                                        stack.append("\n\t at ");
1589                                    } else {
1590                                        stack.append("$");
1591                                    }
1592                                } else {
1593                                    tag.append(" ");
1594                                    stack.append("$");
1595                                }
1596                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1597                                    appendMemBucket(tag, mi.pss, mi.name, false);
1598                                }
1599                                appendMemBucket(stack, mi.pss, mi.name, true);
1600                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1601                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1602                                    stack.append("(");
1603                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1604                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1605                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1606                                            stack.append(":");
1607                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1608                                        }
1609                                    }
1610                                    stack.append(")");
1611                                }
1612                            }
1613
1614                            logBuilder.append("  ");
1615                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1616                            logBuilder.append(' ');
1617                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1618                            logBuilder.append(' ');
1619                            ProcessList.appendRamKb(logBuilder, mi.pss);
1620                            logBuilder.append(" kB: ");
1621                            logBuilder.append(mi.name);
1622                            logBuilder.append(" (");
1623                            logBuilder.append(mi.pid);
1624                            logBuilder.append(") ");
1625                            logBuilder.append(mi.adjType);
1626                            logBuilder.append('\n');
1627                            if (mi.adjReason != null) {
1628                                logBuilder.append("                      ");
1629                                logBuilder.append(mi.adjReason);
1630                                logBuilder.append('\n');
1631                            }
1632                        }
1633
1634                        logBuilder.append("           ");
1635                        ProcessList.appendRamKb(logBuilder, totalPss);
1636                        logBuilder.append(" kB: TOTAL\n");
1637
1638                        long[] infos = new long[Debug.MEMINFO_COUNT];
1639                        Debug.getMemInfo(infos);
1640                        logBuilder.append("  MemInfo: ");
1641                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1642                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1643                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1644                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1645                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1646                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1647                            logBuilder.append("  ZRAM: ");
1648                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1649                            logBuilder.append(" kB RAM, ");
1650                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1651                            logBuilder.append(" kB swap total, ");
1652                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1653                            logBuilder.append(" kB swap free\n");
1654                        }
1655                        Slog.i(TAG, logBuilder.toString());
1656
1657                        StringBuilder dropBuilder = new StringBuilder(1024);
1658                        /*
1659                        StringWriter oomSw = new StringWriter();
1660                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1661                        StringWriter catSw = new StringWriter();
1662                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1663                        String[] emptyArgs = new String[] { };
1664                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1665                        oomPw.flush();
1666                        String oomString = oomSw.toString();
1667                        */
1668                        dropBuilder.append(stack);
1669                        dropBuilder.append('\n');
1670                        dropBuilder.append('\n');
1671                        dropBuilder.append(logBuilder);
1672                        dropBuilder.append('\n');
1673                        /*
1674                        dropBuilder.append(oomString);
1675                        dropBuilder.append('\n');
1676                        */
1677                        StringWriter catSw = new StringWriter();
1678                        synchronized (ActivityManagerService.this) {
1679                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1680                            String[] emptyArgs = new String[] { };
1681                            catPw.println();
1682                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1683                            catPw.println();
1684                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1685                                    false, false, null);
1686                            catPw.println();
1687                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1688                            catPw.flush();
1689                        }
1690                        dropBuilder.append(catSw.toString());
1691                        addErrorToDropBox("lowmem", null, "system_server", null,
1692                                null, tag.toString(), dropBuilder.toString(), null, null);
1693                        //Slog.i(TAG, "Sent to dropbox:");
1694                        //Slog.i(TAG, dropBuilder.toString());
1695                        synchronized (ActivityManagerService.this) {
1696                            long now = SystemClock.uptimeMillis();
1697                            if (mLastMemUsageReportTime < now) {
1698                                mLastMemUsageReportTime = now;
1699                            }
1700                        }
1701                    }
1702                };
1703                thread.start();
1704                break;
1705            }
1706            case REPORT_USER_SWITCH_MSG: {
1707                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1708                break;
1709            }
1710            case CONTINUE_USER_SWITCH_MSG: {
1711                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1712                break;
1713            }
1714            case USER_SWITCH_TIMEOUT_MSG: {
1715                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1716                break;
1717            }
1718            case IMMERSIVE_MODE_LOCK_MSG: {
1719                final boolean nextState = (msg.arg1 != 0);
1720                if (mUpdateLock.isHeld() != nextState) {
1721                    if (DEBUG_IMMERSIVE) {
1722                        final ActivityRecord r = (ActivityRecord) msg.obj;
1723                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1724                    }
1725                    if (nextState) {
1726                        mUpdateLock.acquire();
1727                    } else {
1728                        mUpdateLock.release();
1729                    }
1730                }
1731                break;
1732            }
1733            case PERSIST_URI_GRANTS_MSG: {
1734                writeGrantedUriPermissions();
1735                break;
1736            }
1737            case REQUEST_ALL_PSS_MSG: {
1738                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1739                break;
1740            }
1741            case START_PROFILES_MSG: {
1742                synchronized (ActivityManagerService.this) {
1743                    startProfilesLocked();
1744                }
1745                break;
1746            }
1747            case UPDATE_TIME: {
1748                synchronized (ActivityManagerService.this) {
1749                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1750                        ProcessRecord r = mLruProcesses.get(i);
1751                        if (r.thread != null) {
1752                            try {
1753                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1754                            } catch (RemoteException ex) {
1755                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1756                            }
1757                        }
1758                    }
1759                }
1760                break;
1761            }
1762            case SYSTEM_USER_START_MSG: {
1763                mSystemServiceManager.startUser(msg.arg1);
1764                break;
1765            }
1766            case SYSTEM_USER_CURRENT_MSG: {
1767                mSystemServiceManager.switchUser(msg.arg1);
1768                break;
1769            }
1770            }
1771        }
1772    };
1773
1774    static final int COLLECT_PSS_BG_MSG = 1;
1775
1776    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1777        @Override
1778        public void handleMessage(Message msg) {
1779            switch (msg.what) {
1780            case COLLECT_PSS_BG_MSG: {
1781                int i=0, num=0;
1782                long start = SystemClock.uptimeMillis();
1783                long[] tmp = new long[1];
1784                do {
1785                    ProcessRecord proc;
1786                    int procState;
1787                    int pid;
1788                    synchronized (ActivityManagerService.this) {
1789                        if (i >= mPendingPssProcesses.size()) {
1790                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1791                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1792                            mPendingPssProcesses.clear();
1793                            return;
1794                        }
1795                        proc = mPendingPssProcesses.get(i);
1796                        procState = proc.pssProcState;
1797                        if (proc.thread != null && procState == proc.setProcState) {
1798                            pid = proc.pid;
1799                        } else {
1800                            proc = null;
1801                            pid = 0;
1802                        }
1803                        i++;
1804                    }
1805                    if (proc != null) {
1806                        long pss = Debug.getPss(pid, tmp);
1807                        synchronized (ActivityManagerService.this) {
1808                            if (proc.thread != null && proc.setProcState == procState
1809                                    && proc.pid == pid) {
1810                                num++;
1811                                proc.lastPssTime = SystemClock.uptimeMillis();
1812                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1813                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1814                                        + ": " + pss + " lastPss=" + proc.lastPss
1815                                        + " state=" + ProcessList.makeProcStateString(procState));
1816                                if (proc.initialIdlePss == 0) {
1817                                    proc.initialIdlePss = pss;
1818                                }
1819                                proc.lastPss = pss;
1820                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1821                                    proc.lastCachedPss = pss;
1822                                }
1823                            }
1824                        }
1825                    }
1826                } while (true);
1827            }
1828            }
1829        }
1830    };
1831
1832    /**
1833     * Monitor for package changes and update our internal state.
1834     */
1835    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1836        @Override
1837        public void onPackageRemoved(String packageName, int uid) {
1838            // Remove all tasks with activities in the specified package from the list of recent tasks
1839            synchronized (ActivityManagerService.this) {
1840                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1841                    TaskRecord tr = mRecentTasks.get(i);
1842                    ComponentName cn = tr.intent.getComponent();
1843                    if (cn != null && cn.getPackageName().equals(packageName)) {
1844                        // If the package name matches, remove the task and kill the process
1845                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1846                    }
1847                }
1848            }
1849        }
1850
1851        @Override
1852        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1853            onPackageModified(packageName);
1854            return true;
1855        }
1856
1857        @Override
1858        public void onPackageModified(String packageName) {
1859            final PackageManager pm = mContext.getPackageManager();
1860            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1861                    new ArrayList<Pair<Intent, Integer>>();
1862            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1863            // Copy the list of recent tasks so that we don't hold onto the lock on
1864            // ActivityManagerService for long periods while checking if components exist.
1865            synchronized (ActivityManagerService.this) {
1866                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1867                    TaskRecord tr = mRecentTasks.get(i);
1868                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1869                }
1870            }
1871            // Check the recent tasks and filter out all tasks with components that no longer exist.
1872            Intent tmpI = new Intent();
1873            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1874                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1875                ComponentName cn = p.first.getComponent();
1876                if (cn != null && cn.getPackageName().equals(packageName)) {
1877                    try {
1878                        // Add the task to the list to remove if the component no longer exists
1879                        tmpI.setComponent(cn);
1880                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1881                            tasksToRemove.add(p.second);
1882                        }
1883                    } catch (Exception e) {}
1884                }
1885            }
1886            // Prune all the tasks with removed components from the list of recent tasks
1887            synchronized (ActivityManagerService.this) {
1888                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1889                    // Remove the task but don't kill the process (since other components in that
1890                    // package may still be running and in the background)
1891                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1892                }
1893            }
1894        }
1895
1896        @Override
1897        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1898            // Force stop the specified packages
1899            if (packages != null) {
1900                for (String pkg : packages) {
1901                    synchronized (ActivityManagerService.this) {
1902                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1903                                "finished booting")) {
1904                            return true;
1905                        }
1906                    }
1907                }
1908            }
1909            return false;
1910        }
1911    };
1912
1913    public void setSystemProcess() {
1914        try {
1915            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1916            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1917            ServiceManager.addService("meminfo", new MemBinder(this));
1918            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1919            ServiceManager.addService("dbinfo", new DbBinder(this));
1920            if (MONITOR_CPU_USAGE) {
1921                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1922            }
1923            ServiceManager.addService("permission", new PermissionController(this));
1924
1925            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1926                    "android", STOCK_PM_FLAGS);
1927            mSystemThread.installSystemApplicationInfo(info);
1928
1929            synchronized (this) {
1930                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1931                app.persistent = true;
1932                app.pid = MY_PID;
1933                app.maxAdj = ProcessList.SYSTEM_ADJ;
1934                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1935                mProcessNames.put(app.processName, app.uid, app);
1936                synchronized (mPidsSelfLocked) {
1937                    mPidsSelfLocked.put(app.pid, app);
1938                }
1939                updateLruProcessLocked(app, false, null);
1940                updateOomAdjLocked();
1941            }
1942        } catch (PackageManager.NameNotFoundException e) {
1943            throw new RuntimeException(
1944                    "Unable to find android system package", e);
1945        }
1946    }
1947
1948    public void setWindowManager(WindowManagerService wm) {
1949        mWindowManager = wm;
1950        mStackSupervisor.setWindowManager(wm);
1951    }
1952
1953    public void startObservingNativeCrashes() {
1954        final NativeCrashListener ncl = new NativeCrashListener(this);
1955        ncl.start();
1956    }
1957
1958    public IAppOpsService getAppOpsService() {
1959        return mAppOpsService;
1960    }
1961
1962    static class MemBinder extends Binder {
1963        ActivityManagerService mActivityManagerService;
1964        MemBinder(ActivityManagerService activityManagerService) {
1965            mActivityManagerService = activityManagerService;
1966        }
1967
1968        @Override
1969        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1970            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1971                    != PackageManager.PERMISSION_GRANTED) {
1972                pw.println("Permission Denial: can't dump meminfo from from pid="
1973                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1974                        + " without permission " + android.Manifest.permission.DUMP);
1975                return;
1976            }
1977
1978            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1979        }
1980    }
1981
1982    static class GraphicsBinder extends Binder {
1983        ActivityManagerService mActivityManagerService;
1984        GraphicsBinder(ActivityManagerService activityManagerService) {
1985            mActivityManagerService = activityManagerService;
1986        }
1987
1988        @Override
1989        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1990            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1991                    != PackageManager.PERMISSION_GRANTED) {
1992                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1993                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1994                        + " without permission " + android.Manifest.permission.DUMP);
1995                return;
1996            }
1997
1998            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1999        }
2000    }
2001
2002    static class DbBinder extends Binder {
2003        ActivityManagerService mActivityManagerService;
2004        DbBinder(ActivityManagerService activityManagerService) {
2005            mActivityManagerService = activityManagerService;
2006        }
2007
2008        @Override
2009        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2010            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2011                    != PackageManager.PERMISSION_GRANTED) {
2012                pw.println("Permission Denial: can't dump dbinfo from from pid="
2013                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2014                        + " without permission " + android.Manifest.permission.DUMP);
2015                return;
2016            }
2017
2018            mActivityManagerService.dumpDbInfo(fd, pw, args);
2019        }
2020    }
2021
2022    static class CpuBinder extends Binder {
2023        ActivityManagerService mActivityManagerService;
2024        CpuBinder(ActivityManagerService activityManagerService) {
2025            mActivityManagerService = activityManagerService;
2026        }
2027
2028        @Override
2029        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2030            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2031                    != PackageManager.PERMISSION_GRANTED) {
2032                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2033                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2034                        + " without permission " + android.Manifest.permission.DUMP);
2035                return;
2036            }
2037
2038            synchronized (mActivityManagerService.mProcessCpuThread) {
2039                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2040                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2041                        SystemClock.uptimeMillis()));
2042            }
2043        }
2044    }
2045
2046    public static final class Lifecycle extends SystemService {
2047        private final ActivityManagerService mService;
2048
2049        public Lifecycle(Context context) {
2050            super(context);
2051            mService = new ActivityManagerService(context);
2052        }
2053
2054        @Override
2055        public void onStart() {
2056            mService.start();
2057        }
2058
2059        public ActivityManagerService getService() {
2060            return mService;
2061        }
2062    }
2063
2064    // Note: This method is invoked on the main thread but may need to attach various
2065    // handlers to other threads.  So take care to be explicit about the looper.
2066    public ActivityManagerService(Context systemContext) {
2067        mContext = systemContext;
2068        mFactoryTest = FactoryTest.getMode();
2069        mSystemThread = ActivityThread.currentActivityThread();
2070
2071        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2072
2073        mHandlerThread = new ServiceThread(TAG,
2074                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2075        mHandlerThread.start();
2076        mHandler = new MainHandler(mHandlerThread.getLooper());
2077
2078        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2079                "foreground", BROADCAST_FG_TIMEOUT, false);
2080        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2081                "background", BROADCAST_BG_TIMEOUT, true);
2082        mBroadcastQueues[0] = mFgBroadcastQueue;
2083        mBroadcastQueues[1] = mBgBroadcastQueue;
2084
2085        mServices = new ActiveServices(this);
2086        mProviderMap = new ProviderMap(this);
2087
2088        // TODO: Move creation of battery stats service outside of activity manager service.
2089        File dataDir = Environment.getDataDirectory();
2090        File systemDir = new File(dataDir, "system");
2091        systemDir.mkdirs();
2092        mBatteryStatsService = new BatteryStatsService(new File(
2093                systemDir, "batterystats.bin").toString(), mHandler);
2094        mBatteryStatsService.getActiveStatistics().readLocked();
2095        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2096        mOnBattery = DEBUG_POWER ? true
2097                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2098        mBatteryStatsService.getActiveStatistics().setCallback(this);
2099
2100        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2101
2102        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2103        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2104
2105        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2106
2107        // User 0 is the first and only user that runs at boot.
2108        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2109        mUserLru.add(Integer.valueOf(0));
2110        updateStartedUserArrayLocked();
2111
2112        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2113            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2114
2115        mConfiguration.setToDefaults();
2116        mConfiguration.setLocale(Locale.getDefault());
2117
2118        mConfigurationSeq = mConfiguration.seq = 1;
2119        mProcessCpuTracker.init();
2120
2121        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2122        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2123        mStackSupervisor = new ActivityStackSupervisor(this);
2124
2125        mProcessCpuThread = new Thread("CpuTracker") {
2126            @Override
2127            public void run() {
2128                while (true) {
2129                    try {
2130                        try {
2131                            synchronized(this) {
2132                                final long now = SystemClock.uptimeMillis();
2133                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2134                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2135                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2136                                //        + ", write delay=" + nextWriteDelay);
2137                                if (nextWriteDelay < nextCpuDelay) {
2138                                    nextCpuDelay = nextWriteDelay;
2139                                }
2140                                if (nextCpuDelay > 0) {
2141                                    mProcessCpuMutexFree.set(true);
2142                                    this.wait(nextCpuDelay);
2143                                }
2144                            }
2145                        } catch (InterruptedException e) {
2146                        }
2147                        updateCpuStatsNow();
2148                    } catch (Exception e) {
2149                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2150                    }
2151                }
2152            }
2153        };
2154
2155        Watchdog.getInstance().addMonitor(this);
2156        Watchdog.getInstance().addThread(mHandler);
2157    }
2158
2159    public void setSystemServiceManager(SystemServiceManager mgr) {
2160        mSystemServiceManager = mgr;
2161    }
2162
2163    private void start() {
2164        mProcessCpuThread.start();
2165
2166        mBatteryStatsService.publish(mContext);
2167        mUsageStatsService.publish(mContext);
2168        mAppOpsService.publish(mContext);
2169
2170        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2171    }
2172
2173    @Override
2174    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2175            throws RemoteException {
2176        if (code == SYSPROPS_TRANSACTION) {
2177            // We need to tell all apps about the system property change.
2178            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2179            synchronized(this) {
2180                final int NP = mProcessNames.getMap().size();
2181                for (int ip=0; ip<NP; ip++) {
2182                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2183                    final int NA = apps.size();
2184                    for (int ia=0; ia<NA; ia++) {
2185                        ProcessRecord app = apps.valueAt(ia);
2186                        if (app.thread != null) {
2187                            procs.add(app.thread.asBinder());
2188                        }
2189                    }
2190                }
2191            }
2192
2193            int N = procs.size();
2194            for (int i=0; i<N; i++) {
2195                Parcel data2 = Parcel.obtain();
2196                try {
2197                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2198                } catch (RemoteException e) {
2199                }
2200                data2.recycle();
2201            }
2202        }
2203        try {
2204            return super.onTransact(code, data, reply, flags);
2205        } catch (RuntimeException e) {
2206            // The activity manager only throws security exceptions, so let's
2207            // log all others.
2208            if (!(e instanceof SecurityException)) {
2209                Slog.wtf(TAG, "Activity Manager Crash", e);
2210            }
2211            throw e;
2212        }
2213    }
2214
2215    void updateCpuStats() {
2216        final long now = SystemClock.uptimeMillis();
2217        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2218            return;
2219        }
2220        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2221            synchronized (mProcessCpuThread) {
2222                mProcessCpuThread.notify();
2223            }
2224        }
2225    }
2226
2227    void updateCpuStatsNow() {
2228        synchronized (mProcessCpuThread) {
2229            mProcessCpuMutexFree.set(false);
2230            final long now = SystemClock.uptimeMillis();
2231            boolean haveNewCpuStats = false;
2232
2233            if (MONITOR_CPU_USAGE &&
2234                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2235                mLastCpuTime.set(now);
2236                haveNewCpuStats = true;
2237                mProcessCpuTracker.update();
2238                //Slog.i(TAG, mProcessCpu.printCurrentState());
2239                //Slog.i(TAG, "Total CPU usage: "
2240                //        + mProcessCpu.getTotalCpuPercent() + "%");
2241
2242                // Slog the cpu usage if the property is set.
2243                if ("true".equals(SystemProperties.get("events.cpu"))) {
2244                    int user = mProcessCpuTracker.getLastUserTime();
2245                    int system = mProcessCpuTracker.getLastSystemTime();
2246                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2247                    int irq = mProcessCpuTracker.getLastIrqTime();
2248                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2249                    int idle = mProcessCpuTracker.getLastIdleTime();
2250
2251                    int total = user + system + iowait + irq + softIrq + idle;
2252                    if (total == 0) total = 1;
2253
2254                    EventLog.writeEvent(EventLogTags.CPU,
2255                            ((user+system+iowait+irq+softIrq) * 100) / total,
2256                            (user * 100) / total,
2257                            (system * 100) / total,
2258                            (iowait * 100) / total,
2259                            (irq * 100) / total,
2260                            (softIrq * 100) / total);
2261                }
2262            }
2263
2264            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2265            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2266            synchronized(bstats) {
2267                synchronized(mPidsSelfLocked) {
2268                    if (haveNewCpuStats) {
2269                        if (mOnBattery) {
2270                            int perc = bstats.startAddingCpuLocked();
2271                            int totalUTime = 0;
2272                            int totalSTime = 0;
2273                            final int N = mProcessCpuTracker.countStats();
2274                            for (int i=0; i<N; i++) {
2275                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2276                                if (!st.working) {
2277                                    continue;
2278                                }
2279                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2280                                int otherUTime = (st.rel_utime*perc)/100;
2281                                int otherSTime = (st.rel_stime*perc)/100;
2282                                totalUTime += otherUTime;
2283                                totalSTime += otherSTime;
2284                                if (pr != null) {
2285                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2286                                    if (ps == null || !ps.isActive()) {
2287                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2288                                                pr.info.uid, pr.processName);
2289                                    }
2290                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2291                                            st.rel_stime-otherSTime);
2292                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2293                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2294                                } else {
2295                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2296                                    if (ps == null || !ps.isActive()) {
2297                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2298                                                bstats.mapUid(st.uid), st.name);
2299                                    }
2300                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2301                                            st.rel_stime-otherSTime);
2302                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2303                                }
2304                            }
2305                            bstats.finishAddingCpuLocked(perc, totalUTime,
2306                                    totalSTime, cpuSpeedTimes);
2307                        }
2308                    }
2309                }
2310
2311                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2312                    mLastWriteTime = now;
2313                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2314                }
2315            }
2316        }
2317    }
2318
2319    @Override
2320    public void batteryNeedsCpuUpdate() {
2321        updateCpuStatsNow();
2322    }
2323
2324    @Override
2325    public void batteryPowerChanged(boolean onBattery) {
2326        // When plugging in, update the CPU stats first before changing
2327        // the plug state.
2328        updateCpuStatsNow();
2329        synchronized (this) {
2330            synchronized(mPidsSelfLocked) {
2331                mOnBattery = DEBUG_POWER ? true : onBattery;
2332            }
2333        }
2334    }
2335
2336    /**
2337     * Initialize the application bind args. These are passed to each
2338     * process when the bindApplication() IPC is sent to the process. They're
2339     * lazily setup to make sure the services are running when they're asked for.
2340     */
2341    private HashMap<String, IBinder> getCommonServicesLocked() {
2342        if (mAppBindArgs == null) {
2343            mAppBindArgs = new HashMap<String, IBinder>();
2344
2345            // Setup the application init args
2346            mAppBindArgs.put("package", ServiceManager.getService("package"));
2347            mAppBindArgs.put("window", ServiceManager.getService("window"));
2348            mAppBindArgs.put(Context.ALARM_SERVICE,
2349                    ServiceManager.getService(Context.ALARM_SERVICE));
2350        }
2351        return mAppBindArgs;
2352    }
2353
2354    final void setFocusedActivityLocked(ActivityRecord r) {
2355        if (mFocusedActivity != r) {
2356            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2357            mFocusedActivity = r;
2358            if (r.task != null && r.task.voiceInteractor != null) {
2359                startRunningVoiceLocked();
2360            } else {
2361                finishRunningVoiceLocked();
2362            }
2363            mStackSupervisor.setFocusedStack(r);
2364            if (r != null) {
2365                mWindowManager.setFocusedApp(r.appToken, true);
2366            }
2367            applyUpdateLockStateLocked(r);
2368        }
2369    }
2370
2371    final void clearFocusedActivity(ActivityRecord r) {
2372        if (mFocusedActivity == r) {
2373            mFocusedActivity = null;
2374        }
2375    }
2376
2377    @Override
2378    public void setFocusedStack(int stackId) {
2379        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2380        synchronized (ActivityManagerService.this) {
2381            ActivityStack stack = mStackSupervisor.getStack(stackId);
2382            if (stack != null) {
2383                ActivityRecord r = stack.topRunningActivityLocked(null);
2384                if (r != null) {
2385                    setFocusedActivityLocked(r);
2386                }
2387            }
2388        }
2389    }
2390
2391    @Override
2392    public void notifyActivityDrawn(IBinder token) {
2393        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2394        synchronized (this) {
2395            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2396            if (r != null) {
2397                r.task.stack.notifyActivityDrawnLocked(r);
2398            }
2399        }
2400    }
2401
2402    final void applyUpdateLockStateLocked(ActivityRecord r) {
2403        // Modifications to the UpdateLock state are done on our handler, outside
2404        // the activity manager's locks.  The new state is determined based on the
2405        // state *now* of the relevant activity record.  The object is passed to
2406        // the handler solely for logging detail, not to be consulted/modified.
2407        final boolean nextState = r != null && r.immersive;
2408        mHandler.sendMessage(
2409                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2410    }
2411
2412    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2413        Message msg = Message.obtain();
2414        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2415        msg.obj = r.task.askedCompatMode ? null : r;
2416        mHandler.sendMessage(msg);
2417    }
2418
2419    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2420            String what, Object obj, ProcessRecord srcApp) {
2421        app.lastActivityTime = now;
2422
2423        if (app.activities.size() > 0) {
2424            // Don't want to touch dependent processes that are hosting activities.
2425            return index;
2426        }
2427
2428        int lrui = mLruProcesses.lastIndexOf(app);
2429        if (lrui < 0) {
2430            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2431                    + what + " " + obj + " from " + srcApp);
2432            return index;
2433        }
2434
2435        if (lrui >= index) {
2436            // Don't want to cause this to move dependent processes *back* in the
2437            // list as if they were less frequently used.
2438            return index;
2439        }
2440
2441        if (lrui >= mLruProcessActivityStart) {
2442            // Don't want to touch dependent processes that are hosting activities.
2443            return index;
2444        }
2445
2446        mLruProcesses.remove(lrui);
2447        if (index > 0) {
2448            index--;
2449        }
2450        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2451                + " in LRU list: " + app);
2452        mLruProcesses.add(index, app);
2453        return index;
2454    }
2455
2456    final void removeLruProcessLocked(ProcessRecord app) {
2457        int lrui = mLruProcesses.lastIndexOf(app);
2458        if (lrui >= 0) {
2459            if (lrui <= mLruProcessActivityStart) {
2460                mLruProcessActivityStart--;
2461            }
2462            if (lrui <= mLruProcessServiceStart) {
2463                mLruProcessServiceStart--;
2464            }
2465            mLruProcesses.remove(lrui);
2466        }
2467    }
2468
2469    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2470            ProcessRecord client) {
2471        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2472                || app.treatLikeActivity;
2473        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2474        if (!activityChange && hasActivity) {
2475            // The process has activities, so we are only allowing activity-based adjustments
2476            // to move it.  It should be kept in the front of the list with other
2477            // processes that have activities, and we don't want those to change their
2478            // order except due to activity operations.
2479            return;
2480        }
2481
2482        mLruSeq++;
2483        final long now = SystemClock.uptimeMillis();
2484        app.lastActivityTime = now;
2485
2486        // First a quick reject: if the app is already at the position we will
2487        // put it, then there is nothing to do.
2488        if (hasActivity) {
2489            final int N = mLruProcesses.size();
2490            if (N > 0 && mLruProcesses.get(N-1) == app) {
2491                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2492                return;
2493            }
2494        } else {
2495            if (mLruProcessServiceStart > 0
2496                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2497                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2498                return;
2499            }
2500        }
2501
2502        int lrui = mLruProcesses.lastIndexOf(app);
2503
2504        if (app.persistent && lrui >= 0) {
2505            // We don't care about the position of persistent processes, as long as
2506            // they are in the list.
2507            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2508            return;
2509        }
2510
2511        /* In progress: compute new position first, so we can avoid doing work
2512           if the process is not actually going to move.  Not yet working.
2513        int addIndex;
2514        int nextIndex;
2515        boolean inActivity = false, inService = false;
2516        if (hasActivity) {
2517            // Process has activities, put it at the very tipsy-top.
2518            addIndex = mLruProcesses.size();
2519            nextIndex = mLruProcessServiceStart;
2520            inActivity = true;
2521        } else if (hasService) {
2522            // Process has services, put it at the top of the service list.
2523            addIndex = mLruProcessActivityStart;
2524            nextIndex = mLruProcessServiceStart;
2525            inActivity = true;
2526            inService = true;
2527        } else  {
2528            // Process not otherwise of interest, it goes to the top of the non-service area.
2529            addIndex = mLruProcessServiceStart;
2530            if (client != null) {
2531                int clientIndex = mLruProcesses.lastIndexOf(client);
2532                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2533                        + app);
2534                if (clientIndex >= 0 && addIndex > clientIndex) {
2535                    addIndex = clientIndex;
2536                }
2537            }
2538            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2539        }
2540
2541        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2542                + mLruProcessActivityStart + "): " + app);
2543        */
2544
2545        if (lrui >= 0) {
2546            if (lrui < mLruProcessActivityStart) {
2547                mLruProcessActivityStart--;
2548            }
2549            if (lrui < mLruProcessServiceStart) {
2550                mLruProcessServiceStart--;
2551            }
2552            /*
2553            if (addIndex > lrui) {
2554                addIndex--;
2555            }
2556            if (nextIndex > lrui) {
2557                nextIndex--;
2558            }
2559            */
2560            mLruProcesses.remove(lrui);
2561        }
2562
2563        /*
2564        mLruProcesses.add(addIndex, app);
2565        if (inActivity) {
2566            mLruProcessActivityStart++;
2567        }
2568        if (inService) {
2569            mLruProcessActivityStart++;
2570        }
2571        */
2572
2573        int nextIndex;
2574        if (hasActivity) {
2575            final int N = mLruProcesses.size();
2576            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2577                // Process doesn't have activities, but has clients with
2578                // activities...  move it up, but one below the top (the top
2579                // should always have a real activity).
2580                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2581                mLruProcesses.add(N-1, app);
2582                // To keep it from spamming the LRU list (by making a bunch of clients),
2583                // we will push down any other entries owned by the app.
2584                final int uid = app.info.uid;
2585                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2586                    ProcessRecord subProc = mLruProcesses.get(i);
2587                    if (subProc.info.uid == uid) {
2588                        // We want to push this one down the list.  If the process after
2589                        // it is for the same uid, however, don't do so, because we don't
2590                        // want them internally to be re-ordered.
2591                        if (mLruProcesses.get(i-1).info.uid != uid) {
2592                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2593                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2594                            ProcessRecord tmp = mLruProcesses.get(i);
2595                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2596                            mLruProcesses.set(i-1, tmp);
2597                            i--;
2598                        }
2599                    } else {
2600                        // A gap, we can stop here.
2601                        break;
2602                    }
2603                }
2604            } else {
2605                // Process has activities, put it at the very tipsy-top.
2606                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2607                mLruProcesses.add(app);
2608            }
2609            nextIndex = mLruProcessServiceStart;
2610        } else if (hasService) {
2611            // Process has services, put it at the top of the service list.
2612            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2613            mLruProcesses.add(mLruProcessActivityStart, app);
2614            nextIndex = mLruProcessServiceStart;
2615            mLruProcessActivityStart++;
2616        } else  {
2617            // Process not otherwise of interest, it goes to the top of the non-service area.
2618            int index = mLruProcessServiceStart;
2619            if (client != null) {
2620                // If there is a client, don't allow the process to be moved up higher
2621                // in the list than that client.
2622                int clientIndex = mLruProcesses.lastIndexOf(client);
2623                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2624                        + " when updating " + app);
2625                if (clientIndex <= lrui) {
2626                    // Don't allow the client index restriction to push it down farther in the
2627                    // list than it already is.
2628                    clientIndex = lrui;
2629                }
2630                if (clientIndex >= 0 && index > clientIndex) {
2631                    index = clientIndex;
2632                }
2633            }
2634            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2635            mLruProcesses.add(index, app);
2636            nextIndex = index-1;
2637            mLruProcessActivityStart++;
2638            mLruProcessServiceStart++;
2639        }
2640
2641        // If the app is currently using a content provider or service,
2642        // bump those processes as well.
2643        for (int j=app.connections.size()-1; j>=0; j--) {
2644            ConnectionRecord cr = app.connections.valueAt(j);
2645            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2646                    && cr.binding.service.app != null
2647                    && cr.binding.service.app.lruSeq != mLruSeq
2648                    && !cr.binding.service.app.persistent) {
2649                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2650                        "service connection", cr, app);
2651            }
2652        }
2653        for (int j=app.conProviders.size()-1; j>=0; j--) {
2654            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2655            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2656                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2657                        "provider reference", cpr, app);
2658            }
2659        }
2660    }
2661
2662    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2663        if (uid == Process.SYSTEM_UID) {
2664            // The system gets to run in any process.  If there are multiple
2665            // processes with the same uid, just pick the first (this
2666            // should never happen).
2667            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2668            if (procs == null) return null;
2669            final int N = procs.size();
2670            for (int i = 0; i < N; i++) {
2671                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2672            }
2673        }
2674        ProcessRecord proc = mProcessNames.get(processName, uid);
2675        if (false && proc != null && !keepIfLarge
2676                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2677                && proc.lastCachedPss >= 4000) {
2678            // Turn this condition on to cause killing to happen regularly, for testing.
2679            if (proc.baseProcessTracker != null) {
2680                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2681            }
2682            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2683                    + "k from cached");
2684        } else if (proc != null && !keepIfLarge
2685                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2686                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2687            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2688            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2689                if (proc.baseProcessTracker != null) {
2690                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2691                }
2692                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2693                        + "k from cached");
2694            }
2695        }
2696        return proc;
2697    }
2698
2699    void ensurePackageDexOpt(String packageName) {
2700        IPackageManager pm = AppGlobals.getPackageManager();
2701        try {
2702            if (pm.performDexOpt(packageName)) {
2703                mDidDexOpt = true;
2704            }
2705        } catch (RemoteException e) {
2706        }
2707    }
2708
2709    boolean isNextTransitionForward() {
2710        int transit = mWindowManager.getPendingAppTransition();
2711        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2712                || transit == AppTransition.TRANSIT_TASK_OPEN
2713                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2714    }
2715
2716    final ProcessRecord startProcessLocked(String processName,
2717            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2718            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2719            boolean isolated, boolean keepIfLarge) {
2720        ProcessRecord app;
2721        if (!isolated) {
2722            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2723        } else {
2724            // If this is an isolated process, it can't re-use an existing process.
2725            app = null;
2726        }
2727        // We don't have to do anything more if:
2728        // (1) There is an existing application record; and
2729        // (2) The caller doesn't think it is dead, OR there is no thread
2730        //     object attached to it so we know it couldn't have crashed; and
2731        // (3) There is a pid assigned to it, so it is either starting or
2732        //     already running.
2733        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2734                + " app=" + app + " knownToBeDead=" + knownToBeDead
2735                + " thread=" + (app != null ? app.thread : null)
2736                + " pid=" + (app != null ? app.pid : -1));
2737        if (app != null && app.pid > 0) {
2738            if (!knownToBeDead || app.thread == null) {
2739                // We already have the app running, or are waiting for it to
2740                // come up (we have a pid but not yet its thread), so keep it.
2741                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2742                // If this is a new package in the process, add the package to the list
2743                app.addPackage(info.packageName, mProcessStats);
2744                return app;
2745            }
2746
2747            // An application record is attached to a previous process,
2748            // clean it up now.
2749            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2750            handleAppDiedLocked(app, true, true);
2751        }
2752
2753        String hostingNameStr = hostingName != null
2754                ? hostingName.flattenToShortString() : null;
2755
2756        if (!isolated) {
2757            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2758                // If we are in the background, then check to see if this process
2759                // is bad.  If so, we will just silently fail.
2760                if (mBadProcesses.get(info.processName, info.uid) != null) {
2761                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2762                            + "/" + info.processName);
2763                    return null;
2764                }
2765            } else {
2766                // When the user is explicitly starting a process, then clear its
2767                // crash count so that we won't make it bad until they see at
2768                // least one crash dialog again, and make the process good again
2769                // if it had been bad.
2770                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2771                        + "/" + info.processName);
2772                mProcessCrashTimes.remove(info.processName, info.uid);
2773                if (mBadProcesses.get(info.processName, info.uid) != null) {
2774                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2775                            UserHandle.getUserId(info.uid), info.uid,
2776                            info.processName);
2777                    mBadProcesses.remove(info.processName, info.uid);
2778                    if (app != null) {
2779                        app.bad = false;
2780                    }
2781                }
2782            }
2783        }
2784
2785        if (app == null) {
2786            app = newProcessRecordLocked(info, processName, isolated);
2787            if (app == null) {
2788                Slog.w(TAG, "Failed making new process record for "
2789                        + processName + "/" + info.uid + " isolated=" + isolated);
2790                return null;
2791            }
2792            mProcessNames.put(processName, app.uid, app);
2793            if (isolated) {
2794                mIsolatedProcesses.put(app.uid, app);
2795            }
2796        } else {
2797            // If this is a new package in the process, add the package to the list
2798            app.addPackage(info.packageName, mProcessStats);
2799        }
2800
2801        // If the system is not ready yet, then hold off on starting this
2802        // process until it is.
2803        if (!mProcessesReady
2804                && !isAllowedWhileBooting(info)
2805                && !allowWhileBooting) {
2806            if (!mProcessesOnHold.contains(app)) {
2807                mProcessesOnHold.add(app);
2808            }
2809            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2810            return app;
2811        }
2812
2813        startProcessLocked(app, hostingType, hostingNameStr);
2814        return (app.pid != 0) ? app : null;
2815    }
2816
2817    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2818        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2819    }
2820
2821    private final void startProcessLocked(ProcessRecord app,
2822            String hostingType, String hostingNameStr) {
2823        if (app.pid > 0 && app.pid != MY_PID) {
2824            synchronized (mPidsSelfLocked) {
2825                mPidsSelfLocked.remove(app.pid);
2826                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2827            }
2828            app.setPid(0);
2829        }
2830
2831        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2832                "startProcessLocked removing on hold: " + app);
2833        mProcessesOnHold.remove(app);
2834
2835        updateCpuStats();
2836
2837        try {
2838            int uid = app.uid;
2839
2840            int[] gids = null;
2841            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2842            if (!app.isolated) {
2843                int[] permGids = null;
2844                try {
2845                    final PackageManager pm = mContext.getPackageManager();
2846                    permGids = pm.getPackageGids(app.info.packageName);
2847
2848                    if (Environment.isExternalStorageEmulated()) {
2849                        if (pm.checkPermission(
2850                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2851                                app.info.packageName) == PERMISSION_GRANTED) {
2852                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2853                        } else {
2854                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2855                        }
2856                    }
2857                } catch (PackageManager.NameNotFoundException e) {
2858                    Slog.w(TAG, "Unable to retrieve gids", e);
2859                }
2860
2861                /*
2862                 * Add shared application GID so applications can share some
2863                 * resources like shared libraries
2864                 */
2865                if (permGids == null) {
2866                    gids = new int[1];
2867                } else {
2868                    gids = new int[permGids.length + 1];
2869                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2870                }
2871                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2872            }
2873            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2874                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2875                        && mTopComponent != null
2876                        && app.processName.equals(mTopComponent.getPackageName())) {
2877                    uid = 0;
2878                }
2879                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2880                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2881                    uid = 0;
2882                }
2883            }
2884            int debugFlags = 0;
2885            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2886                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2887                // Also turn on CheckJNI for debuggable apps. It's quite
2888                // awkward to turn on otherwise.
2889                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2890            }
2891            // Run the app in safe mode if its manifest requests so or the
2892            // system is booted in safe mode.
2893            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2894                mSafeMode == true) {
2895                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2896            }
2897            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2898                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2899            }
2900            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2901                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2902            }
2903            if ("1".equals(SystemProperties.get("debug.assert"))) {
2904                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2905            }
2906
2907            String requiredAbi = app.info.requiredCpuAbi;
2908            if (requiredAbi == null) {
2909                requiredAbi = Build.SUPPORTED_ABIS[0];
2910            }
2911
2912            // Start the process.  It will either succeed and return a result containing
2913            // the PID of the new process, or else throw a RuntimeException.
2914            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2915                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2916                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2917
2918            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2919            synchronized (bs) {
2920                if (bs.isOnBattery()) {
2921                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2922                }
2923            }
2924
2925            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2926                    UserHandle.getUserId(uid), startResult.pid, uid,
2927                    app.processName, hostingType,
2928                    hostingNameStr != null ? hostingNameStr : "");
2929
2930            if (app.persistent) {
2931                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2932            }
2933
2934            StringBuilder buf = mStringBuilder;
2935            buf.setLength(0);
2936            buf.append("Start proc ");
2937            buf.append(app.processName);
2938            buf.append(" for ");
2939            buf.append(hostingType);
2940            if (hostingNameStr != null) {
2941                buf.append(" ");
2942                buf.append(hostingNameStr);
2943            }
2944            buf.append(": pid=");
2945            buf.append(startResult.pid);
2946            buf.append(" uid=");
2947            buf.append(uid);
2948            buf.append(" gids={");
2949            if (gids != null) {
2950                for (int gi=0; gi<gids.length; gi++) {
2951                    if (gi != 0) buf.append(", ");
2952                    buf.append(gids[gi]);
2953
2954                }
2955            }
2956            buf.append("}");
2957            Slog.i(TAG, buf.toString());
2958            app.setPid(startResult.pid);
2959            app.usingWrapper = startResult.usingWrapper;
2960            app.removed = false;
2961            synchronized (mPidsSelfLocked) {
2962                this.mPidsSelfLocked.put(startResult.pid, app);
2963                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2964                msg.obj = app;
2965                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2966                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2967            }
2968            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2969                    app.processName, app.info.uid);
2970            if (app.isolated) {
2971                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2972            }
2973        } catch (RuntimeException e) {
2974            // XXX do better error recovery.
2975            app.setPid(0);
2976            Slog.e(TAG, "Failure starting process " + app.processName, e);
2977        }
2978    }
2979
2980    void updateUsageStats(ActivityRecord component, boolean resumed) {
2981        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2982        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2983        if (resumed) {
2984            mUsageStatsService.noteResumeComponent(component.realActivity);
2985            synchronized (stats) {
2986                stats.noteActivityResumedLocked(component.app.uid);
2987            }
2988        } else {
2989            mUsageStatsService.notePauseComponent(component.realActivity);
2990            synchronized (stats) {
2991                stats.noteActivityPausedLocked(component.app.uid);
2992            }
2993        }
2994    }
2995
2996    Intent getHomeIntent() {
2997        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2998        intent.setComponent(mTopComponent);
2999        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3000            intent.addCategory(Intent.CATEGORY_HOME);
3001        }
3002        return intent;
3003    }
3004
3005    boolean startHomeActivityLocked(int userId) {
3006        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3007                && mTopAction == null) {
3008            // We are running in factory test mode, but unable to find
3009            // the factory test app, so just sit around displaying the
3010            // error message and don't try to start anything.
3011            return false;
3012        }
3013        Intent intent = getHomeIntent();
3014        ActivityInfo aInfo =
3015            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3016        if (aInfo != null) {
3017            intent.setComponent(new ComponentName(
3018                    aInfo.applicationInfo.packageName, aInfo.name));
3019            // Don't do this if the home app is currently being
3020            // instrumented.
3021            aInfo = new ActivityInfo(aInfo);
3022            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3023            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3024                    aInfo.applicationInfo.uid, true);
3025            if (app == null || app.instrumentationClass == null) {
3026                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3027                mStackSupervisor.startHomeActivity(intent, aInfo);
3028            }
3029        }
3030
3031        return true;
3032    }
3033
3034    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3035        ActivityInfo ai = null;
3036        ComponentName comp = intent.getComponent();
3037        try {
3038            if (comp != null) {
3039                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3040            } else {
3041                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3042                        intent,
3043                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3044                            flags, userId);
3045
3046                if (info != null) {
3047                    ai = info.activityInfo;
3048                }
3049            }
3050        } catch (RemoteException e) {
3051            // ignore
3052        }
3053
3054        return ai;
3055    }
3056
3057    /**
3058     * Starts the "new version setup screen" if appropriate.
3059     */
3060    void startSetupActivityLocked() {
3061        // Only do this once per boot.
3062        if (mCheckedForSetup) {
3063            return;
3064        }
3065
3066        // We will show this screen if the current one is a different
3067        // version than the last one shown, and we are not running in
3068        // low-level factory test mode.
3069        final ContentResolver resolver = mContext.getContentResolver();
3070        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3071                Settings.Global.getInt(resolver,
3072                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3073            mCheckedForSetup = true;
3074
3075            // See if we should be showing the platform update setup UI.
3076            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3077            List<ResolveInfo> ris = mContext.getPackageManager()
3078                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3079
3080            // We don't allow third party apps to replace this.
3081            ResolveInfo ri = null;
3082            for (int i=0; ris != null && i<ris.size(); i++) {
3083                if ((ris.get(i).activityInfo.applicationInfo.flags
3084                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3085                    ri = ris.get(i);
3086                    break;
3087                }
3088            }
3089
3090            if (ri != null) {
3091                String vers = ri.activityInfo.metaData != null
3092                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3093                        : null;
3094                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3095                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3096                            Intent.METADATA_SETUP_VERSION);
3097                }
3098                String lastVers = Settings.Secure.getString(
3099                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3100                if (vers != null && !vers.equals(lastVers)) {
3101                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3102                    intent.setComponent(new ComponentName(
3103                            ri.activityInfo.packageName, ri.activityInfo.name));
3104                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3105                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3106                }
3107            }
3108        }
3109    }
3110
3111    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3112        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3113    }
3114
3115    void enforceNotIsolatedCaller(String caller) {
3116        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3117            throw new SecurityException("Isolated process not allowed to call " + caller);
3118        }
3119    }
3120
3121    @Override
3122    public int getFrontActivityScreenCompatMode() {
3123        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3124        synchronized (this) {
3125            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3126        }
3127    }
3128
3129    @Override
3130    public void setFrontActivityScreenCompatMode(int mode) {
3131        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3132                "setFrontActivityScreenCompatMode");
3133        synchronized (this) {
3134            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3135        }
3136    }
3137
3138    @Override
3139    public int getPackageScreenCompatMode(String packageName) {
3140        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3141        synchronized (this) {
3142            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3143        }
3144    }
3145
3146    @Override
3147    public void setPackageScreenCompatMode(String packageName, int mode) {
3148        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3149                "setPackageScreenCompatMode");
3150        synchronized (this) {
3151            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3152        }
3153    }
3154
3155    @Override
3156    public boolean getPackageAskScreenCompat(String packageName) {
3157        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3158        synchronized (this) {
3159            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3160        }
3161    }
3162
3163    @Override
3164    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3165        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3166                "setPackageAskScreenCompat");
3167        synchronized (this) {
3168            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3169        }
3170    }
3171
3172    private void dispatchProcessesChanged() {
3173        int N;
3174        synchronized (this) {
3175            N = mPendingProcessChanges.size();
3176            if (mActiveProcessChanges.length < N) {
3177                mActiveProcessChanges = new ProcessChangeItem[N];
3178            }
3179            mPendingProcessChanges.toArray(mActiveProcessChanges);
3180            mAvailProcessChanges.addAll(mPendingProcessChanges);
3181            mPendingProcessChanges.clear();
3182            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3183        }
3184
3185        int i = mProcessObservers.beginBroadcast();
3186        while (i > 0) {
3187            i--;
3188            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3189            if (observer != null) {
3190                try {
3191                    for (int j=0; j<N; j++) {
3192                        ProcessChangeItem item = mActiveProcessChanges[j];
3193                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3194                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3195                                    + item.pid + " uid=" + item.uid + ": "
3196                                    + item.foregroundActivities);
3197                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3198                                    item.foregroundActivities);
3199                        }
3200                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3201                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3202                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3203                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3204                        }
3205                    }
3206                } catch (RemoteException e) {
3207                }
3208            }
3209        }
3210        mProcessObservers.finishBroadcast();
3211    }
3212
3213    private void dispatchProcessDied(int pid, int uid) {
3214        int i = mProcessObservers.beginBroadcast();
3215        while (i > 0) {
3216            i--;
3217            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3218            if (observer != null) {
3219                try {
3220                    observer.onProcessDied(pid, uid);
3221                } catch (RemoteException e) {
3222                }
3223            }
3224        }
3225        mProcessObservers.finishBroadcast();
3226    }
3227
3228    final void doPendingActivityLaunchesLocked(boolean doResume) {
3229        final int N = mPendingActivityLaunches.size();
3230        if (N <= 0) {
3231            return;
3232        }
3233        for (int i=0; i<N; i++) {
3234            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3235            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3236                    doResume && i == (N-1), null);
3237        }
3238        mPendingActivityLaunches.clear();
3239    }
3240
3241    @Override
3242    public final int startActivity(IApplicationThread caller, String callingPackage,
3243            Intent intent, String resolvedType, IBinder resultTo,
3244            String resultWho, int requestCode, int startFlags,
3245            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3246        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3247                resultWho, requestCode,
3248                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3249    }
3250
3251    @Override
3252    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3253            Intent intent, String resolvedType, IBinder resultTo,
3254            String resultWho, int requestCode, int startFlags,
3255            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3256        enforceNotIsolatedCaller("startActivity");
3257        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3258                false, true, "startActivity", null);
3259        // TODO: Switch to user app stacks here.
3260        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3261                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3262                null, null, options, userId, null);
3263    }
3264
3265    @Override
3266    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3267            Intent intent, String resolvedType, IBinder resultTo,
3268            String resultWho, int requestCode, int startFlags, String profileFile,
3269            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3270        enforceNotIsolatedCaller("startActivityAndWait");
3271        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3272                false, true, "startActivityAndWait", null);
3273        WaitResult res = new WaitResult();
3274        // TODO: Switch to user app stacks here.
3275        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3276                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3277                res, null, options, UserHandle.getCallingUserId(), null);
3278        return res;
3279    }
3280
3281    @Override
3282    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3283            Intent intent, String resolvedType, IBinder resultTo,
3284            String resultWho, int requestCode, int startFlags, Configuration config,
3285            Bundle options, int userId) {
3286        enforceNotIsolatedCaller("startActivityWithConfig");
3287        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3288                false, true, "startActivityWithConfig", null);
3289        // TODO: Switch to user app stacks here.
3290        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3291                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3292                null, null, null, config, options, userId, null);
3293        return ret;
3294    }
3295
3296    @Override
3297    public int startActivityIntentSender(IApplicationThread caller,
3298            IntentSender intent, Intent fillInIntent, String resolvedType,
3299            IBinder resultTo, String resultWho, int requestCode,
3300            int flagsMask, int flagsValues, Bundle options) {
3301        enforceNotIsolatedCaller("startActivityIntentSender");
3302        // Refuse possible leaked file descriptors
3303        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3304            throw new IllegalArgumentException("File descriptors passed in Intent");
3305        }
3306
3307        IIntentSender sender = intent.getTarget();
3308        if (!(sender instanceof PendingIntentRecord)) {
3309            throw new IllegalArgumentException("Bad PendingIntent object");
3310        }
3311
3312        PendingIntentRecord pir = (PendingIntentRecord)sender;
3313
3314        synchronized (this) {
3315            // If this is coming from the currently resumed activity, it is
3316            // effectively saying that app switches are allowed at this point.
3317            final ActivityStack stack = getFocusedStack();
3318            if (stack.mResumedActivity != null &&
3319                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3320                mAppSwitchesAllowedTime = 0;
3321            }
3322        }
3323        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3324                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3325        return ret;
3326    }
3327
3328    @Override
3329    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3330            Intent intent, String resolvedType, IVoiceInteractionSession session,
3331            IVoiceInteractor interactor, int startFlags, String profileFile,
3332            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3333        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3334                != PackageManager.PERMISSION_GRANTED) {
3335            String msg = "Permission Denial: startVoiceActivity() from pid="
3336                    + Binder.getCallingPid()
3337                    + ", uid=" + Binder.getCallingUid()
3338                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3339            Slog.w(TAG, msg);
3340            throw new SecurityException(msg);
3341        }
3342        if (session == null || interactor == null) {
3343            throw new NullPointerException("null session or interactor");
3344        }
3345        userId = handleIncomingUser(callingPid, callingUid, userId,
3346                false, true, "startVoiceActivity", null);
3347        // TODO: Switch to user app stacks here.
3348        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3349                resolvedType, session, interactor, null, null, 0, startFlags,
3350                profileFile, profileFd, null, null, options, userId, null);
3351    }
3352
3353    @Override
3354    public boolean startNextMatchingActivity(IBinder callingActivity,
3355            Intent intent, Bundle options) {
3356        // Refuse possible leaked file descriptors
3357        if (intent != null && intent.hasFileDescriptors() == true) {
3358            throw new IllegalArgumentException("File descriptors passed in Intent");
3359        }
3360
3361        synchronized (this) {
3362            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3363            if (r == null) {
3364                ActivityOptions.abort(options);
3365                return false;
3366            }
3367            if (r.app == null || r.app.thread == null) {
3368                // The caller is not running...  d'oh!
3369                ActivityOptions.abort(options);
3370                return false;
3371            }
3372            intent = new Intent(intent);
3373            // The caller is not allowed to change the data.
3374            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3375            // And we are resetting to find the next component...
3376            intent.setComponent(null);
3377
3378            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3379
3380            ActivityInfo aInfo = null;
3381            try {
3382                List<ResolveInfo> resolves =
3383                    AppGlobals.getPackageManager().queryIntentActivities(
3384                            intent, r.resolvedType,
3385                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3386                            UserHandle.getCallingUserId());
3387
3388                // Look for the original activity in the list...
3389                final int N = resolves != null ? resolves.size() : 0;
3390                for (int i=0; i<N; i++) {
3391                    ResolveInfo rInfo = resolves.get(i);
3392                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3393                            && rInfo.activityInfo.name.equals(r.info.name)) {
3394                        // We found the current one...  the next matching is
3395                        // after it.
3396                        i++;
3397                        if (i<N) {
3398                            aInfo = resolves.get(i).activityInfo;
3399                        }
3400                        if (debug) {
3401                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3402                                    + "/" + r.info.name);
3403                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3404                                    + "/" + aInfo.name);
3405                        }
3406                        break;
3407                    }
3408                }
3409            } catch (RemoteException e) {
3410            }
3411
3412            if (aInfo == null) {
3413                // Nobody who is next!
3414                ActivityOptions.abort(options);
3415                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3416                return false;
3417            }
3418
3419            intent.setComponent(new ComponentName(
3420                    aInfo.applicationInfo.packageName, aInfo.name));
3421            intent.setFlags(intent.getFlags()&~(
3422                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3423                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3424                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3425                    Intent.FLAG_ACTIVITY_NEW_TASK));
3426
3427            // Okay now we need to start the new activity, replacing the
3428            // currently running activity.  This is a little tricky because
3429            // we want to start the new one as if the current one is finished,
3430            // but not finish the current one first so that there is no flicker.
3431            // And thus...
3432            final boolean wasFinishing = r.finishing;
3433            r.finishing = true;
3434
3435            // Propagate reply information over to the new activity.
3436            final ActivityRecord resultTo = r.resultTo;
3437            final String resultWho = r.resultWho;
3438            final int requestCode = r.requestCode;
3439            r.resultTo = null;
3440            if (resultTo != null) {
3441                resultTo.removeResultsLocked(r, resultWho, requestCode);
3442            }
3443
3444            final long origId = Binder.clearCallingIdentity();
3445            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3446                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3447                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3448                    options, false, null, null);
3449            Binder.restoreCallingIdentity(origId);
3450
3451            r.finishing = wasFinishing;
3452            if (res != ActivityManager.START_SUCCESS) {
3453                return false;
3454            }
3455            return true;
3456        }
3457    }
3458
3459    final int startActivityInPackage(int uid, String callingPackage,
3460            Intent intent, String resolvedType, IBinder resultTo,
3461            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3462                    IActivityContainer container) {
3463
3464        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3465                false, true, "startActivityInPackage", null);
3466
3467        // TODO: Switch to user app stacks here.
3468        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3469                null, null, resultTo, resultWho, requestCode, startFlags,
3470                null, null, null, null, options, userId, container);
3471        return ret;
3472    }
3473
3474    @Override
3475    public final int startActivities(IApplicationThread caller, String callingPackage,
3476            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3477            int userId) {
3478        enforceNotIsolatedCaller("startActivities");
3479        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3480                false, true, "startActivity", null);
3481        // TODO: Switch to user app stacks here.
3482        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3483                resolvedTypes, resultTo, options, userId);
3484        return ret;
3485    }
3486
3487    final int startActivitiesInPackage(int uid, String callingPackage,
3488            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3489            Bundle options, int userId) {
3490
3491        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3492                false, true, "startActivityInPackage", null);
3493        // TODO: Switch to user app stacks here.
3494        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3495                resultTo, options, userId);
3496        return ret;
3497    }
3498
3499    final void addRecentTaskLocked(TaskRecord task) {
3500        int N = mRecentTasks.size();
3501        // Quick case: check if the top-most recent task is the same.
3502        if (N > 0 && mRecentTasks.get(0) == task) {
3503            return;
3504        }
3505        // Another quick case: never add voice sessions.
3506        if (task.voiceSession != null) {
3507            return;
3508        }
3509        // Remove any existing entries that are the same kind of task.
3510        final Intent intent = task.intent;
3511        final boolean document = intent != null && intent.isDocument();
3512        for (int i=0; i<N; i++) {
3513            TaskRecord tr = mRecentTasks.get(i);
3514            if (task != tr) {
3515                if (task.userId != tr.userId) {
3516                    continue;
3517                }
3518                final Intent trIntent = tr.intent;
3519                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3520                    (intent == null || !intent.filterEquals(trIntent))) {
3521                    continue;
3522                }
3523                if (document || trIntent != null && trIntent.isDocument()) {
3524                    // Document tasks do not match other tasks.
3525                    continue;
3526                }
3527            }
3528
3529            // Either task and tr are the same or, their affinities match or their intents match
3530            // and neither of them is a document.
3531            tr.disposeThumbnail();
3532            mRecentTasks.remove(i);
3533            i--;
3534            N--;
3535            if (task.intent == null) {
3536                // If the new recent task we are adding is not fully
3537                // specified, then replace it with the existing recent task.
3538                task = tr;
3539            }
3540        }
3541        if (N >= MAX_RECENT_TASKS) {
3542            mRecentTasks.remove(N-1).disposeThumbnail();
3543        }
3544        mRecentTasks.add(0, task);
3545    }
3546
3547    @Override
3548    public void reportActivityFullyDrawn(IBinder token) {
3549        synchronized (this) {
3550            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3551            if (r == null) {
3552                return;
3553            }
3554            r.reportFullyDrawnLocked();
3555        }
3556    }
3557
3558    @Override
3559    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3560        synchronized (this) {
3561            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3562            if (r == null) {
3563                return;
3564            }
3565            final long origId = Binder.clearCallingIdentity();
3566            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3567            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3568                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3569            if (config != null) {
3570                r.frozenBeforeDestroy = true;
3571                if (!updateConfigurationLocked(config, r, false, false)) {
3572                    mStackSupervisor.resumeTopActivitiesLocked();
3573                }
3574            }
3575            Binder.restoreCallingIdentity(origId);
3576        }
3577    }
3578
3579    @Override
3580    public int getRequestedOrientation(IBinder token) {
3581        synchronized (this) {
3582            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3583            if (r == null) {
3584                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3585            }
3586            return mWindowManager.getAppOrientation(r.appToken);
3587        }
3588    }
3589
3590    /**
3591     * This is the internal entry point for handling Activity.finish().
3592     *
3593     * @param token The Binder token referencing the Activity we want to finish.
3594     * @param resultCode Result code, if any, from this Activity.
3595     * @param resultData Result data (Intent), if any, from this Activity.
3596     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3597     *            the root Activity in the task.
3598     *
3599     * @return Returns true if the activity successfully finished, or false if it is still running.
3600     */
3601    @Override
3602    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3603            boolean finishTask) {
3604        // Refuse possible leaked file descriptors
3605        if (resultData != null && resultData.hasFileDescriptors() == true) {
3606            throw new IllegalArgumentException("File descriptors passed in Intent");
3607        }
3608
3609        synchronized(this) {
3610            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3611            if (r == null) {
3612                return true;
3613            }
3614            // Keep track of the root activity of the task before we finish it
3615            TaskRecord tr = r.task;
3616            ActivityRecord rootR = tr.getRootActivity();
3617            if (mController != null) {
3618                // Find the first activity that is not finishing.
3619                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3620                if (next != null) {
3621                    // ask watcher if this is allowed
3622                    boolean resumeOK = true;
3623                    try {
3624                        resumeOK = mController.activityResuming(next.packageName);
3625                    } catch (RemoteException e) {
3626                        mController = null;
3627                        Watchdog.getInstance().setActivityController(null);
3628                    }
3629
3630                    if (!resumeOK) {
3631                        return false;
3632                    }
3633                }
3634            }
3635            final long origId = Binder.clearCallingIdentity();
3636            try {
3637                boolean res;
3638                if (finishTask && r == rootR) {
3639                    // If requested, remove the task that is associated to this activity only if it
3640                    // was the root activity in the task.  The result code and data is ignored because
3641                    // we don't support returning them across task boundaries.
3642                    res = removeTaskByIdLocked(tr.taskId, 0);
3643                } else {
3644                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3645                            resultData, "app-request", true);
3646                }
3647                return res;
3648            } finally {
3649                Binder.restoreCallingIdentity(origId);
3650            }
3651        }
3652    }
3653
3654    @Override
3655    public final void finishHeavyWeightApp() {
3656        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3657                != PackageManager.PERMISSION_GRANTED) {
3658            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3659                    + Binder.getCallingPid()
3660                    + ", uid=" + Binder.getCallingUid()
3661                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3662            Slog.w(TAG, msg);
3663            throw new SecurityException(msg);
3664        }
3665
3666        synchronized(this) {
3667            if (mHeavyWeightProcess == null) {
3668                return;
3669            }
3670
3671            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3672                    mHeavyWeightProcess.activities);
3673            for (int i=0; i<activities.size(); i++) {
3674                ActivityRecord r = activities.get(i);
3675                if (!r.finishing) {
3676                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3677                            null, "finish-heavy", true);
3678                }
3679            }
3680
3681            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3682                    mHeavyWeightProcess.userId, 0));
3683            mHeavyWeightProcess = null;
3684        }
3685    }
3686
3687    @Override
3688    public void crashApplication(int uid, int initialPid, String packageName,
3689            String message) {
3690        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3691                != PackageManager.PERMISSION_GRANTED) {
3692            String msg = "Permission Denial: crashApplication() from pid="
3693                    + Binder.getCallingPid()
3694                    + ", uid=" + Binder.getCallingUid()
3695                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3696            Slog.w(TAG, msg);
3697            throw new SecurityException(msg);
3698        }
3699
3700        synchronized(this) {
3701            ProcessRecord proc = null;
3702
3703            // Figure out which process to kill.  We don't trust that initialPid
3704            // still has any relation to current pids, so must scan through the
3705            // list.
3706            synchronized (mPidsSelfLocked) {
3707                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3708                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3709                    if (p.uid != uid) {
3710                        continue;
3711                    }
3712                    if (p.pid == initialPid) {
3713                        proc = p;
3714                        break;
3715                    }
3716                    if (p.pkgList.containsKey(packageName)) {
3717                        proc = p;
3718                    }
3719                }
3720            }
3721
3722            if (proc == null) {
3723                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3724                        + " initialPid=" + initialPid
3725                        + " packageName=" + packageName);
3726                return;
3727            }
3728
3729            if (proc.thread != null) {
3730                if (proc.pid == Process.myPid()) {
3731                    Log.w(TAG, "crashApplication: trying to crash self!");
3732                    return;
3733                }
3734                long ident = Binder.clearCallingIdentity();
3735                try {
3736                    proc.thread.scheduleCrash(message);
3737                } catch (RemoteException e) {
3738                }
3739                Binder.restoreCallingIdentity(ident);
3740            }
3741        }
3742    }
3743
3744    @Override
3745    public final void finishSubActivity(IBinder token, String resultWho,
3746            int requestCode) {
3747        synchronized(this) {
3748            final long origId = Binder.clearCallingIdentity();
3749            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3750            if (r != null) {
3751                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3752            }
3753            Binder.restoreCallingIdentity(origId);
3754        }
3755    }
3756
3757    @Override
3758    public boolean finishActivityAffinity(IBinder token) {
3759        synchronized(this) {
3760            final long origId = Binder.clearCallingIdentity();
3761            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3762            boolean res = false;
3763            if (r != null) {
3764                res = r.task.stack.finishActivityAffinityLocked(r);
3765            }
3766            Binder.restoreCallingIdentity(origId);
3767            return res;
3768        }
3769    }
3770
3771    @Override
3772    public boolean willActivityBeVisible(IBinder token) {
3773        synchronized(this) {
3774            ActivityStack stack = ActivityRecord.getStackLocked(token);
3775            if (stack != null) {
3776                return stack.willActivityBeVisibleLocked(token);
3777            }
3778            return false;
3779        }
3780    }
3781
3782    @Override
3783    public void overridePendingTransition(IBinder token, String packageName,
3784            int enterAnim, int exitAnim) {
3785        synchronized(this) {
3786            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3787            if (self == null) {
3788                return;
3789            }
3790
3791            final long origId = Binder.clearCallingIdentity();
3792
3793            if (self.state == ActivityState.RESUMED
3794                    || self.state == ActivityState.PAUSING) {
3795                mWindowManager.overridePendingAppTransition(packageName,
3796                        enterAnim, exitAnim, null);
3797            }
3798
3799            Binder.restoreCallingIdentity(origId);
3800        }
3801    }
3802
3803    /**
3804     * Main function for removing an existing process from the activity manager
3805     * as a result of that process going away.  Clears out all connections
3806     * to the process.
3807     */
3808    private final void handleAppDiedLocked(ProcessRecord app,
3809            boolean restarting, boolean allowRestart) {
3810        int pid = app.pid;
3811        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3812        if (!restarting) {
3813            removeLruProcessLocked(app);
3814            if (pid > 0) {
3815                ProcessList.remove(pid);
3816            }
3817        }
3818
3819        if (mProfileProc == app) {
3820            clearProfilerLocked();
3821        }
3822
3823        // Remove this application's activities from active lists.
3824        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3825
3826        app.activities.clear();
3827
3828        if (app.instrumentationClass != null) {
3829            Slog.w(TAG, "Crash of app " + app.processName
3830                  + " running instrumentation " + app.instrumentationClass);
3831            Bundle info = new Bundle();
3832            info.putString("shortMsg", "Process crashed.");
3833            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3834        }
3835
3836        if (!restarting) {
3837            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3838                // If there was nothing to resume, and we are not already
3839                // restarting this process, but there is a visible activity that
3840                // is hosted by the process...  then make sure all visible
3841                // activities are running, taking care of restarting this
3842                // process.
3843                if (hasVisibleActivities) {
3844                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3845                }
3846            }
3847        }
3848    }
3849
3850    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3851        IBinder threadBinder = thread.asBinder();
3852        // Find the application record.
3853        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3854            ProcessRecord rec = mLruProcesses.get(i);
3855            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3856                return i;
3857            }
3858        }
3859        return -1;
3860    }
3861
3862    final ProcessRecord getRecordForAppLocked(
3863            IApplicationThread thread) {
3864        if (thread == null) {
3865            return null;
3866        }
3867
3868        int appIndex = getLRURecordIndexForAppLocked(thread);
3869        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3870    }
3871
3872    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3873        // If there are no longer any background processes running,
3874        // and the app that died was not running instrumentation,
3875        // then tell everyone we are now low on memory.
3876        boolean haveBg = false;
3877        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3878            ProcessRecord rec = mLruProcesses.get(i);
3879            if (rec.thread != null
3880                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3881                haveBg = true;
3882                break;
3883            }
3884        }
3885
3886        if (!haveBg) {
3887            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3888            if (doReport) {
3889                long now = SystemClock.uptimeMillis();
3890                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3891                    doReport = false;
3892                } else {
3893                    mLastMemUsageReportTime = now;
3894                }
3895            }
3896            final ArrayList<ProcessMemInfo> memInfos
3897                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3898            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3899            long now = SystemClock.uptimeMillis();
3900            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3901                ProcessRecord rec = mLruProcesses.get(i);
3902                if (rec == dyingProc || rec.thread == null) {
3903                    continue;
3904                }
3905                if (doReport) {
3906                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3907                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3908                }
3909                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3910                    // The low memory report is overriding any current
3911                    // state for a GC request.  Make sure to do
3912                    // heavy/important/visible/foreground processes first.
3913                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3914                        rec.lastRequestedGc = 0;
3915                    } else {
3916                        rec.lastRequestedGc = rec.lastLowMemory;
3917                    }
3918                    rec.reportLowMemory = true;
3919                    rec.lastLowMemory = now;
3920                    mProcessesToGc.remove(rec);
3921                    addProcessToGcListLocked(rec);
3922                }
3923            }
3924            if (doReport) {
3925                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3926                mHandler.sendMessage(msg);
3927            }
3928            scheduleAppGcsLocked();
3929        }
3930    }
3931
3932    final void appDiedLocked(ProcessRecord app, int pid,
3933            IApplicationThread thread) {
3934
3935        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3936        synchronized (stats) {
3937            stats.noteProcessDiedLocked(app.info.uid, pid);
3938        }
3939
3940        // Clean up already done if the process has been re-started.
3941        if (app.pid == pid && app.thread != null &&
3942                app.thread.asBinder() == thread.asBinder()) {
3943            boolean doLowMem = app.instrumentationClass == null;
3944            boolean doOomAdj = doLowMem;
3945            if (!app.killedByAm) {
3946                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3947                        + ") has died.");
3948                mAllowLowerMemLevel = true;
3949            } else {
3950                // Note that we always want to do oom adj to update our state with the
3951                // new number of procs.
3952                mAllowLowerMemLevel = false;
3953                doLowMem = false;
3954            }
3955            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3956            if (DEBUG_CLEANUP) Slog.v(
3957                TAG, "Dying app: " + app + ", pid: " + pid
3958                + ", thread: " + thread.asBinder());
3959            handleAppDiedLocked(app, false, true);
3960
3961            if (doOomAdj) {
3962                updateOomAdjLocked();
3963            }
3964            if (doLowMem) {
3965                doLowMemReportIfNeededLocked(app);
3966            }
3967        } else if (app.pid != pid) {
3968            // A new process has already been started.
3969            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3970                    + ") has died and restarted (pid " + app.pid + ").");
3971            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3972        } else if (DEBUG_PROCESSES) {
3973            Slog.d(TAG, "Received spurious death notification for thread "
3974                    + thread.asBinder());
3975        }
3976    }
3977
3978    /**
3979     * If a stack trace dump file is configured, dump process stack traces.
3980     * @param clearTraces causes the dump file to be erased prior to the new
3981     *    traces being written, if true; when false, the new traces will be
3982     *    appended to any existing file content.
3983     * @param firstPids of dalvik VM processes to dump stack traces for first
3984     * @param lastPids of dalvik VM processes to dump stack traces for last
3985     * @param nativeProcs optional list of native process names to dump stack crawls
3986     * @return file containing stack traces, or null if no dump file is configured
3987     */
3988    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3989            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3990        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3991        if (tracesPath == null || tracesPath.length() == 0) {
3992            return null;
3993        }
3994
3995        File tracesFile = new File(tracesPath);
3996        try {
3997            File tracesDir = tracesFile.getParentFile();
3998            if (!tracesDir.exists()) {
3999                tracesFile.mkdirs();
4000                if (!SELinux.restorecon(tracesDir)) {
4001                    return null;
4002                }
4003            }
4004            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4005
4006            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4007            tracesFile.createNewFile();
4008            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4009        } catch (IOException e) {
4010            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4011            return null;
4012        }
4013
4014        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4015        return tracesFile;
4016    }
4017
4018    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4019            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4020        // Use a FileObserver to detect when traces finish writing.
4021        // The order of traces is considered important to maintain for legibility.
4022        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4023            @Override
4024            public synchronized void onEvent(int event, String path) { notify(); }
4025        };
4026
4027        try {
4028            observer.startWatching();
4029
4030            // First collect all of the stacks of the most important pids.
4031            if (firstPids != null) {
4032                try {
4033                    int num = firstPids.size();
4034                    for (int i = 0; i < num; i++) {
4035                        synchronized (observer) {
4036                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4037                            observer.wait(200);  // Wait for write-close, give up after 200msec
4038                        }
4039                    }
4040                } catch (InterruptedException e) {
4041                    Log.wtf(TAG, e);
4042                }
4043            }
4044
4045            // Next collect the stacks of the native pids
4046            if (nativeProcs != null) {
4047                int[] pids = Process.getPidsForCommands(nativeProcs);
4048                if (pids != null) {
4049                    for (int pid : pids) {
4050                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4051                    }
4052                }
4053            }
4054
4055            // Lastly, measure CPU usage.
4056            if (processCpuTracker != null) {
4057                processCpuTracker.init();
4058                System.gc();
4059                processCpuTracker.update();
4060                try {
4061                    synchronized (processCpuTracker) {
4062                        processCpuTracker.wait(500); // measure over 1/2 second.
4063                    }
4064                } catch (InterruptedException e) {
4065                }
4066                processCpuTracker.update();
4067
4068                // We'll take the stack crawls of just the top apps using CPU.
4069                final int N = processCpuTracker.countWorkingStats();
4070                int numProcs = 0;
4071                for (int i=0; i<N && numProcs<5; i++) {
4072                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4073                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4074                        numProcs++;
4075                        try {
4076                            synchronized (observer) {
4077                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4078                                observer.wait(200);  // Wait for write-close, give up after 200msec
4079                            }
4080                        } catch (InterruptedException e) {
4081                            Log.wtf(TAG, e);
4082                        }
4083
4084                    }
4085                }
4086            }
4087        } finally {
4088            observer.stopWatching();
4089        }
4090    }
4091
4092    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4093        if (true || IS_USER_BUILD) {
4094            return;
4095        }
4096        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4097        if (tracesPath == null || tracesPath.length() == 0) {
4098            return;
4099        }
4100
4101        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4102        StrictMode.allowThreadDiskWrites();
4103        try {
4104            final File tracesFile = new File(tracesPath);
4105            final File tracesDir = tracesFile.getParentFile();
4106            final File tracesTmp = new File(tracesDir, "__tmp__");
4107            try {
4108                if (!tracesDir.exists()) {
4109                    tracesFile.mkdirs();
4110                    if (!SELinux.restorecon(tracesDir.getPath())) {
4111                        return;
4112                    }
4113                }
4114                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4115
4116                if (tracesFile.exists()) {
4117                    tracesTmp.delete();
4118                    tracesFile.renameTo(tracesTmp);
4119                }
4120                StringBuilder sb = new StringBuilder();
4121                Time tobj = new Time();
4122                tobj.set(System.currentTimeMillis());
4123                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4124                sb.append(": ");
4125                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4126                sb.append(" since ");
4127                sb.append(msg);
4128                FileOutputStream fos = new FileOutputStream(tracesFile);
4129                fos.write(sb.toString().getBytes());
4130                if (app == null) {
4131                    fos.write("\n*** No application process!".getBytes());
4132                }
4133                fos.close();
4134                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4135            } catch (IOException e) {
4136                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4137                return;
4138            }
4139
4140            if (app != null) {
4141                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4142                firstPids.add(app.pid);
4143                dumpStackTraces(tracesPath, firstPids, null, null, null);
4144            }
4145
4146            File lastTracesFile = null;
4147            File curTracesFile = null;
4148            for (int i=9; i>=0; i--) {
4149                String name = String.format(Locale.US, "slow%02d.txt", i);
4150                curTracesFile = new File(tracesDir, name);
4151                if (curTracesFile.exists()) {
4152                    if (lastTracesFile != null) {
4153                        curTracesFile.renameTo(lastTracesFile);
4154                    } else {
4155                        curTracesFile.delete();
4156                    }
4157                }
4158                lastTracesFile = curTracesFile;
4159            }
4160            tracesFile.renameTo(curTracesFile);
4161            if (tracesTmp.exists()) {
4162                tracesTmp.renameTo(tracesFile);
4163            }
4164        } finally {
4165            StrictMode.setThreadPolicy(oldPolicy);
4166        }
4167    }
4168
4169    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4170            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4171        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4172        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4173
4174        if (mController != null) {
4175            try {
4176                // 0 == continue, -1 = kill process immediately
4177                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4178                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4179            } catch (RemoteException e) {
4180                mController = null;
4181                Watchdog.getInstance().setActivityController(null);
4182            }
4183        }
4184
4185        long anrTime = SystemClock.uptimeMillis();
4186        if (MONITOR_CPU_USAGE) {
4187            updateCpuStatsNow();
4188        }
4189
4190        synchronized (this) {
4191            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4192            if (mShuttingDown) {
4193                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4194                return;
4195            } else if (app.notResponding) {
4196                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4197                return;
4198            } else if (app.crashing) {
4199                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4200                return;
4201            }
4202
4203            // In case we come through here for the same app before completing
4204            // this one, mark as anring now so we will bail out.
4205            app.notResponding = true;
4206
4207            // Log the ANR to the event log.
4208            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4209                    app.processName, app.info.flags, annotation);
4210
4211            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4212            firstPids.add(app.pid);
4213
4214            int parentPid = app.pid;
4215            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4216            if (parentPid != app.pid) firstPids.add(parentPid);
4217
4218            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4219
4220            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4221                ProcessRecord r = mLruProcesses.get(i);
4222                if (r != null && r.thread != null) {
4223                    int pid = r.pid;
4224                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4225                        if (r.persistent) {
4226                            firstPids.add(pid);
4227                        } else {
4228                            lastPids.put(pid, Boolean.TRUE);
4229                        }
4230                    }
4231                }
4232            }
4233        }
4234
4235        // Log the ANR to the main log.
4236        StringBuilder info = new StringBuilder();
4237        info.setLength(0);
4238        info.append("ANR in ").append(app.processName);
4239        if (activity != null && activity.shortComponentName != null) {
4240            info.append(" (").append(activity.shortComponentName).append(")");
4241        }
4242        info.append("\n");
4243        info.append("PID: ").append(app.pid).append("\n");
4244        if (annotation != null) {
4245            info.append("Reason: ").append(annotation).append("\n");
4246        }
4247        if (parent != null && parent != activity) {
4248            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4249        }
4250
4251        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4252
4253        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4254                NATIVE_STACKS_OF_INTEREST);
4255
4256        String cpuInfo = null;
4257        if (MONITOR_CPU_USAGE) {
4258            updateCpuStatsNow();
4259            synchronized (mProcessCpuThread) {
4260                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4261            }
4262            info.append(processCpuTracker.printCurrentLoad());
4263            info.append(cpuInfo);
4264        }
4265
4266        info.append(processCpuTracker.printCurrentState(anrTime));
4267
4268        Slog.e(TAG, info.toString());
4269        if (tracesFile == null) {
4270            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4271            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4272        }
4273
4274        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4275                cpuInfo, tracesFile, null);
4276
4277        if (mController != null) {
4278            try {
4279                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4280                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4281                if (res != 0) {
4282                    if (res < 0 && app.pid != MY_PID) {
4283                        Process.killProcess(app.pid);
4284                    } else {
4285                        synchronized (this) {
4286                            mServices.scheduleServiceTimeoutLocked(app);
4287                        }
4288                    }
4289                    return;
4290                }
4291            } catch (RemoteException e) {
4292                mController = null;
4293                Watchdog.getInstance().setActivityController(null);
4294            }
4295        }
4296
4297        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4298        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4299                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4300
4301        synchronized (this) {
4302            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4303                killUnneededProcessLocked(app, "background ANR");
4304                return;
4305            }
4306
4307            // Set the app's notResponding state, and look up the errorReportReceiver
4308            makeAppNotRespondingLocked(app,
4309                    activity != null ? activity.shortComponentName : null,
4310                    annotation != null ? "ANR " + annotation : "ANR",
4311                    info.toString());
4312
4313            // Bring up the infamous App Not Responding dialog
4314            Message msg = Message.obtain();
4315            HashMap<String, Object> map = new HashMap<String, Object>();
4316            msg.what = SHOW_NOT_RESPONDING_MSG;
4317            msg.obj = map;
4318            msg.arg1 = aboveSystem ? 1 : 0;
4319            map.put("app", app);
4320            if (activity != null) {
4321                map.put("activity", activity);
4322            }
4323
4324            mHandler.sendMessage(msg);
4325        }
4326    }
4327
4328    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4329        if (!mLaunchWarningShown) {
4330            mLaunchWarningShown = true;
4331            mHandler.post(new Runnable() {
4332                @Override
4333                public void run() {
4334                    synchronized (ActivityManagerService.this) {
4335                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4336                        d.show();
4337                        mHandler.postDelayed(new Runnable() {
4338                            @Override
4339                            public void run() {
4340                                synchronized (ActivityManagerService.this) {
4341                                    d.dismiss();
4342                                    mLaunchWarningShown = false;
4343                                }
4344                            }
4345                        }, 4000);
4346                    }
4347                }
4348            });
4349        }
4350    }
4351
4352    @Override
4353    public boolean clearApplicationUserData(final String packageName,
4354            final IPackageDataObserver observer, int userId) {
4355        enforceNotIsolatedCaller("clearApplicationUserData");
4356        int uid = Binder.getCallingUid();
4357        int pid = Binder.getCallingPid();
4358        userId = handleIncomingUser(pid, uid,
4359                userId, false, true, "clearApplicationUserData", null);
4360        long callingId = Binder.clearCallingIdentity();
4361        try {
4362            IPackageManager pm = AppGlobals.getPackageManager();
4363            int pkgUid = -1;
4364            synchronized(this) {
4365                try {
4366                    pkgUid = pm.getPackageUid(packageName, userId);
4367                } catch (RemoteException e) {
4368                }
4369                if (pkgUid == -1) {
4370                    Slog.w(TAG, "Invalid packageName: " + packageName);
4371                    if (observer != null) {
4372                        try {
4373                            observer.onRemoveCompleted(packageName, false);
4374                        } catch (RemoteException e) {
4375                            Slog.i(TAG, "Observer no longer exists.");
4376                        }
4377                    }
4378                    return false;
4379                }
4380                if (uid == pkgUid || checkComponentPermission(
4381                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4382                        pid, uid, -1, true)
4383                        == PackageManager.PERMISSION_GRANTED) {
4384                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4385                } else {
4386                    throw new SecurityException("PID " + pid + " does not have permission "
4387                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4388                                    + " of package " + packageName);
4389                }
4390            }
4391
4392            try {
4393                // Clear application user data
4394                pm.clearApplicationUserData(packageName, observer, userId);
4395
4396                // Remove all permissions granted from/to this package
4397                removeUriPermissionsForPackageLocked(packageName, userId, true);
4398
4399                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4400                        Uri.fromParts("package", packageName, null));
4401                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4402                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4403                        null, null, 0, null, null, null, false, false, userId);
4404            } catch (RemoteException e) {
4405            }
4406        } finally {
4407            Binder.restoreCallingIdentity(callingId);
4408        }
4409        return true;
4410    }
4411
4412    @Override
4413    public void killBackgroundProcesses(final String packageName, int userId) {
4414        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4415                != PackageManager.PERMISSION_GRANTED &&
4416                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4417                        != PackageManager.PERMISSION_GRANTED) {
4418            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4419                    + Binder.getCallingPid()
4420                    + ", uid=" + Binder.getCallingUid()
4421                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4422            Slog.w(TAG, msg);
4423            throw new SecurityException(msg);
4424        }
4425
4426        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4427                userId, true, true, "killBackgroundProcesses", null);
4428        long callingId = Binder.clearCallingIdentity();
4429        try {
4430            IPackageManager pm = AppGlobals.getPackageManager();
4431            synchronized(this) {
4432                int appId = -1;
4433                try {
4434                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4435                } catch (RemoteException e) {
4436                }
4437                if (appId == -1) {
4438                    Slog.w(TAG, "Invalid packageName: " + packageName);
4439                    return;
4440                }
4441                killPackageProcessesLocked(packageName, appId, userId,
4442                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4443            }
4444        } finally {
4445            Binder.restoreCallingIdentity(callingId);
4446        }
4447    }
4448
4449    @Override
4450    public void killAllBackgroundProcesses() {
4451        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4452                != PackageManager.PERMISSION_GRANTED) {
4453            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4454                    + Binder.getCallingPid()
4455                    + ", uid=" + Binder.getCallingUid()
4456                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4457            Slog.w(TAG, msg);
4458            throw new SecurityException(msg);
4459        }
4460
4461        long callingId = Binder.clearCallingIdentity();
4462        try {
4463            synchronized(this) {
4464                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4465                final int NP = mProcessNames.getMap().size();
4466                for (int ip=0; ip<NP; ip++) {
4467                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4468                    final int NA = apps.size();
4469                    for (int ia=0; ia<NA; ia++) {
4470                        ProcessRecord app = apps.valueAt(ia);
4471                        if (app.persistent) {
4472                            // we don't kill persistent processes
4473                            continue;
4474                        }
4475                        if (app.removed) {
4476                            procs.add(app);
4477                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4478                            app.removed = true;
4479                            procs.add(app);
4480                        }
4481                    }
4482                }
4483
4484                int N = procs.size();
4485                for (int i=0; i<N; i++) {
4486                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4487                }
4488                mAllowLowerMemLevel = true;
4489                updateOomAdjLocked();
4490                doLowMemReportIfNeededLocked(null);
4491            }
4492        } finally {
4493            Binder.restoreCallingIdentity(callingId);
4494        }
4495    }
4496
4497    @Override
4498    public void forceStopPackage(final String packageName, int userId) {
4499        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4500                != PackageManager.PERMISSION_GRANTED) {
4501            String msg = "Permission Denial: forceStopPackage() from pid="
4502                    + Binder.getCallingPid()
4503                    + ", uid=" + Binder.getCallingUid()
4504                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4505            Slog.w(TAG, msg);
4506            throw new SecurityException(msg);
4507        }
4508        final int callingPid = Binder.getCallingPid();
4509        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4510                userId, true, true, "forceStopPackage", null);
4511        long callingId = Binder.clearCallingIdentity();
4512        try {
4513            IPackageManager pm = AppGlobals.getPackageManager();
4514            synchronized(this) {
4515                int[] users = userId == UserHandle.USER_ALL
4516                        ? getUsersLocked() : new int[] { userId };
4517                for (int user : users) {
4518                    int pkgUid = -1;
4519                    try {
4520                        pkgUid = pm.getPackageUid(packageName, user);
4521                    } catch (RemoteException e) {
4522                    }
4523                    if (pkgUid == -1) {
4524                        Slog.w(TAG, "Invalid packageName: " + packageName);
4525                        continue;
4526                    }
4527                    try {
4528                        pm.setPackageStoppedState(packageName, true, user);
4529                    } catch (RemoteException e) {
4530                    } catch (IllegalArgumentException e) {
4531                        Slog.w(TAG, "Failed trying to unstop package "
4532                                + packageName + ": " + e);
4533                    }
4534                    if (isUserRunningLocked(user, false)) {
4535                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4536                    }
4537                }
4538            }
4539        } finally {
4540            Binder.restoreCallingIdentity(callingId);
4541        }
4542    }
4543
4544    /*
4545     * The pkg name and app id have to be specified.
4546     */
4547    @Override
4548    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4549        if (pkg == null) {
4550            return;
4551        }
4552        // Make sure the uid is valid.
4553        if (appid < 0) {
4554            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4555            return;
4556        }
4557        int callerUid = Binder.getCallingUid();
4558        // Only the system server can kill an application
4559        if (callerUid == Process.SYSTEM_UID) {
4560            // Post an aysnc message to kill the application
4561            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4562            msg.arg1 = appid;
4563            msg.arg2 = 0;
4564            Bundle bundle = new Bundle();
4565            bundle.putString("pkg", pkg);
4566            bundle.putString("reason", reason);
4567            msg.obj = bundle;
4568            mHandler.sendMessage(msg);
4569        } else {
4570            throw new SecurityException(callerUid + " cannot kill pkg: " +
4571                    pkg);
4572        }
4573    }
4574
4575    @Override
4576    public void closeSystemDialogs(String reason) {
4577        enforceNotIsolatedCaller("closeSystemDialogs");
4578
4579        final int pid = Binder.getCallingPid();
4580        final int uid = Binder.getCallingUid();
4581        final long origId = Binder.clearCallingIdentity();
4582        try {
4583            synchronized (this) {
4584                // Only allow this from foreground processes, so that background
4585                // applications can't abuse it to prevent system UI from being shown.
4586                if (uid >= Process.FIRST_APPLICATION_UID) {
4587                    ProcessRecord proc;
4588                    synchronized (mPidsSelfLocked) {
4589                        proc = mPidsSelfLocked.get(pid);
4590                    }
4591                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4592                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4593                                + " from background process " + proc);
4594                        return;
4595                    }
4596                }
4597                closeSystemDialogsLocked(reason);
4598            }
4599        } finally {
4600            Binder.restoreCallingIdentity(origId);
4601        }
4602    }
4603
4604    void closeSystemDialogsLocked(String reason) {
4605        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4606        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4607                | Intent.FLAG_RECEIVER_FOREGROUND);
4608        if (reason != null) {
4609            intent.putExtra("reason", reason);
4610        }
4611        mWindowManager.closeSystemDialogs(reason);
4612
4613        mStackSupervisor.closeSystemDialogsLocked();
4614
4615        broadcastIntentLocked(null, null, intent, null,
4616                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4617                Process.SYSTEM_UID, UserHandle.USER_ALL);
4618    }
4619
4620    @Override
4621    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4622        enforceNotIsolatedCaller("getProcessMemoryInfo");
4623        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4624        for (int i=pids.length-1; i>=0; i--) {
4625            ProcessRecord proc;
4626            int oomAdj;
4627            synchronized (this) {
4628                synchronized (mPidsSelfLocked) {
4629                    proc = mPidsSelfLocked.get(pids[i]);
4630                    oomAdj = proc != null ? proc.setAdj : 0;
4631                }
4632            }
4633            infos[i] = new Debug.MemoryInfo();
4634            Debug.getMemoryInfo(pids[i], infos[i]);
4635            if (proc != null) {
4636                synchronized (this) {
4637                    if (proc.thread != null && proc.setAdj == oomAdj) {
4638                        // Record this for posterity if the process has been stable.
4639                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4640                                infos[i].getTotalUss(), false, proc.pkgList);
4641                    }
4642                }
4643            }
4644        }
4645        return infos;
4646    }
4647
4648    @Override
4649    public long[] getProcessPss(int[] pids) {
4650        enforceNotIsolatedCaller("getProcessPss");
4651        long[] pss = new long[pids.length];
4652        for (int i=pids.length-1; i>=0; i--) {
4653            ProcessRecord proc;
4654            int oomAdj;
4655            synchronized (this) {
4656                synchronized (mPidsSelfLocked) {
4657                    proc = mPidsSelfLocked.get(pids[i]);
4658                    oomAdj = proc != null ? proc.setAdj : 0;
4659                }
4660            }
4661            long[] tmpUss = new long[1];
4662            pss[i] = Debug.getPss(pids[i], tmpUss);
4663            if (proc != null) {
4664                synchronized (this) {
4665                    if (proc.thread != null && proc.setAdj == oomAdj) {
4666                        // Record this for posterity if the process has been stable.
4667                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4668                    }
4669                }
4670            }
4671        }
4672        return pss;
4673    }
4674
4675    @Override
4676    public void killApplicationProcess(String processName, int uid) {
4677        if (processName == null) {
4678            return;
4679        }
4680
4681        int callerUid = Binder.getCallingUid();
4682        // Only the system server can kill an application
4683        if (callerUid == Process.SYSTEM_UID) {
4684            synchronized (this) {
4685                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4686                if (app != null && app.thread != null) {
4687                    try {
4688                        app.thread.scheduleSuicide();
4689                    } catch (RemoteException e) {
4690                        // If the other end already died, then our work here is done.
4691                    }
4692                } else {
4693                    Slog.w(TAG, "Process/uid not found attempting kill of "
4694                            + processName + " / " + uid);
4695                }
4696            }
4697        } else {
4698            throw new SecurityException(callerUid + " cannot kill app process: " +
4699                    processName);
4700        }
4701    }
4702
4703    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4704        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4705                false, true, false, false, UserHandle.getUserId(uid), reason);
4706        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4707                Uri.fromParts("package", packageName, null));
4708        if (!mProcessesReady) {
4709            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4710                    | Intent.FLAG_RECEIVER_FOREGROUND);
4711        }
4712        intent.putExtra(Intent.EXTRA_UID, uid);
4713        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4714        broadcastIntentLocked(null, null, intent,
4715                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4716                false, false,
4717                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4718    }
4719
4720    private void forceStopUserLocked(int userId, String reason) {
4721        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4722        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4723        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4724                | Intent.FLAG_RECEIVER_FOREGROUND);
4725        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4726        broadcastIntentLocked(null, null, intent,
4727                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4728                false, false,
4729                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4730    }
4731
4732    private final boolean killPackageProcessesLocked(String packageName, int appId,
4733            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4734            boolean doit, boolean evenPersistent, String reason) {
4735        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4736
4737        // Remove all processes this package may have touched: all with the
4738        // same UID (except for the system or root user), and all whose name
4739        // matches the package name.
4740        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4741        final int NP = mProcessNames.getMap().size();
4742        for (int ip=0; ip<NP; ip++) {
4743            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4744            final int NA = apps.size();
4745            for (int ia=0; ia<NA; ia++) {
4746                ProcessRecord app = apps.valueAt(ia);
4747                if (app.persistent && !evenPersistent) {
4748                    // we don't kill persistent processes
4749                    continue;
4750                }
4751                if (app.removed) {
4752                    if (doit) {
4753                        procs.add(app);
4754                    }
4755                    continue;
4756                }
4757
4758                // Skip process if it doesn't meet our oom adj requirement.
4759                if (app.setAdj < minOomAdj) {
4760                    continue;
4761                }
4762
4763                // If no package is specified, we call all processes under the
4764                // give user id.
4765                if (packageName == null) {
4766                    if (app.userId != userId) {
4767                        continue;
4768                    }
4769                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4770                        continue;
4771                    }
4772                // Package has been specified, we want to hit all processes
4773                // that match it.  We need to qualify this by the processes
4774                // that are running under the specified app and user ID.
4775                } else {
4776                    if (UserHandle.getAppId(app.uid) != appId) {
4777                        continue;
4778                    }
4779                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4780                        continue;
4781                    }
4782                    if (!app.pkgList.containsKey(packageName)) {
4783                        continue;
4784                    }
4785                }
4786
4787                // Process has passed all conditions, kill it!
4788                if (!doit) {
4789                    return true;
4790                }
4791                app.removed = true;
4792                procs.add(app);
4793            }
4794        }
4795
4796        int N = procs.size();
4797        for (int i=0; i<N; i++) {
4798            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4799        }
4800        updateOomAdjLocked();
4801        return N > 0;
4802    }
4803
4804    private final boolean forceStopPackageLocked(String name, int appId,
4805            boolean callerWillRestart, boolean purgeCache, boolean doit,
4806            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4807        int i;
4808        int N;
4809
4810        if (userId == UserHandle.USER_ALL && name == null) {
4811            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4812        }
4813
4814        if (appId < 0 && name != null) {
4815            try {
4816                appId = UserHandle.getAppId(
4817                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4818            } catch (RemoteException e) {
4819            }
4820        }
4821
4822        if (doit) {
4823            if (name != null) {
4824                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4825                        + " user=" + userId + ": " + reason);
4826            } else {
4827                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4828            }
4829
4830            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4831            for (int ip=pmap.size()-1; ip>=0; ip--) {
4832                SparseArray<Long> ba = pmap.valueAt(ip);
4833                for (i=ba.size()-1; i>=0; i--) {
4834                    boolean remove = false;
4835                    final int entUid = ba.keyAt(i);
4836                    if (name != null) {
4837                        if (userId == UserHandle.USER_ALL) {
4838                            if (UserHandle.getAppId(entUid) == appId) {
4839                                remove = true;
4840                            }
4841                        } else {
4842                            if (entUid == UserHandle.getUid(userId, appId)) {
4843                                remove = true;
4844                            }
4845                        }
4846                    } else if (UserHandle.getUserId(entUid) == userId) {
4847                        remove = true;
4848                    }
4849                    if (remove) {
4850                        ba.removeAt(i);
4851                    }
4852                }
4853                if (ba.size() == 0) {
4854                    pmap.removeAt(ip);
4855                }
4856            }
4857        }
4858
4859        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4860                -100, callerWillRestart, true, doit, evenPersistent,
4861                name == null ? ("stop user " + userId) : ("stop " + name));
4862
4863        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4864            if (!doit) {
4865                return true;
4866            }
4867            didSomething = true;
4868        }
4869
4870        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4871            if (!doit) {
4872                return true;
4873            }
4874            didSomething = true;
4875        }
4876
4877        if (name == null) {
4878            // Remove all sticky broadcasts from this user.
4879            mStickyBroadcasts.remove(userId);
4880        }
4881
4882        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4883        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4884                userId, providers)) {
4885            if (!doit) {
4886                return true;
4887            }
4888            didSomething = true;
4889        }
4890        N = providers.size();
4891        for (i=0; i<N; i++) {
4892            removeDyingProviderLocked(null, providers.get(i), true);
4893        }
4894
4895        // Remove transient permissions granted from/to this package/user
4896        removeUriPermissionsForPackageLocked(name, userId, false);
4897
4898        if (name == null || uninstalling) {
4899            // Remove pending intents.  For now we only do this when force
4900            // stopping users, because we have some problems when doing this
4901            // for packages -- app widgets are not currently cleaned up for
4902            // such packages, so they can be left with bad pending intents.
4903            if (mIntentSenderRecords.size() > 0) {
4904                Iterator<WeakReference<PendingIntentRecord>> it
4905                        = mIntentSenderRecords.values().iterator();
4906                while (it.hasNext()) {
4907                    WeakReference<PendingIntentRecord> wpir = it.next();
4908                    if (wpir == null) {
4909                        it.remove();
4910                        continue;
4911                    }
4912                    PendingIntentRecord pir = wpir.get();
4913                    if (pir == null) {
4914                        it.remove();
4915                        continue;
4916                    }
4917                    if (name == null) {
4918                        // Stopping user, remove all objects for the user.
4919                        if (pir.key.userId != userId) {
4920                            // Not the same user, skip it.
4921                            continue;
4922                        }
4923                    } else {
4924                        if (UserHandle.getAppId(pir.uid) != appId) {
4925                            // Different app id, skip it.
4926                            continue;
4927                        }
4928                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4929                            // Different user, skip it.
4930                            continue;
4931                        }
4932                        if (!pir.key.packageName.equals(name)) {
4933                            // Different package, skip it.
4934                            continue;
4935                        }
4936                    }
4937                    if (!doit) {
4938                        return true;
4939                    }
4940                    didSomething = true;
4941                    it.remove();
4942                    pir.canceled = true;
4943                    if (pir.key.activity != null) {
4944                        pir.key.activity.pendingResults.remove(pir.ref);
4945                    }
4946                }
4947            }
4948        }
4949
4950        if (doit) {
4951            if (purgeCache && name != null) {
4952                AttributeCache ac = AttributeCache.instance();
4953                if (ac != null) {
4954                    ac.removePackage(name);
4955                }
4956            }
4957            if (mBooted) {
4958                mStackSupervisor.resumeTopActivitiesLocked();
4959                mStackSupervisor.scheduleIdleLocked();
4960            }
4961        }
4962
4963        return didSomething;
4964    }
4965
4966    private final boolean removeProcessLocked(ProcessRecord app,
4967            boolean callerWillRestart, boolean allowRestart, String reason) {
4968        final String name = app.processName;
4969        final int uid = app.uid;
4970        if (DEBUG_PROCESSES) Slog.d(
4971            TAG, "Force removing proc " + app.toShortString() + " (" + name
4972            + "/" + uid + ")");
4973
4974        mProcessNames.remove(name, uid);
4975        mIsolatedProcesses.remove(app.uid);
4976        if (mHeavyWeightProcess == app) {
4977            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4978                    mHeavyWeightProcess.userId, 0));
4979            mHeavyWeightProcess = null;
4980        }
4981        boolean needRestart = false;
4982        if (app.pid > 0 && app.pid != MY_PID) {
4983            int pid = app.pid;
4984            synchronized (mPidsSelfLocked) {
4985                mPidsSelfLocked.remove(pid);
4986                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4987            }
4988            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4989                    app.processName, app.info.uid);
4990            if (app.isolated) {
4991                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4992            }
4993            killUnneededProcessLocked(app, reason);
4994            handleAppDiedLocked(app, true, allowRestart);
4995            removeLruProcessLocked(app);
4996
4997            if (app.persistent && !app.isolated) {
4998                if (!callerWillRestart) {
4999                    addAppLocked(app.info, false);
5000                } else {
5001                    needRestart = true;
5002                }
5003            }
5004        } else {
5005            mRemovedProcesses.add(app);
5006        }
5007
5008        return needRestart;
5009    }
5010
5011    private final void processStartTimedOutLocked(ProcessRecord app) {
5012        final int pid = app.pid;
5013        boolean gone = false;
5014        synchronized (mPidsSelfLocked) {
5015            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5016            if (knownApp != null && knownApp.thread == null) {
5017                mPidsSelfLocked.remove(pid);
5018                gone = true;
5019            }
5020        }
5021
5022        if (gone) {
5023            Slog.w(TAG, "Process " + app + " failed to attach");
5024            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5025                    pid, app.uid, app.processName);
5026            mProcessNames.remove(app.processName, app.uid);
5027            mIsolatedProcesses.remove(app.uid);
5028            if (mHeavyWeightProcess == app) {
5029                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5030                        mHeavyWeightProcess.userId, 0));
5031                mHeavyWeightProcess = null;
5032            }
5033            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5034                    app.processName, app.info.uid);
5035            if (app.isolated) {
5036                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5037            }
5038            // Take care of any launching providers waiting for this process.
5039            checkAppInLaunchingProvidersLocked(app, true);
5040            // Take care of any services that are waiting for the process.
5041            mServices.processStartTimedOutLocked(app);
5042            killUnneededProcessLocked(app, "start timeout");
5043            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5044                Slog.w(TAG, "Unattached app died before backup, skipping");
5045                try {
5046                    IBackupManager bm = IBackupManager.Stub.asInterface(
5047                            ServiceManager.getService(Context.BACKUP_SERVICE));
5048                    bm.agentDisconnected(app.info.packageName);
5049                } catch (RemoteException e) {
5050                    // Can't happen; the backup manager is local
5051                }
5052            }
5053            if (isPendingBroadcastProcessLocked(pid)) {
5054                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5055                skipPendingBroadcastLocked(pid);
5056            }
5057        } else {
5058            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5059        }
5060    }
5061
5062    private final boolean attachApplicationLocked(IApplicationThread thread,
5063            int pid) {
5064
5065        // Find the application record that is being attached...  either via
5066        // the pid if we are running in multiple processes, or just pull the
5067        // next app record if we are emulating process with anonymous threads.
5068        ProcessRecord app;
5069        if (pid != MY_PID && pid >= 0) {
5070            synchronized (mPidsSelfLocked) {
5071                app = mPidsSelfLocked.get(pid);
5072            }
5073        } else {
5074            app = null;
5075        }
5076
5077        if (app == null) {
5078            Slog.w(TAG, "No pending application record for pid " + pid
5079                    + " (IApplicationThread " + thread + "); dropping process");
5080            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5081            if (pid > 0 && pid != MY_PID) {
5082                Process.killProcessQuiet(pid);
5083            } else {
5084                try {
5085                    thread.scheduleExit();
5086                } catch (Exception e) {
5087                    // Ignore exceptions.
5088                }
5089            }
5090            return false;
5091        }
5092
5093        // If this application record is still attached to a previous
5094        // process, clean it up now.
5095        if (app.thread != null) {
5096            handleAppDiedLocked(app, true, true);
5097        }
5098
5099        // Tell the process all about itself.
5100
5101        if (localLOGV) Slog.v(
5102                TAG, "Binding process pid " + pid + " to record " + app);
5103
5104        final String processName = app.processName;
5105        try {
5106            AppDeathRecipient adr = new AppDeathRecipient(
5107                    app, pid, thread);
5108            thread.asBinder().linkToDeath(adr, 0);
5109            app.deathRecipient = adr;
5110        } catch (RemoteException e) {
5111            app.resetPackageList(mProcessStats);
5112            startProcessLocked(app, "link fail", processName);
5113            return false;
5114        }
5115
5116        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5117
5118        app.makeActive(thread, mProcessStats);
5119        app.curAdj = app.setAdj = -100;
5120        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5121        app.forcingToForeground = null;
5122        updateProcessForegroundLocked(app, false, false);
5123        app.hasShownUi = false;
5124        app.debugging = false;
5125        app.cached = false;
5126
5127        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5128
5129        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5130        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5131
5132        if (!normalMode) {
5133            Slog.i(TAG, "Launching preboot mode app: " + app);
5134        }
5135
5136        if (localLOGV) Slog.v(
5137            TAG, "New app record " + app
5138            + " thread=" + thread.asBinder() + " pid=" + pid);
5139        try {
5140            int testMode = IApplicationThread.DEBUG_OFF;
5141            if (mDebugApp != null && mDebugApp.equals(processName)) {
5142                testMode = mWaitForDebugger
5143                    ? IApplicationThread.DEBUG_WAIT
5144                    : IApplicationThread.DEBUG_ON;
5145                app.debugging = true;
5146                if (mDebugTransient) {
5147                    mDebugApp = mOrigDebugApp;
5148                    mWaitForDebugger = mOrigWaitForDebugger;
5149                }
5150            }
5151            String profileFile = app.instrumentationProfileFile;
5152            ParcelFileDescriptor profileFd = null;
5153            boolean profileAutoStop = false;
5154            if (mProfileApp != null && mProfileApp.equals(processName)) {
5155                mProfileProc = app;
5156                profileFile = mProfileFile;
5157                profileFd = mProfileFd;
5158                profileAutoStop = mAutoStopProfiler;
5159            }
5160            boolean enableOpenGlTrace = false;
5161            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5162                enableOpenGlTrace = true;
5163                mOpenGlTraceApp = null;
5164            }
5165
5166            // If the app is being launched for restore or full backup, set it up specially
5167            boolean isRestrictedBackupMode = false;
5168            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5169                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5170                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5171                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5172            }
5173
5174            ensurePackageDexOpt(app.instrumentationInfo != null
5175                    ? app.instrumentationInfo.packageName
5176                    : app.info.packageName);
5177            if (app.instrumentationClass != null) {
5178                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5179            }
5180            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5181                    + processName + " with config " + mConfiguration);
5182            ApplicationInfo appInfo = app.instrumentationInfo != null
5183                    ? app.instrumentationInfo : app.info;
5184            app.compat = compatibilityInfoForPackageLocked(appInfo);
5185            if (profileFd != null) {
5186                profileFd = profileFd.dup();
5187            }
5188            thread.bindApplication(processName, appInfo, providers,
5189                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5190                    app.instrumentationArguments, app.instrumentationWatcher,
5191                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5192                    isRestrictedBackupMode || !normalMode, app.persistent,
5193                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5194                    mCoreSettingsObserver.getCoreSettingsLocked());
5195            updateLruProcessLocked(app, false, null);
5196            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5197        } catch (Exception e) {
5198            // todo: Yikes!  What should we do?  For now we will try to
5199            // start another process, but that could easily get us in
5200            // an infinite loop of restarting processes...
5201            Slog.w(TAG, "Exception thrown during bind!", e);
5202
5203            app.resetPackageList(mProcessStats);
5204            app.unlinkDeathRecipient();
5205            startProcessLocked(app, "bind fail", processName);
5206            return false;
5207        }
5208
5209        // Remove this record from the list of starting applications.
5210        mPersistentStartingProcesses.remove(app);
5211        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5212                "Attach application locked removing on hold: " + app);
5213        mProcessesOnHold.remove(app);
5214
5215        boolean badApp = false;
5216        boolean didSomething = false;
5217
5218        // See if the top visible activity is waiting to run in this process...
5219        if (normalMode) {
5220            try {
5221                if (mStackSupervisor.attachApplicationLocked(app)) {
5222                    didSomething = true;
5223                }
5224            } catch (Exception e) {
5225                badApp = true;
5226            }
5227        }
5228
5229        // Find any services that should be running in this process...
5230        if (!badApp) {
5231            try {
5232                didSomething |= mServices.attachApplicationLocked(app, processName);
5233            } catch (Exception e) {
5234                badApp = true;
5235            }
5236        }
5237
5238        // Check if a next-broadcast receiver is in this process...
5239        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5240            try {
5241                didSomething |= sendPendingBroadcastsLocked(app);
5242            } catch (Exception e) {
5243                // If the app died trying to launch the receiver we declare it 'bad'
5244                badApp = true;
5245            }
5246        }
5247
5248        // Check whether the next backup agent is in this process...
5249        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5250            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5251            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5252            try {
5253                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5254                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5255                        mBackupTarget.backupMode);
5256            } catch (Exception e) {
5257                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5258                e.printStackTrace();
5259            }
5260        }
5261
5262        if (badApp) {
5263            // todo: Also need to kill application to deal with all
5264            // kinds of exceptions.
5265            handleAppDiedLocked(app, false, true);
5266            return false;
5267        }
5268
5269        if (!didSomething) {
5270            updateOomAdjLocked();
5271        }
5272
5273        return true;
5274    }
5275
5276    @Override
5277    public final void attachApplication(IApplicationThread thread) {
5278        synchronized (this) {
5279            int callingPid = Binder.getCallingPid();
5280            final long origId = Binder.clearCallingIdentity();
5281            attachApplicationLocked(thread, callingPid);
5282            Binder.restoreCallingIdentity(origId);
5283        }
5284    }
5285
5286    @Override
5287    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5288        final long origId = Binder.clearCallingIdentity();
5289        synchronized (this) {
5290            ActivityStack stack = ActivityRecord.getStackLocked(token);
5291            if (stack != null) {
5292                ActivityRecord r =
5293                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5294                if (stopProfiling) {
5295                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5296                        try {
5297                            mProfileFd.close();
5298                        } catch (IOException e) {
5299                        }
5300                        clearProfilerLocked();
5301                    }
5302                }
5303            }
5304        }
5305        Binder.restoreCallingIdentity(origId);
5306    }
5307
5308    void enableScreenAfterBoot() {
5309        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5310                SystemClock.uptimeMillis());
5311        mWindowManager.enableScreenAfterBoot();
5312
5313        synchronized (this) {
5314            updateEventDispatchingLocked();
5315        }
5316    }
5317
5318    @Override
5319    public void showBootMessage(final CharSequence msg, final boolean always) {
5320        enforceNotIsolatedCaller("showBootMessage");
5321        mWindowManager.showBootMessage(msg, always);
5322    }
5323
5324    @Override
5325    public void dismissKeyguardOnNextActivity() {
5326        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5327        final long token = Binder.clearCallingIdentity();
5328        try {
5329            synchronized (this) {
5330                if (DEBUG_LOCKSCREEN) logLockScreen("");
5331                if (mLockScreenShown) {
5332                    mLockScreenShown = false;
5333                    comeOutOfSleepIfNeededLocked();
5334                }
5335                mStackSupervisor.setDismissKeyguard(true);
5336            }
5337        } finally {
5338            Binder.restoreCallingIdentity(token);
5339        }
5340    }
5341
5342    final void finishBooting() {
5343        // Register receivers to handle package update events
5344        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5345
5346        synchronized (this) {
5347            // Ensure that any processes we had put on hold are now started
5348            // up.
5349            final int NP = mProcessesOnHold.size();
5350            if (NP > 0) {
5351                ArrayList<ProcessRecord> procs =
5352                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5353                for (int ip=0; ip<NP; ip++) {
5354                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5355                            + procs.get(ip));
5356                    startProcessLocked(procs.get(ip), "on-hold", null);
5357                }
5358            }
5359
5360            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5361                // Start looking for apps that are abusing wake locks.
5362                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5363                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5364                // Tell anyone interested that we are done booting!
5365                SystemProperties.set("sys.boot_completed", "1");
5366                SystemProperties.set("dev.bootcomplete", "1");
5367                for (int i=0; i<mStartedUsers.size(); i++) {
5368                    UserStartedState uss = mStartedUsers.valueAt(i);
5369                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5370                        uss.mState = UserStartedState.STATE_RUNNING;
5371                        final int userId = mStartedUsers.keyAt(i);
5372                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5373                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5374                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5375                        broadcastIntentLocked(null, null, intent, null,
5376                                new IIntentReceiver.Stub() {
5377                                    @Override
5378                                    public void performReceive(Intent intent, int resultCode,
5379                                            String data, Bundle extras, boolean ordered,
5380                                            boolean sticky, int sendingUser) {
5381                                        synchronized (ActivityManagerService.this) {
5382                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5383                                                    true, false);
5384                                        }
5385                                    }
5386                                },
5387                                0, null, null,
5388                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5389                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5390                                userId);
5391                    }
5392                }
5393                scheduleStartProfilesLocked();
5394            }
5395        }
5396    }
5397
5398    final void ensureBootCompleted() {
5399        boolean booting;
5400        boolean enableScreen;
5401        synchronized (this) {
5402            booting = mBooting;
5403            mBooting = false;
5404            enableScreen = !mBooted;
5405            mBooted = true;
5406        }
5407
5408        if (booting) {
5409            finishBooting();
5410        }
5411
5412        if (enableScreen) {
5413            enableScreenAfterBoot();
5414        }
5415    }
5416
5417    @Override
5418    public final void activityResumed(IBinder token) {
5419        final long origId = Binder.clearCallingIdentity();
5420        synchronized(this) {
5421            ActivityStack stack = ActivityRecord.getStackLocked(token);
5422            if (stack != null) {
5423                ActivityRecord.activityResumedLocked(token);
5424            }
5425        }
5426        Binder.restoreCallingIdentity(origId);
5427    }
5428
5429    @Override
5430    public final void activityPaused(IBinder token) {
5431        final long origId = Binder.clearCallingIdentity();
5432        synchronized(this) {
5433            ActivityStack stack = ActivityRecord.getStackLocked(token);
5434            if (stack != null) {
5435                stack.activityPausedLocked(token, false);
5436            }
5437        }
5438        Binder.restoreCallingIdentity(origId);
5439    }
5440
5441    @Override
5442    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5443            CharSequence description) {
5444        if (localLOGV) Slog.v(
5445            TAG, "Activity stopped: token=" + token);
5446
5447        // Refuse possible leaked file descriptors
5448        if (icicle != null && icicle.hasFileDescriptors()) {
5449            throw new IllegalArgumentException("File descriptors passed in Bundle");
5450        }
5451
5452        final long origId = Binder.clearCallingIdentity();
5453
5454        synchronized (this) {
5455            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5456            if (r != null) {
5457                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5458            }
5459        }
5460
5461        trimApplications();
5462
5463        Binder.restoreCallingIdentity(origId);
5464    }
5465
5466    @Override
5467    public final void activityDestroyed(IBinder token) {
5468        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5469        synchronized (this) {
5470            ActivityStack stack = ActivityRecord.getStackLocked(token);
5471            if (stack != null) {
5472                stack.activityDestroyedLocked(token);
5473            }
5474        }
5475    }
5476
5477    @Override
5478    public String getCallingPackage(IBinder token) {
5479        synchronized (this) {
5480            ActivityRecord r = getCallingRecordLocked(token);
5481            return r != null ? r.info.packageName : null;
5482        }
5483    }
5484
5485    @Override
5486    public ComponentName getCallingActivity(IBinder token) {
5487        synchronized (this) {
5488            ActivityRecord r = getCallingRecordLocked(token);
5489            return r != null ? r.intent.getComponent() : null;
5490        }
5491    }
5492
5493    private ActivityRecord getCallingRecordLocked(IBinder token) {
5494        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5495        if (r == null) {
5496            return null;
5497        }
5498        return r.resultTo;
5499    }
5500
5501    @Override
5502    public ComponentName getActivityClassForToken(IBinder token) {
5503        synchronized(this) {
5504            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5505            if (r == null) {
5506                return null;
5507            }
5508            return r.intent.getComponent();
5509        }
5510    }
5511
5512    @Override
5513    public String getPackageForToken(IBinder token) {
5514        synchronized(this) {
5515            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5516            if (r == null) {
5517                return null;
5518            }
5519            return r.packageName;
5520        }
5521    }
5522
5523    @Override
5524    public IIntentSender getIntentSender(int type,
5525            String packageName, IBinder token, String resultWho,
5526            int requestCode, Intent[] intents, String[] resolvedTypes,
5527            int flags, Bundle options, int userId) {
5528        enforceNotIsolatedCaller("getIntentSender");
5529        // Refuse possible leaked file descriptors
5530        if (intents != null) {
5531            if (intents.length < 1) {
5532                throw new IllegalArgumentException("Intents array length must be >= 1");
5533            }
5534            for (int i=0; i<intents.length; i++) {
5535                Intent intent = intents[i];
5536                if (intent != null) {
5537                    if (intent.hasFileDescriptors()) {
5538                        throw new IllegalArgumentException("File descriptors passed in Intent");
5539                    }
5540                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5541                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5542                        throw new IllegalArgumentException(
5543                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5544                    }
5545                    intents[i] = new Intent(intent);
5546                }
5547            }
5548            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5549                throw new IllegalArgumentException(
5550                        "Intent array length does not match resolvedTypes length");
5551            }
5552        }
5553        if (options != null) {
5554            if (options.hasFileDescriptors()) {
5555                throw new IllegalArgumentException("File descriptors passed in options");
5556            }
5557        }
5558
5559        synchronized(this) {
5560            int callingUid = Binder.getCallingUid();
5561            int origUserId = userId;
5562            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5563                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5564                    "getIntentSender", null);
5565            if (origUserId == UserHandle.USER_CURRENT) {
5566                // We don't want to evaluate this until the pending intent is
5567                // actually executed.  However, we do want to always do the
5568                // security checking for it above.
5569                userId = UserHandle.USER_CURRENT;
5570            }
5571            try {
5572                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5573                    int uid = AppGlobals.getPackageManager()
5574                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5575                    if (!UserHandle.isSameApp(callingUid, uid)) {
5576                        String msg = "Permission Denial: getIntentSender() from pid="
5577                            + Binder.getCallingPid()
5578                            + ", uid=" + Binder.getCallingUid()
5579                            + ", (need uid=" + uid + ")"
5580                            + " is not allowed to send as package " + packageName;
5581                        Slog.w(TAG, msg);
5582                        throw new SecurityException(msg);
5583                    }
5584                }
5585
5586                return getIntentSenderLocked(type, packageName, callingUid, userId,
5587                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5588
5589            } catch (RemoteException e) {
5590                throw new SecurityException(e);
5591            }
5592        }
5593    }
5594
5595    IIntentSender getIntentSenderLocked(int type, String packageName,
5596            int callingUid, int userId, IBinder token, String resultWho,
5597            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5598            Bundle options) {
5599        if (DEBUG_MU)
5600            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5601        ActivityRecord activity = null;
5602        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5603            activity = ActivityRecord.isInStackLocked(token);
5604            if (activity == null) {
5605                return null;
5606            }
5607            if (activity.finishing) {
5608                return null;
5609            }
5610        }
5611
5612        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5613        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5614        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5615        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5616                |PendingIntent.FLAG_UPDATE_CURRENT);
5617
5618        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5619                type, packageName, activity, resultWho,
5620                requestCode, intents, resolvedTypes, flags, options, userId);
5621        WeakReference<PendingIntentRecord> ref;
5622        ref = mIntentSenderRecords.get(key);
5623        PendingIntentRecord rec = ref != null ? ref.get() : null;
5624        if (rec != null) {
5625            if (!cancelCurrent) {
5626                if (updateCurrent) {
5627                    if (rec.key.requestIntent != null) {
5628                        rec.key.requestIntent.replaceExtras(intents != null ?
5629                                intents[intents.length - 1] : null);
5630                    }
5631                    if (intents != null) {
5632                        intents[intents.length-1] = rec.key.requestIntent;
5633                        rec.key.allIntents = intents;
5634                        rec.key.allResolvedTypes = resolvedTypes;
5635                    } else {
5636                        rec.key.allIntents = null;
5637                        rec.key.allResolvedTypes = null;
5638                    }
5639                }
5640                return rec;
5641            }
5642            rec.canceled = true;
5643            mIntentSenderRecords.remove(key);
5644        }
5645        if (noCreate) {
5646            return rec;
5647        }
5648        rec = new PendingIntentRecord(this, key, callingUid);
5649        mIntentSenderRecords.put(key, rec.ref);
5650        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5651            if (activity.pendingResults == null) {
5652                activity.pendingResults
5653                        = new HashSet<WeakReference<PendingIntentRecord>>();
5654            }
5655            activity.pendingResults.add(rec.ref);
5656        }
5657        return rec;
5658    }
5659
5660    @Override
5661    public void cancelIntentSender(IIntentSender sender) {
5662        if (!(sender instanceof PendingIntentRecord)) {
5663            return;
5664        }
5665        synchronized(this) {
5666            PendingIntentRecord rec = (PendingIntentRecord)sender;
5667            try {
5668                int uid = AppGlobals.getPackageManager()
5669                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5670                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5671                    String msg = "Permission Denial: cancelIntentSender() from pid="
5672                        + Binder.getCallingPid()
5673                        + ", uid=" + Binder.getCallingUid()
5674                        + " is not allowed to cancel packges "
5675                        + rec.key.packageName;
5676                    Slog.w(TAG, msg);
5677                    throw new SecurityException(msg);
5678                }
5679            } catch (RemoteException e) {
5680                throw new SecurityException(e);
5681            }
5682            cancelIntentSenderLocked(rec, true);
5683        }
5684    }
5685
5686    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5687        rec.canceled = true;
5688        mIntentSenderRecords.remove(rec.key);
5689        if (cleanActivity && rec.key.activity != null) {
5690            rec.key.activity.pendingResults.remove(rec.ref);
5691        }
5692    }
5693
5694    @Override
5695    public String getPackageForIntentSender(IIntentSender pendingResult) {
5696        if (!(pendingResult instanceof PendingIntentRecord)) {
5697            return null;
5698        }
5699        try {
5700            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5701            return res.key.packageName;
5702        } catch (ClassCastException e) {
5703        }
5704        return null;
5705    }
5706
5707    @Override
5708    public int getUidForIntentSender(IIntentSender sender) {
5709        if (sender instanceof PendingIntentRecord) {
5710            try {
5711                PendingIntentRecord res = (PendingIntentRecord)sender;
5712                return res.uid;
5713            } catch (ClassCastException e) {
5714            }
5715        }
5716        return -1;
5717    }
5718
5719    @Override
5720    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5721        if (!(pendingResult instanceof PendingIntentRecord)) {
5722            return false;
5723        }
5724        try {
5725            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5726            if (res.key.allIntents == null) {
5727                return false;
5728            }
5729            for (int i=0; i<res.key.allIntents.length; i++) {
5730                Intent intent = res.key.allIntents[i];
5731                if (intent.getPackage() != null && intent.getComponent() != null) {
5732                    return false;
5733                }
5734            }
5735            return true;
5736        } catch (ClassCastException e) {
5737        }
5738        return false;
5739    }
5740
5741    @Override
5742    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5743        if (!(pendingResult instanceof PendingIntentRecord)) {
5744            return false;
5745        }
5746        try {
5747            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5748            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5749                return true;
5750            }
5751            return false;
5752        } catch (ClassCastException e) {
5753        }
5754        return false;
5755    }
5756
5757    @Override
5758    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5759        if (!(pendingResult instanceof PendingIntentRecord)) {
5760            return null;
5761        }
5762        try {
5763            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5764            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5765        } catch (ClassCastException e) {
5766        }
5767        return null;
5768    }
5769
5770    @Override
5771    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5772        if (!(pendingResult instanceof PendingIntentRecord)) {
5773            return null;
5774        }
5775        try {
5776            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5777            Intent intent = res.key.requestIntent;
5778            if (intent != null) {
5779                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5780                        || res.lastTagPrefix.equals(prefix))) {
5781                    return res.lastTag;
5782                }
5783                res.lastTagPrefix = prefix;
5784                StringBuilder sb = new StringBuilder(128);
5785                if (prefix != null) {
5786                    sb.append(prefix);
5787                }
5788                if (intent.getAction() != null) {
5789                    sb.append(intent.getAction());
5790                } else if (intent.getComponent() != null) {
5791                    intent.getComponent().appendShortString(sb);
5792                } else {
5793                    sb.append("?");
5794                }
5795                return res.lastTag = sb.toString();
5796            }
5797        } catch (ClassCastException e) {
5798        }
5799        return null;
5800    }
5801
5802    @Override
5803    public void setProcessLimit(int max) {
5804        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5805                "setProcessLimit()");
5806        synchronized (this) {
5807            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5808            mProcessLimitOverride = max;
5809        }
5810        trimApplications();
5811    }
5812
5813    @Override
5814    public int getProcessLimit() {
5815        synchronized (this) {
5816            return mProcessLimitOverride;
5817        }
5818    }
5819
5820    void foregroundTokenDied(ForegroundToken token) {
5821        synchronized (ActivityManagerService.this) {
5822            synchronized (mPidsSelfLocked) {
5823                ForegroundToken cur
5824                    = mForegroundProcesses.get(token.pid);
5825                if (cur != token) {
5826                    return;
5827                }
5828                mForegroundProcesses.remove(token.pid);
5829                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5830                if (pr == null) {
5831                    return;
5832                }
5833                pr.forcingToForeground = null;
5834                updateProcessForegroundLocked(pr, false, false);
5835            }
5836            updateOomAdjLocked();
5837        }
5838    }
5839
5840    @Override
5841    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5842        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5843                "setProcessForeground()");
5844        synchronized(this) {
5845            boolean changed = false;
5846
5847            synchronized (mPidsSelfLocked) {
5848                ProcessRecord pr = mPidsSelfLocked.get(pid);
5849                if (pr == null && isForeground) {
5850                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5851                    return;
5852                }
5853                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5854                if (oldToken != null) {
5855                    oldToken.token.unlinkToDeath(oldToken, 0);
5856                    mForegroundProcesses.remove(pid);
5857                    if (pr != null) {
5858                        pr.forcingToForeground = null;
5859                    }
5860                    changed = true;
5861                }
5862                if (isForeground && token != null) {
5863                    ForegroundToken newToken = new ForegroundToken() {
5864                        @Override
5865                        public void binderDied() {
5866                            foregroundTokenDied(this);
5867                        }
5868                    };
5869                    newToken.pid = pid;
5870                    newToken.token = token;
5871                    try {
5872                        token.linkToDeath(newToken, 0);
5873                        mForegroundProcesses.put(pid, newToken);
5874                        pr.forcingToForeground = token;
5875                        changed = true;
5876                    } catch (RemoteException e) {
5877                        // If the process died while doing this, we will later
5878                        // do the cleanup with the process death link.
5879                    }
5880                }
5881            }
5882
5883            if (changed) {
5884                updateOomAdjLocked();
5885            }
5886        }
5887    }
5888
5889    // =========================================================
5890    // PERMISSIONS
5891    // =========================================================
5892
5893    static class PermissionController extends IPermissionController.Stub {
5894        ActivityManagerService mActivityManagerService;
5895        PermissionController(ActivityManagerService activityManagerService) {
5896            mActivityManagerService = activityManagerService;
5897        }
5898
5899        @Override
5900        public boolean checkPermission(String permission, int pid, int uid) {
5901            return mActivityManagerService.checkPermission(permission, pid,
5902                    uid) == PackageManager.PERMISSION_GRANTED;
5903        }
5904    }
5905
5906    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5907        @Override
5908        public int checkComponentPermission(String permission, int pid, int uid,
5909                int owningUid, boolean exported) {
5910            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5911                    owningUid, exported);
5912        }
5913
5914        @Override
5915        public Object getAMSLock() {
5916            return ActivityManagerService.this;
5917        }
5918    }
5919
5920    /**
5921     * This can be called with or without the global lock held.
5922     */
5923    int checkComponentPermission(String permission, int pid, int uid,
5924            int owningUid, boolean exported) {
5925        // We might be performing an operation on behalf of an indirect binder
5926        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5927        // client identity accordingly before proceeding.
5928        Identity tlsIdentity = sCallerIdentity.get();
5929        if (tlsIdentity != null) {
5930            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5931                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5932            uid = tlsIdentity.uid;
5933            pid = tlsIdentity.pid;
5934        }
5935
5936        if (pid == MY_PID) {
5937            return PackageManager.PERMISSION_GRANTED;
5938        }
5939
5940        return ActivityManager.checkComponentPermission(permission, uid,
5941                owningUid, exported);
5942    }
5943
5944    /**
5945     * As the only public entry point for permissions checking, this method
5946     * can enforce the semantic that requesting a check on a null global
5947     * permission is automatically denied.  (Internally a null permission
5948     * string is used when calling {@link #checkComponentPermission} in cases
5949     * when only uid-based security is needed.)
5950     *
5951     * This can be called with or without the global lock held.
5952     */
5953    @Override
5954    public int checkPermission(String permission, int pid, int uid) {
5955        if (permission == null) {
5956            return PackageManager.PERMISSION_DENIED;
5957        }
5958        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5959    }
5960
5961    /**
5962     * Binder IPC calls go through the public entry point.
5963     * This can be called with or without the global lock held.
5964     */
5965    int checkCallingPermission(String permission) {
5966        return checkPermission(permission,
5967                Binder.getCallingPid(),
5968                UserHandle.getAppId(Binder.getCallingUid()));
5969    }
5970
5971    /**
5972     * This can be called with or without the global lock held.
5973     */
5974    void enforceCallingPermission(String permission, String func) {
5975        if (checkCallingPermission(permission)
5976                == PackageManager.PERMISSION_GRANTED) {
5977            return;
5978        }
5979
5980        String msg = "Permission Denial: " + func + " from pid="
5981                + Binder.getCallingPid()
5982                + ", uid=" + Binder.getCallingUid()
5983                + " requires " + permission;
5984        Slog.w(TAG, msg);
5985        throw new SecurityException(msg);
5986    }
5987
5988    /**
5989     * Determine if UID is holding permissions required to access {@link Uri} in
5990     * the given {@link ProviderInfo}. Final permission checking is always done
5991     * in {@link ContentProvider}.
5992     */
5993    private final boolean checkHoldingPermissionsLocked(
5994            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
5995        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5996                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5997
5998        if (pi.applicationInfo.uid == uid) {
5999            return true;
6000        } else if (!pi.exported) {
6001            return false;
6002        }
6003
6004        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6005        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6006        try {
6007            // check if target holds top-level <provider> permissions
6008            if (!readMet && pi.readPermission != null
6009                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6010                readMet = true;
6011            }
6012            if (!writeMet && pi.writePermission != null
6013                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6014                writeMet = true;
6015            }
6016
6017            // track if unprotected read/write is allowed; any denied
6018            // <path-permission> below removes this ability
6019            boolean allowDefaultRead = pi.readPermission == null;
6020            boolean allowDefaultWrite = pi.writePermission == null;
6021
6022            // check if target holds any <path-permission> that match uri
6023            final PathPermission[] pps = pi.pathPermissions;
6024            if (pps != null) {
6025                final String path = uri.getPath();
6026                int i = pps.length;
6027                while (i > 0 && (!readMet || !writeMet)) {
6028                    i--;
6029                    PathPermission pp = pps[i];
6030                    if (pp.match(path)) {
6031                        if (!readMet) {
6032                            final String pprperm = pp.getReadPermission();
6033                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6034                                    + pprperm + " for " + pp.getPath()
6035                                    + ": match=" + pp.match(path)
6036                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6037                            if (pprperm != null) {
6038                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6039                                    readMet = true;
6040                                } else {
6041                                    allowDefaultRead = false;
6042                                }
6043                            }
6044                        }
6045                        if (!writeMet) {
6046                            final String ppwperm = pp.getWritePermission();
6047                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6048                                    + ppwperm + " for " + pp.getPath()
6049                                    + ": match=" + pp.match(path)
6050                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6051                            if (ppwperm != null) {
6052                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6053                                    writeMet = true;
6054                                } else {
6055                                    allowDefaultWrite = false;
6056                                }
6057                            }
6058                        }
6059                    }
6060                }
6061            }
6062
6063            // grant unprotected <provider> read/write, if not blocked by
6064            // <path-permission> above
6065            if (allowDefaultRead) readMet = true;
6066            if (allowDefaultWrite) writeMet = true;
6067
6068        } catch (RemoteException e) {
6069            return false;
6070        }
6071
6072        return readMet && writeMet;
6073    }
6074
6075    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6076        ProviderInfo pi = null;
6077        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6078        if (cpr != null) {
6079            pi = cpr.info;
6080        } else {
6081            try {
6082                pi = AppGlobals.getPackageManager().resolveContentProvider(
6083                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6084            } catch (RemoteException ex) {
6085            }
6086        }
6087        return pi;
6088    }
6089
6090    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
6091        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6092        if (targetUris != null) {
6093            return targetUris.get(uri);
6094        }
6095        return null;
6096    }
6097
6098    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6099            String targetPkg, int targetUid, GrantUri uri) {
6100        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6101        if (targetUris == null) {
6102            targetUris = Maps.newArrayMap();
6103            mGrantedUriPermissions.put(targetUid, targetUris);
6104        }
6105
6106        UriPermission perm = targetUris.get(uri);
6107        if (perm == null) {
6108            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
6109            targetUris.put(uri, perm);
6110        }
6111
6112        return perm;
6113    }
6114
6115    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6116        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6117        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6118                : UriPermission.STRENGTH_OWNED;
6119
6120        // Root gets to do everything.
6121        if (uid == 0) {
6122            return true;
6123        }
6124
6125        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6126        if (perms == null) return false;
6127
6128        // First look for exact match
6129        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6130        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6131            return true;
6132        }
6133
6134        // No exact match, look for prefixes
6135        final int N = perms.size();
6136        for (int i = 0; i < N; i++) {
6137            final UriPermission perm = perms.valueAt(i);
6138            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6139                    && perm.getStrength(modeFlags) >= minStrength) {
6140                return true;
6141            }
6142        }
6143
6144        return false;
6145    }
6146
6147    @Override
6148    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6149        enforceNotIsolatedCaller("checkUriPermission");
6150
6151        // Another redirected-binder-call permissions check as in
6152        // {@link checkComponentPermission}.
6153        Identity tlsIdentity = sCallerIdentity.get();
6154        if (tlsIdentity != null) {
6155            uid = tlsIdentity.uid;
6156            pid = tlsIdentity.pid;
6157        }
6158
6159        // Our own process gets to do everything.
6160        if (pid == MY_PID) {
6161            return PackageManager.PERMISSION_GRANTED;
6162        }
6163        synchronized (this) {
6164            return checkUriPermissionLocked(uri, uid, modeFlags)
6165                    ? PackageManager.PERMISSION_GRANTED
6166                    : PackageManager.PERMISSION_DENIED;
6167        }
6168    }
6169
6170    /**
6171     * Check if the targetPkg can be granted permission to access uri by
6172     * the callingUid using the given modeFlags.  Throws a security exception
6173     * if callingUid is not allowed to do this.  Returns the uid of the target
6174     * if the URI permission grant should be performed; returns -1 if it is not
6175     * needed (for example targetPkg already has permission to access the URI).
6176     * If you already know the uid of the target, you can supply it in
6177     * lastTargetUid else set that to -1.
6178     */
6179    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6180            Uri uri, final int modeFlags, int lastTargetUid) {
6181        if (!Intent.isAccessUriMode(modeFlags)) {
6182            return -1;
6183        }
6184
6185        if (targetPkg != null) {
6186            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6187                    "Checking grant " + targetPkg + " permission to " + uri);
6188        }
6189
6190        final IPackageManager pm = AppGlobals.getPackageManager();
6191
6192        // If this is not a content: uri, we can't do anything with it.
6193        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6194            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6195                    "Can't grant URI permission for non-content URI: " + uri);
6196            return -1;
6197        }
6198
6199        final String authority = uri.getAuthority();
6200        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6201        if (pi == null) {
6202            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6203            return -1;
6204        }
6205
6206        int targetUid = lastTargetUid;
6207        if (targetUid < 0 && targetPkg != null) {
6208            try {
6209                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6210                if (targetUid < 0) {
6211                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6212                            "Can't grant URI permission no uid for: " + targetPkg);
6213                    return -1;
6214                }
6215            } catch (RemoteException ex) {
6216                return -1;
6217            }
6218        }
6219
6220        if (targetUid >= 0) {
6221            // First...  does the target actually need this permission?
6222            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6223                // No need to grant the target this permission.
6224                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6225                        "Target " + targetPkg + " already has full permission to " + uri);
6226                return -1;
6227            }
6228        } else {
6229            // First...  there is no target package, so can anyone access it?
6230            boolean allowed = pi.exported;
6231            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6232                if (pi.readPermission != null) {
6233                    allowed = false;
6234                }
6235            }
6236            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6237                if (pi.writePermission != null) {
6238                    allowed = false;
6239                }
6240            }
6241            if (allowed) {
6242                return -1;
6243            }
6244        }
6245
6246        // Second...  is the provider allowing granting of URI permissions?
6247        if (!pi.grantUriPermissions) {
6248            throw new SecurityException("Provider " + pi.packageName
6249                    + "/" + pi.name
6250                    + " does not allow granting of Uri permissions (uri "
6251                    + uri + ")");
6252        }
6253        if (pi.uriPermissionPatterns != null) {
6254            final int N = pi.uriPermissionPatterns.length;
6255            boolean allowed = false;
6256            for (int i=0; i<N; i++) {
6257                if (pi.uriPermissionPatterns[i] != null
6258                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6259                    allowed = true;
6260                    break;
6261                }
6262            }
6263            if (!allowed) {
6264                throw new SecurityException("Provider " + pi.packageName
6265                        + "/" + pi.name
6266                        + " does not allow granting of permission to path of Uri "
6267                        + uri);
6268            }
6269        }
6270
6271        // Third...  does the caller itself have permission to access
6272        // this uri?
6273        if (callingUid != Process.myUid()) {
6274            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6275                // Require they hold a strong enough Uri permission
6276                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6277                    throw new SecurityException("Uid " + callingUid
6278                            + " does not have permission to uri " + uri);
6279                }
6280            }
6281        }
6282
6283        return targetUid;
6284    }
6285
6286    @Override
6287    public int checkGrantUriPermission(int callingUid, String targetPkg,
6288            Uri uri, final int modeFlags) {
6289        enforceNotIsolatedCaller("checkGrantUriPermission");
6290        synchronized(this) {
6291            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6292        }
6293    }
6294
6295    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6296            final int modeFlags, UriPermissionOwner owner) {
6297        if (!Intent.isAccessUriMode(modeFlags)) {
6298            return;
6299        }
6300
6301        // So here we are: the caller has the assumed permission
6302        // to the uri, and the target doesn't.  Let's now give this to
6303        // the target.
6304
6305        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6306                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6307
6308        final String authority = uri.getAuthority();
6309        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6310        if (pi == null) {
6311            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6312            return;
6313        }
6314
6315        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6316        final UriPermission perm = findOrCreateUriPermissionLocked(
6317                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6318        perm.grantModes(modeFlags, owner);
6319    }
6320
6321    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6322            final int modeFlags, UriPermissionOwner owner) {
6323        if (targetPkg == null) {
6324            throw new NullPointerException("targetPkg");
6325        }
6326
6327        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6328        if (targetUid < 0) {
6329            return;
6330        }
6331
6332        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6333    }
6334
6335    static class NeededUriGrants extends ArrayList<Uri> {
6336        final String targetPkg;
6337        final int targetUid;
6338        final int flags;
6339
6340        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6341            this.targetPkg = targetPkg;
6342            this.targetUid = targetUid;
6343            this.flags = flags;
6344        }
6345    }
6346
6347    /**
6348     * Like checkGrantUriPermissionLocked, but takes an Intent.
6349     */
6350    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6351            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6352        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6353                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6354                + " clip=" + (intent != null ? intent.getClipData() : null)
6355                + " from " + intent + "; flags=0x"
6356                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6357
6358        if (targetPkg == null) {
6359            throw new NullPointerException("targetPkg");
6360        }
6361
6362        if (intent == null) {
6363            return null;
6364        }
6365        Uri data = intent.getData();
6366        ClipData clip = intent.getClipData();
6367        if (data == null && clip == null) {
6368            return null;
6369        }
6370
6371        if (data != null) {
6372            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6373                mode, needed != null ? needed.targetUid : -1);
6374            if (targetUid > 0) {
6375                if (needed == null) {
6376                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6377                }
6378                needed.add(data);
6379            }
6380        }
6381        if (clip != null) {
6382            for (int i=0; i<clip.getItemCount(); i++) {
6383                Uri uri = clip.getItemAt(i).getUri();
6384                if (uri != null) {
6385                    int targetUid = -1;
6386                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6387                            mode, needed != null ? needed.targetUid : -1);
6388                    if (targetUid > 0) {
6389                        if (needed == null) {
6390                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6391                        }
6392                        needed.add(uri);
6393                    }
6394                } else {
6395                    Intent clipIntent = clip.getItemAt(i).getIntent();
6396                    if (clipIntent != null) {
6397                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6398                                callingUid, targetPkg, clipIntent, mode, needed);
6399                        if (newNeeded != null) {
6400                            needed = newNeeded;
6401                        }
6402                    }
6403                }
6404            }
6405        }
6406
6407        return needed;
6408    }
6409
6410    /**
6411     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6412     */
6413    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6414            UriPermissionOwner owner) {
6415        if (needed != null) {
6416            for (int i=0; i<needed.size(); i++) {
6417                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6418                        needed.get(i), needed.flags, owner);
6419            }
6420        }
6421    }
6422
6423    void grantUriPermissionFromIntentLocked(int callingUid,
6424            String targetPkg, Intent intent, UriPermissionOwner owner) {
6425        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6426                intent, intent != null ? intent.getFlags() : 0, null);
6427        if (needed == null) {
6428            return;
6429        }
6430
6431        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6432    }
6433
6434    @Override
6435    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6436            Uri uri, final int modeFlags) {
6437        enforceNotIsolatedCaller("grantUriPermission");
6438        synchronized(this) {
6439            final ProcessRecord r = getRecordForAppLocked(caller);
6440            if (r == null) {
6441                throw new SecurityException("Unable to find app for caller "
6442                        + caller
6443                        + " when granting permission to uri " + uri);
6444            }
6445            if (targetPkg == null) {
6446                throw new IllegalArgumentException("null target");
6447            }
6448            if (uri == null) {
6449                throw new IllegalArgumentException("null uri");
6450            }
6451
6452            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6453                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6454                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6455                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6456
6457            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6458        }
6459    }
6460
6461    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6462        if (perm.modeFlags == 0) {
6463            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6464                    perm.targetUid);
6465            if (perms != null) {
6466                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6467                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6468
6469                perms.remove(perm.uri);
6470                if (perms.isEmpty()) {
6471                    mGrantedUriPermissions.remove(perm.targetUid);
6472                }
6473            }
6474        }
6475    }
6476
6477    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6478        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6479
6480        final IPackageManager pm = AppGlobals.getPackageManager();
6481        final String authority = uri.getAuthority();
6482        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6483        if (pi == null) {
6484            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6485            return;
6486        }
6487
6488        // Does the caller have this permission on the URI?
6489        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6490            // Right now, if you are not the original owner of the permission,
6491            // you are not allowed to revoke it.
6492            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6493                throw new SecurityException("Uid " + callingUid
6494                        + " does not have permission to uri " + uri);
6495            //}
6496        }
6497
6498        boolean persistChanged = false;
6499
6500        // Go through all of the permissions and remove any that match.
6501        int N = mGrantedUriPermissions.size();
6502        for (int i = 0; i < N; i++) {
6503            final int targetUid = mGrantedUriPermissions.keyAt(i);
6504            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6505
6506            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6507                final UriPermission perm = it.next();
6508                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6509                    if (DEBUG_URI_PERMISSION)
6510                        Slog.v(TAG,
6511                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6512                    persistChanged |= perm.revokeModes(
6513                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6514                    if (perm.modeFlags == 0) {
6515                        it.remove();
6516                    }
6517                }
6518            }
6519
6520            if (perms.isEmpty()) {
6521                mGrantedUriPermissions.remove(targetUid);
6522                N--;
6523                i--;
6524            }
6525        }
6526
6527        if (persistChanged) {
6528            schedulePersistUriGrants();
6529        }
6530    }
6531
6532    @Override
6533    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6534            final int modeFlags) {
6535        enforceNotIsolatedCaller("revokeUriPermission");
6536        synchronized(this) {
6537            final ProcessRecord r = getRecordForAppLocked(caller);
6538            if (r == null) {
6539                throw new SecurityException("Unable to find app for caller "
6540                        + caller
6541                        + " when revoking permission to uri " + uri);
6542            }
6543            if (uri == null) {
6544                Slog.w(TAG, "revokeUriPermission: null uri");
6545                return;
6546            }
6547
6548            if (!Intent.isAccessUriMode(modeFlags)) {
6549                return;
6550            }
6551
6552            final IPackageManager pm = AppGlobals.getPackageManager();
6553            final String authority = uri.getAuthority();
6554            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6555            if (pi == null) {
6556                Slog.w(TAG, "No content provider found for permission revoke: "
6557                        + uri.toSafeString());
6558                return;
6559            }
6560
6561            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6562        }
6563    }
6564
6565    /**
6566     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6567     * given package.
6568     *
6569     * @param packageName Package name to match, or {@code null} to apply to all
6570     *            packages.
6571     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6572     *            to all users.
6573     * @param persistable If persistable grants should be removed.
6574     */
6575    private void removeUriPermissionsForPackageLocked(
6576            String packageName, int userHandle, boolean persistable) {
6577        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6578            throw new IllegalArgumentException("Must narrow by either package or user");
6579        }
6580
6581        boolean persistChanged = false;
6582
6583        int N = mGrantedUriPermissions.size();
6584        for (int i = 0; i < N; i++) {
6585            final int targetUid = mGrantedUriPermissions.keyAt(i);
6586            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6587
6588            // Only inspect grants matching user
6589            if (userHandle == UserHandle.USER_ALL
6590                    || userHandle == UserHandle.getUserId(targetUid)) {
6591                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6592                    final UriPermission perm = it.next();
6593
6594                    // Only inspect grants matching package
6595                    if (packageName == null || perm.sourcePkg.equals(packageName)
6596                            || perm.targetPkg.equals(packageName)) {
6597                        persistChanged |= perm.revokeModes(
6598                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6599
6600                        // Only remove when no modes remain; any persisted grants
6601                        // will keep this alive.
6602                        if (perm.modeFlags == 0) {
6603                            it.remove();
6604                        }
6605                    }
6606                }
6607
6608                if (perms.isEmpty()) {
6609                    mGrantedUriPermissions.remove(targetUid);
6610                    N--;
6611                    i--;
6612                }
6613            }
6614        }
6615
6616        if (persistChanged) {
6617            schedulePersistUriGrants();
6618        }
6619    }
6620
6621    @Override
6622    public IBinder newUriPermissionOwner(String name) {
6623        enforceNotIsolatedCaller("newUriPermissionOwner");
6624        synchronized(this) {
6625            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6626            return owner.getExternalTokenLocked();
6627        }
6628    }
6629
6630    @Override
6631    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6632            Uri uri, final int modeFlags) {
6633        synchronized(this) {
6634            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6635            if (owner == null) {
6636                throw new IllegalArgumentException("Unknown owner: " + token);
6637            }
6638            if (fromUid != Binder.getCallingUid()) {
6639                if (Binder.getCallingUid() != Process.myUid()) {
6640                    // Only system code can grant URI permissions on behalf
6641                    // of other users.
6642                    throw new SecurityException("nice try");
6643                }
6644            }
6645            if (targetPkg == null) {
6646                throw new IllegalArgumentException("null target");
6647            }
6648            if (uri == null) {
6649                throw new IllegalArgumentException("null uri");
6650            }
6651
6652            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6653        }
6654    }
6655
6656    @Override
6657    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6658        synchronized(this) {
6659            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6660            if (owner == null) {
6661                throw new IllegalArgumentException("Unknown owner: " + token);
6662            }
6663
6664            if (uri == null) {
6665                owner.removeUriPermissionsLocked(mode);
6666            } else {
6667                owner.removeUriPermissionLocked(uri, mode);
6668            }
6669        }
6670    }
6671
6672    private void schedulePersistUriGrants() {
6673        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6674            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6675                    10 * DateUtils.SECOND_IN_MILLIS);
6676        }
6677    }
6678
6679    private void writeGrantedUriPermissions() {
6680        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6681
6682        // Snapshot permissions so we can persist without lock
6683        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6684        synchronized (this) {
6685            final int size = mGrantedUriPermissions.size();
6686            for (int i = 0; i < size; i++) {
6687                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6688                for (UriPermission perm : perms.values()) {
6689                    if (perm.persistedModeFlags != 0) {
6690                        persist.add(perm.snapshot());
6691                    }
6692                }
6693            }
6694        }
6695
6696        FileOutputStream fos = null;
6697        try {
6698            fos = mGrantFile.startWrite();
6699
6700            XmlSerializer out = new FastXmlSerializer();
6701            out.setOutput(fos, "utf-8");
6702            out.startDocument(null, true);
6703            out.startTag(null, TAG_URI_GRANTS);
6704            for (UriPermission.Snapshot perm : persist) {
6705                out.startTag(null, TAG_URI_GRANT);
6706                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6707                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6708                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6709                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6710                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6711                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6712                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6713                out.endTag(null, TAG_URI_GRANT);
6714            }
6715            out.endTag(null, TAG_URI_GRANTS);
6716            out.endDocument();
6717
6718            mGrantFile.finishWrite(fos);
6719        } catch (IOException e) {
6720            if (fos != null) {
6721                mGrantFile.failWrite(fos);
6722            }
6723        }
6724    }
6725
6726    private void readGrantedUriPermissionsLocked() {
6727        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6728
6729        final long now = System.currentTimeMillis();
6730
6731        FileInputStream fis = null;
6732        try {
6733            fis = mGrantFile.openRead();
6734            final XmlPullParser in = Xml.newPullParser();
6735            in.setInput(fis, null);
6736
6737            int type;
6738            while ((type = in.next()) != END_DOCUMENT) {
6739                final String tag = in.getName();
6740                if (type == START_TAG) {
6741                    if (TAG_URI_GRANT.equals(tag)) {
6742                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6743                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6744                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6745                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6746                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6747                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6748                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6749
6750                        // Sanity check that provider still belongs to source package
6751                        final ProviderInfo pi = getProviderInfoLocked(
6752                                uri.getAuthority(), userHandle);
6753                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6754                            int targetUid = -1;
6755                            try {
6756                                targetUid = AppGlobals.getPackageManager()
6757                                        .getPackageUid(targetPkg, userHandle);
6758                            } catch (RemoteException e) {
6759                            }
6760                            if (targetUid != -1) {
6761                                final UriPermission perm = findOrCreateUriPermissionLocked(
6762                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6763                                perm.initPersistedModes(modeFlags, createdTime);
6764                            }
6765                        } else {
6766                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6767                                    + " but instead found " + pi);
6768                        }
6769                    }
6770                }
6771            }
6772        } catch (FileNotFoundException e) {
6773            // Missing grants is okay
6774        } catch (IOException e) {
6775            Log.wtf(TAG, "Failed reading Uri grants", e);
6776        } catch (XmlPullParserException e) {
6777            Log.wtf(TAG, "Failed reading Uri grants", e);
6778        } finally {
6779            IoUtils.closeQuietly(fis);
6780        }
6781    }
6782
6783    @Override
6784    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6785        enforceNotIsolatedCaller("takePersistableUriPermission");
6786
6787        Preconditions.checkFlagsArgument(modeFlags,
6788                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6789
6790        synchronized (this) {
6791            final int callingUid = Binder.getCallingUid();
6792            boolean persistChanged = false;
6793
6794            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6795            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6796
6797            final boolean exactValid = (exactPerm != null)
6798                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6799            final boolean prefixValid = (prefixPerm != null)
6800                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6801
6802            if (!(exactValid || prefixValid)) {
6803                throw new SecurityException("No persistable permission grants found for UID "
6804                        + callingUid + " and Uri " + uri.toSafeString());
6805            }
6806
6807            if (exactValid) {
6808                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6809            }
6810            if (prefixValid) {
6811                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6812            }
6813
6814            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6815
6816            if (persistChanged) {
6817                schedulePersistUriGrants();
6818            }
6819        }
6820    }
6821
6822    @Override
6823    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6824        enforceNotIsolatedCaller("releasePersistableUriPermission");
6825
6826        Preconditions.checkFlagsArgument(modeFlags,
6827                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6828
6829        synchronized (this) {
6830            final int callingUid = Binder.getCallingUid();
6831            boolean persistChanged = false;
6832
6833            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6834            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6835            if (exactPerm == null && prefixPerm == null) {
6836                throw new SecurityException("No permission grants found for UID " + callingUid
6837                        + " and Uri " + uri.toSafeString());
6838            }
6839
6840            if (exactPerm != null) {
6841                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6842                removeUriPermissionIfNeededLocked(exactPerm);
6843            }
6844            if (prefixPerm != null) {
6845                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6846                removeUriPermissionIfNeededLocked(prefixPerm);
6847            }
6848
6849            if (persistChanged) {
6850                schedulePersistUriGrants();
6851            }
6852        }
6853    }
6854
6855    /**
6856     * Prune any older {@link UriPermission} for the given UID until outstanding
6857     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6858     *
6859     * @return if any mutations occured that require persisting.
6860     */
6861    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6862        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6863        if (perms == null) return false;
6864        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6865
6866        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6867        for (UriPermission perm : perms.values()) {
6868            if (perm.persistedModeFlags != 0) {
6869                persisted.add(perm);
6870            }
6871        }
6872
6873        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6874        if (trimCount <= 0) return false;
6875
6876        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6877        for (int i = 0; i < trimCount; i++) {
6878            final UriPermission perm = persisted.get(i);
6879
6880            if (DEBUG_URI_PERMISSION) {
6881                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6882            }
6883
6884            perm.releasePersistableModes(~0);
6885            removeUriPermissionIfNeededLocked(perm);
6886        }
6887
6888        return true;
6889    }
6890
6891    @Override
6892    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6893            String packageName, boolean incoming) {
6894        enforceNotIsolatedCaller("getPersistedUriPermissions");
6895        Preconditions.checkNotNull(packageName, "packageName");
6896
6897        final int callingUid = Binder.getCallingUid();
6898        final IPackageManager pm = AppGlobals.getPackageManager();
6899        try {
6900            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6901            if (packageUid != callingUid) {
6902                throw new SecurityException(
6903                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6904            }
6905        } catch (RemoteException e) {
6906            throw new SecurityException("Failed to verify package name ownership");
6907        }
6908
6909        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6910        synchronized (this) {
6911            if (incoming) {
6912                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6913                        callingUid);
6914                if (perms == null) {
6915                    Slog.w(TAG, "No permission grants found for " + packageName);
6916                } else {
6917                    for (UriPermission perm : perms.values()) {
6918                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6919                            result.add(perm.buildPersistedPublicApiObject());
6920                        }
6921                    }
6922                }
6923            } else {
6924                final int size = mGrantedUriPermissions.size();
6925                for (int i = 0; i < size; i++) {
6926                    final ArrayMap<GrantUri, UriPermission> perms =
6927                            mGrantedUriPermissions.valueAt(i);
6928                    for (UriPermission perm : perms.values()) {
6929                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6930                            result.add(perm.buildPersistedPublicApiObject());
6931                        }
6932                    }
6933                }
6934            }
6935        }
6936        return new ParceledListSlice<android.content.UriPermission>(result);
6937    }
6938
6939    @Override
6940    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6941        synchronized (this) {
6942            ProcessRecord app =
6943                who != null ? getRecordForAppLocked(who) : null;
6944            if (app == null) return;
6945
6946            Message msg = Message.obtain();
6947            msg.what = WAIT_FOR_DEBUGGER_MSG;
6948            msg.obj = app;
6949            msg.arg1 = waiting ? 1 : 0;
6950            mHandler.sendMessage(msg);
6951        }
6952    }
6953
6954    @Override
6955    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6956        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6957        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6958        outInfo.availMem = Process.getFreeMemory();
6959        outInfo.totalMem = Process.getTotalMemory();
6960        outInfo.threshold = homeAppMem;
6961        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6962        outInfo.hiddenAppThreshold = cachedAppMem;
6963        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6964                ProcessList.SERVICE_ADJ);
6965        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6966                ProcessList.VISIBLE_APP_ADJ);
6967        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6968                ProcessList.FOREGROUND_APP_ADJ);
6969    }
6970
6971    // =========================================================
6972    // TASK MANAGEMENT
6973    // =========================================================
6974
6975    @Override
6976    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
6977        final int callingUid = Binder.getCallingUid();
6978        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6979
6980        synchronized(this) {
6981            if (localLOGV) Slog.v(
6982                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
6983
6984            final boolean allowed = checkCallingPermission(
6985                    android.Manifest.permission.GET_TASKS)
6986                    == PackageManager.PERMISSION_GRANTED;
6987            if (!allowed) {
6988                Slog.w(TAG, "getTasks: caller " + callingUid
6989                        + " does not hold GET_TASKS; limiting output");
6990            }
6991
6992            // TODO: Improve with MRU list from all ActivityStacks.
6993            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
6994        }
6995
6996        return list;
6997    }
6998
6999    TaskRecord getMostRecentTask() {
7000        return mRecentTasks.get(0);
7001    }
7002
7003    @Override
7004    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7005            int flags, int userId) {
7006        final int callingUid = Binder.getCallingUid();
7007        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7008                false, true, "getRecentTasks", null);
7009
7010        synchronized (this) {
7011            final boolean allowed = checkCallingPermission(
7012                    android.Manifest.permission.GET_TASKS)
7013                    == PackageManager.PERMISSION_GRANTED;
7014            if (!allowed) {
7015                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7016                        + " does not hold GET_TASKS; limiting output");
7017            }
7018            final boolean detailed = checkCallingPermission(
7019                    android.Manifest.permission.GET_DETAILED_TASKS)
7020                    == PackageManager.PERMISSION_GRANTED;
7021
7022            IPackageManager pm = AppGlobals.getPackageManager();
7023
7024            final int N = mRecentTasks.size();
7025            ArrayList<ActivityManager.RecentTaskInfo> res
7026                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7027                            maxNum < N ? maxNum : N);
7028
7029            final Set<Integer> includedUsers;
7030            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7031                includedUsers = getProfileIdsLocked(userId);
7032            } else {
7033                includedUsers = new HashSet<Integer>();
7034            }
7035            includedUsers.add(Integer.valueOf(userId));
7036            for (int i=0; i<N && maxNum > 0; i++) {
7037                TaskRecord tr = mRecentTasks.get(i);
7038                // Only add calling user or related users recent tasks
7039                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7040
7041                // Return the entry if desired by the caller.  We always return
7042                // the first entry, because callers always expect this to be the
7043                // foreground app.  We may filter others if the caller has
7044                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7045                // we should exclude the entry.
7046
7047                if (i == 0
7048                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7049                        || (tr.intent == null)
7050                        || ((tr.intent.getFlags()
7051                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7052                    if (!allowed) {
7053                        // If the caller doesn't have the GET_TASKS permission, then only
7054                        // allow them to see a small subset of tasks -- their own and home.
7055                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7056                            continue;
7057                        }
7058                    }
7059                    ActivityManager.RecentTaskInfo rti
7060                            = new ActivityManager.RecentTaskInfo();
7061                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7062                    rti.persistentId = tr.taskId;
7063                    rti.baseIntent = new Intent(
7064                            tr.intent != null ? tr.intent : tr.affinityIntent);
7065                    if (!detailed) {
7066                        rti.baseIntent.replaceExtras((Bundle)null);
7067                    }
7068                    rti.origActivity = tr.origActivity;
7069                    rti.description = tr.lastDescription;
7070                    rti.stackId = tr.stack.mStackId;
7071                    rti.userId = tr.userId;
7072
7073                    // Traverse upwards looking for any break between main task activities and
7074                    // utility activities.
7075                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7076                    int activityNdx;
7077                    final int numActivities = activities.size();
7078                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7079                            ++activityNdx) {
7080                        final ActivityRecord r = activities.get(activityNdx);
7081                        if (r.intent != null &&
7082                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7083                                        != 0) {
7084                            break;
7085                        }
7086                    }
7087                    if (activityNdx > 0) {
7088                        // Traverse downwards starting below break looking for set label, icon.
7089                        // Note that if there are activities in the task but none of them set the
7090                        // recent activity values, then we do not fall back to the last set
7091                        // values in the TaskRecord.
7092                        rti.activityValues = new ActivityManager.RecentsActivityValues();
7093                        for (--activityNdx; activityNdx >= 0; --activityNdx) {
7094                            final ActivityRecord r = activities.get(activityNdx);
7095                            if (r.activityValues != null) {
7096                                if (rti.activityValues.label == null) {
7097                                    rti.activityValues.label = r.activityValues.label;
7098                                    tr.lastActivityValues.label = r.activityValues.label;
7099                                }
7100                                if (rti.activityValues.icon == null) {
7101                                    rti.activityValues.icon = r.activityValues.icon;
7102                                    tr.lastActivityValues.icon = r.activityValues.icon;
7103                                }
7104                                if (rti.activityValues.colorPrimary == 0) {
7105                                    rti.activityValues.colorPrimary = r.activityValues.colorPrimary;
7106                                    tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary;
7107                                }
7108                            }
7109                        }
7110                    } else {
7111                        // If there are no activity records in this task, then we use the last
7112                        // resolved values
7113                        rti.activityValues =
7114                                new ActivityManager.RecentsActivityValues(tr.lastActivityValues);
7115                    }
7116
7117                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7118                        // Check whether this activity is currently available.
7119                        try {
7120                            if (rti.origActivity != null) {
7121                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7122                                        == null) {
7123                                    continue;
7124                                }
7125                            } else if (rti.baseIntent != null) {
7126                                if (pm.queryIntentActivities(rti.baseIntent,
7127                                        null, 0, userId) == null) {
7128                                    continue;
7129                                }
7130                            }
7131                        } catch (RemoteException e) {
7132                            // Will never happen.
7133                        }
7134                    }
7135
7136                    res.add(rti);
7137                    maxNum--;
7138                }
7139            }
7140            return res;
7141        }
7142    }
7143
7144    private TaskRecord recentTaskForIdLocked(int id) {
7145        final int N = mRecentTasks.size();
7146            for (int i=0; i<N; i++) {
7147                TaskRecord tr = mRecentTasks.get(i);
7148                if (tr.taskId == id) {
7149                    return tr;
7150                }
7151            }
7152            return null;
7153    }
7154
7155    @Override
7156    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7157        synchronized (this) {
7158            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7159                    "getTaskThumbnails()");
7160            TaskRecord tr = recentTaskForIdLocked(id);
7161            if (tr != null) {
7162                return tr.getTaskThumbnailsLocked();
7163            }
7164        }
7165        return null;
7166    }
7167
7168    @Override
7169    public Bitmap getTaskTopThumbnail(int id) {
7170        synchronized (this) {
7171            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7172                    "getTaskTopThumbnail()");
7173            TaskRecord tr = recentTaskForIdLocked(id);
7174            if (tr != null) {
7175                return tr.getTaskTopThumbnailLocked();
7176            }
7177        }
7178        return null;
7179    }
7180
7181    @Override
7182    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) {
7183        synchronized (this) {
7184            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7185            if (r != null) {
7186                r.activityValues = rav;
7187            }
7188        }
7189    }
7190
7191    @Override
7192    public boolean removeSubTask(int taskId, int subTaskIndex) {
7193        synchronized (this) {
7194            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7195                    "removeSubTask()");
7196            long ident = Binder.clearCallingIdentity();
7197            try {
7198                TaskRecord tr = recentTaskForIdLocked(taskId);
7199                if (tr != null) {
7200                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7201                }
7202                return false;
7203            } finally {
7204                Binder.restoreCallingIdentity(ident);
7205            }
7206        }
7207    }
7208
7209    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7210        if (!pr.killedByAm) {
7211            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7212            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7213                    pr.processName, pr.setAdj, reason);
7214            pr.killedByAm = true;
7215            Process.killProcessQuiet(pr.pid);
7216        }
7217    }
7218
7219    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7220        tr.disposeThumbnail();
7221        mRecentTasks.remove(tr);
7222        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7223        Intent baseIntent = new Intent(
7224                tr.intent != null ? tr.intent : tr.affinityIntent);
7225        ComponentName component = baseIntent.getComponent();
7226        if (component == null) {
7227            Slog.w(TAG, "Now component for base intent of task: " + tr);
7228            return;
7229        }
7230
7231        // Find any running services associated with this app.
7232        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7233
7234        if (killProcesses) {
7235            // Find any running processes associated with this app.
7236            final String pkg = component.getPackageName();
7237            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7238            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7239            for (int i=0; i<pmap.size(); i++) {
7240                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7241                for (int j=0; j<uids.size(); j++) {
7242                    ProcessRecord proc = uids.valueAt(j);
7243                    if (proc.userId != tr.userId) {
7244                        continue;
7245                    }
7246                    if (!proc.pkgList.containsKey(pkg)) {
7247                        continue;
7248                    }
7249                    procs.add(proc);
7250                }
7251            }
7252
7253            // Kill the running processes.
7254            for (int i=0; i<procs.size(); i++) {
7255                ProcessRecord pr = procs.get(i);
7256                if (pr == mHomeProcess) {
7257                    // Don't kill the home process along with tasks from the same package.
7258                    continue;
7259                }
7260                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7261                    killUnneededProcessLocked(pr, "remove task");
7262                } else {
7263                    pr.waitingToKill = "remove task";
7264                }
7265            }
7266        }
7267    }
7268
7269    /**
7270     * Removes the task with the specified task id.
7271     *
7272     * @param taskId Identifier of the task to be removed.
7273     * @param flags Additional operational flags.  May be 0 or
7274     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7275     * @return Returns true if the given task was found and removed.
7276     */
7277    private boolean removeTaskByIdLocked(int taskId, int flags) {
7278        TaskRecord tr = recentTaskForIdLocked(taskId);
7279        if (tr != null) {
7280            tr.removeTaskActivitiesLocked(-1, false);
7281            cleanUpRemovedTaskLocked(tr, flags);
7282            return true;
7283        }
7284        return false;
7285    }
7286
7287    @Override
7288    public boolean removeTask(int taskId, int flags) {
7289        synchronized (this) {
7290            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7291                    "removeTask()");
7292            long ident = Binder.clearCallingIdentity();
7293            try {
7294                return removeTaskByIdLocked(taskId, flags);
7295            } finally {
7296                Binder.restoreCallingIdentity(ident);
7297            }
7298        }
7299    }
7300
7301    /**
7302     * TODO: Add mController hook
7303     */
7304    @Override
7305    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7306        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7307                "moveTaskToFront()");
7308
7309        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7310        synchronized(this) {
7311            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7312                    Binder.getCallingUid(), "Task to front")) {
7313                ActivityOptions.abort(options);
7314                return;
7315            }
7316            final long origId = Binder.clearCallingIdentity();
7317            try {
7318                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7319                if (task == null) {
7320                    return;
7321                }
7322                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7323                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7324                    return;
7325                }
7326                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7327            } finally {
7328                Binder.restoreCallingIdentity(origId);
7329            }
7330            ActivityOptions.abort(options);
7331        }
7332    }
7333
7334    @Override
7335    public void moveTaskToBack(int taskId) {
7336        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7337                "moveTaskToBack()");
7338
7339        synchronized(this) {
7340            TaskRecord tr = recentTaskForIdLocked(taskId);
7341            if (tr != null) {
7342                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7343                ActivityStack stack = tr.stack;
7344                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7345                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7346                            Binder.getCallingUid(), "Task to back")) {
7347                        return;
7348                    }
7349                }
7350                final long origId = Binder.clearCallingIdentity();
7351                try {
7352                    stack.moveTaskToBackLocked(taskId, null);
7353                } finally {
7354                    Binder.restoreCallingIdentity(origId);
7355                }
7356            }
7357        }
7358    }
7359
7360    /**
7361     * Moves an activity, and all of the other activities within the same task, to the bottom
7362     * of the history stack.  The activity's order within the task is unchanged.
7363     *
7364     * @param token A reference to the activity we wish to move
7365     * @param nonRoot If false then this only works if the activity is the root
7366     *                of a task; if true it will work for any activity in a task.
7367     * @return Returns true if the move completed, false if not.
7368     */
7369    @Override
7370    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7371        enforceNotIsolatedCaller("moveActivityTaskToBack");
7372        synchronized(this) {
7373            final long origId = Binder.clearCallingIdentity();
7374            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7375            if (taskId >= 0) {
7376                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7377            }
7378            Binder.restoreCallingIdentity(origId);
7379        }
7380        return false;
7381    }
7382
7383    @Override
7384    public void moveTaskBackwards(int task) {
7385        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7386                "moveTaskBackwards()");
7387
7388        synchronized(this) {
7389            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7390                    Binder.getCallingUid(), "Task backwards")) {
7391                return;
7392            }
7393            final long origId = Binder.clearCallingIdentity();
7394            moveTaskBackwardsLocked(task);
7395            Binder.restoreCallingIdentity(origId);
7396        }
7397    }
7398
7399    private final void moveTaskBackwardsLocked(int task) {
7400        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7401    }
7402
7403    @Override
7404    public IBinder getHomeActivityToken() throws RemoteException {
7405        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7406                "getHomeActivityToken()");
7407        synchronized (this) {
7408            return mStackSupervisor.getHomeActivityToken();
7409        }
7410    }
7411
7412    @Override
7413    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7414            IActivityContainerCallback callback) throws RemoteException {
7415        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7416                "createActivityContainer()");
7417        synchronized (this) {
7418            if (parentActivityToken == null) {
7419                throw new IllegalArgumentException("parent token must not be null");
7420            }
7421            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7422            if (r == null) {
7423                return null;
7424            }
7425            if (callback == null) {
7426                throw new IllegalArgumentException("callback must not be null");
7427            }
7428            return mStackSupervisor.createActivityContainer(r, callback);
7429        }
7430    }
7431
7432    @Override
7433    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7434        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7435                "deleteActivityContainer()");
7436        synchronized (this) {
7437            mStackSupervisor.deleteActivityContainer(container);
7438        }
7439    }
7440
7441    @Override
7442    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7443            throws RemoteException {
7444        synchronized (this) {
7445            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7446            if (stack != null) {
7447                return stack.mActivityContainer;
7448            }
7449            return null;
7450        }
7451    }
7452
7453    @Override
7454    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7455        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7456                "moveTaskToStack()");
7457        if (stackId == HOME_STACK_ID) {
7458            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7459                    new RuntimeException("here").fillInStackTrace());
7460        }
7461        synchronized (this) {
7462            long ident = Binder.clearCallingIdentity();
7463            try {
7464                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7465                        + stackId + " toTop=" + toTop);
7466                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7467            } finally {
7468                Binder.restoreCallingIdentity(ident);
7469            }
7470        }
7471    }
7472
7473    @Override
7474    public void resizeStack(int stackBoxId, Rect bounds) {
7475        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7476                "resizeStackBox()");
7477        long ident = Binder.clearCallingIdentity();
7478        try {
7479            mWindowManager.resizeStack(stackBoxId, bounds);
7480        } finally {
7481            Binder.restoreCallingIdentity(ident);
7482        }
7483    }
7484
7485    @Override
7486    public List<StackInfo> getAllStackInfos() {
7487        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7488                "getAllStackInfos()");
7489        long ident = Binder.clearCallingIdentity();
7490        try {
7491            synchronized (this) {
7492                return mStackSupervisor.getAllStackInfosLocked();
7493            }
7494        } finally {
7495            Binder.restoreCallingIdentity(ident);
7496        }
7497    }
7498
7499    @Override
7500    public StackInfo getStackInfo(int stackId) {
7501        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7502                "getStackInfo()");
7503        long ident = Binder.clearCallingIdentity();
7504        try {
7505            synchronized (this) {
7506                return mStackSupervisor.getStackInfoLocked(stackId);
7507            }
7508        } finally {
7509            Binder.restoreCallingIdentity(ident);
7510        }
7511    }
7512
7513    @Override
7514    public boolean isInHomeStack(int taskId) {
7515        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7516                "getStackInfo()");
7517        long ident = Binder.clearCallingIdentity();
7518        try {
7519            synchronized (this) {
7520                TaskRecord tr = recentTaskForIdLocked(taskId);
7521                if (tr != null) {
7522                    return tr.stack.isHomeStack();
7523                }
7524            }
7525        } finally {
7526            Binder.restoreCallingIdentity(ident);
7527        }
7528        return false;
7529    }
7530
7531    @Override
7532    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7533        synchronized(this) {
7534            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7535        }
7536    }
7537
7538    private boolean isLockTaskAuthorized(ComponentName name) {
7539//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7540//                "startLockTaskMode()");
7541//        DevicePolicyManager dpm = (DevicePolicyManager)
7542//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7543//        return dpm != null && dpm.isLockTaskPermitted(name);
7544        return true;
7545    }
7546
7547    private void startLockTaskMode(TaskRecord task) {
7548        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7549            return;
7550        }
7551        long ident = Binder.clearCallingIdentity();
7552        try {
7553            synchronized (this) {
7554                // Since we lost lock on task, make sure it is still there.
7555                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7556                if (task != null) {
7557                    mStackSupervisor.setLockTaskModeLocked(task);
7558                }
7559            }
7560        } finally {
7561            Binder.restoreCallingIdentity(ident);
7562        }
7563    }
7564
7565    @Override
7566    public void startLockTaskMode(int taskId) {
7567        long ident = Binder.clearCallingIdentity();
7568        try {
7569            final TaskRecord task;
7570            synchronized (this) {
7571                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7572            }
7573            if (task != null) {
7574                startLockTaskMode(task);
7575            }
7576        } finally {
7577            Binder.restoreCallingIdentity(ident);
7578        }
7579    }
7580
7581    @Override
7582    public void startLockTaskMode(IBinder token) {
7583        long ident = Binder.clearCallingIdentity();
7584        try {
7585            final TaskRecord task;
7586            synchronized (this) {
7587                final ActivityRecord r = ActivityRecord.forToken(token);
7588                if (r == null) {
7589                    return;
7590                }
7591                task = r.task;
7592            }
7593            if (task != null) {
7594                startLockTaskMode(task);
7595            }
7596        } finally {
7597            Binder.restoreCallingIdentity(ident);
7598        }
7599    }
7600
7601    @Override
7602    public void stopLockTaskMode() {
7603//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7604//                "stopLockTaskMode()");
7605        synchronized (this) {
7606            mStackSupervisor.setLockTaskModeLocked(null);
7607        }
7608    }
7609
7610    @Override
7611    public boolean isInLockTaskMode() {
7612        synchronized (this) {
7613            return mStackSupervisor.isInLockTaskMode();
7614        }
7615    }
7616
7617    // =========================================================
7618    // CONTENT PROVIDERS
7619    // =========================================================
7620
7621    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7622        List<ProviderInfo> providers = null;
7623        try {
7624            providers = AppGlobals.getPackageManager().
7625                queryContentProviders(app.processName, app.uid,
7626                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7627        } catch (RemoteException ex) {
7628        }
7629        if (DEBUG_MU)
7630            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7631        int userId = app.userId;
7632        if (providers != null) {
7633            int N = providers.size();
7634            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7635            for (int i=0; i<N; i++) {
7636                ProviderInfo cpi =
7637                    (ProviderInfo)providers.get(i);
7638                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7639                        cpi.name, cpi.flags);
7640                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7641                    // This is a singleton provider, but a user besides the
7642                    // default user is asking to initialize a process it runs
7643                    // in...  well, no, it doesn't actually run in this process,
7644                    // it runs in the process of the default user.  Get rid of it.
7645                    providers.remove(i);
7646                    N--;
7647                    i--;
7648                    continue;
7649                }
7650
7651                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7652                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7653                if (cpr == null) {
7654                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7655                    mProviderMap.putProviderByClass(comp, cpr);
7656                }
7657                if (DEBUG_MU)
7658                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7659                app.pubProviders.put(cpi.name, cpr);
7660                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7661                    // Don't add this if it is a platform component that is marked
7662                    // to run in multiple processes, because this is actually
7663                    // part of the framework so doesn't make sense to track as a
7664                    // separate apk in the process.
7665                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7666                }
7667                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7668            }
7669        }
7670        return providers;
7671    }
7672
7673    /**
7674     * Check if {@link ProcessRecord} has a possible chance at accessing the
7675     * given {@link ProviderInfo}. Final permission checking is always done
7676     * in {@link ContentProvider}.
7677     */
7678    private final String checkContentProviderPermissionLocked(
7679            ProviderInfo cpi, ProcessRecord r) {
7680        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7681        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7682        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7683                cpi.applicationInfo.uid, cpi.exported)
7684                == PackageManager.PERMISSION_GRANTED) {
7685            return null;
7686        }
7687        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7688                cpi.applicationInfo.uid, cpi.exported)
7689                == PackageManager.PERMISSION_GRANTED) {
7690            return null;
7691        }
7692
7693        PathPermission[] pps = cpi.pathPermissions;
7694        if (pps != null) {
7695            int i = pps.length;
7696            while (i > 0) {
7697                i--;
7698                PathPermission pp = pps[i];
7699                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7700                        cpi.applicationInfo.uid, cpi.exported)
7701                        == PackageManager.PERMISSION_GRANTED) {
7702                    return null;
7703                }
7704                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7705                        cpi.applicationInfo.uid, cpi.exported)
7706                        == PackageManager.PERMISSION_GRANTED) {
7707                    return null;
7708                }
7709            }
7710        }
7711
7712        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7713        if (perms != null) {
7714            for (GrantUri uri : perms.keySet()) {
7715                if (uri.uri.getAuthority().equals(cpi.authority)) {
7716                    return null;
7717                }
7718            }
7719        }
7720
7721        String msg;
7722        if (!cpi.exported) {
7723            msg = "Permission Denial: opening provider " + cpi.name
7724                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7725                    + ", uid=" + callingUid + ") that is not exported from uid "
7726                    + cpi.applicationInfo.uid;
7727        } else {
7728            msg = "Permission Denial: opening provider " + cpi.name
7729                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7730                    + ", uid=" + callingUid + ") requires "
7731                    + cpi.readPermission + " or " + cpi.writePermission;
7732        }
7733        Slog.w(TAG, msg);
7734        return msg;
7735    }
7736
7737    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7738            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7739        if (r != null) {
7740            for (int i=0; i<r.conProviders.size(); i++) {
7741                ContentProviderConnection conn = r.conProviders.get(i);
7742                if (conn.provider == cpr) {
7743                    if (DEBUG_PROVIDER) Slog.v(TAG,
7744                            "Adding provider requested by "
7745                            + r.processName + " from process "
7746                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7747                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7748                    if (stable) {
7749                        conn.stableCount++;
7750                        conn.numStableIncs++;
7751                    } else {
7752                        conn.unstableCount++;
7753                        conn.numUnstableIncs++;
7754                    }
7755                    return conn;
7756                }
7757            }
7758            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7759            if (stable) {
7760                conn.stableCount = 1;
7761                conn.numStableIncs = 1;
7762            } else {
7763                conn.unstableCount = 1;
7764                conn.numUnstableIncs = 1;
7765            }
7766            cpr.connections.add(conn);
7767            r.conProviders.add(conn);
7768            return conn;
7769        }
7770        cpr.addExternalProcessHandleLocked(externalProcessToken);
7771        return null;
7772    }
7773
7774    boolean decProviderCountLocked(ContentProviderConnection conn,
7775            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7776        if (conn != null) {
7777            cpr = conn.provider;
7778            if (DEBUG_PROVIDER) Slog.v(TAG,
7779                    "Removing provider requested by "
7780                    + conn.client.processName + " from process "
7781                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7782                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7783            if (stable) {
7784                conn.stableCount--;
7785            } else {
7786                conn.unstableCount--;
7787            }
7788            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7789                cpr.connections.remove(conn);
7790                conn.client.conProviders.remove(conn);
7791                return true;
7792            }
7793            return false;
7794        }
7795        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7796        return false;
7797    }
7798
7799    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7800            String name, IBinder token, boolean stable, int userId) {
7801        ContentProviderRecord cpr;
7802        ContentProviderConnection conn = null;
7803        ProviderInfo cpi = null;
7804
7805        synchronized(this) {
7806            ProcessRecord r = null;
7807            if (caller != null) {
7808                r = getRecordForAppLocked(caller);
7809                if (r == null) {
7810                    throw new SecurityException(
7811                            "Unable to find app for caller " + caller
7812                          + " (pid=" + Binder.getCallingPid()
7813                          + ") when getting content provider " + name);
7814                }
7815            }
7816
7817            // First check if this content provider has been published...
7818            cpr = mProviderMap.getProviderByName(name, userId);
7819            boolean providerRunning = cpr != null;
7820            if (providerRunning) {
7821                cpi = cpr.info;
7822                String msg;
7823                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7824                    throw new SecurityException(msg);
7825                }
7826
7827                if (r != null && cpr.canRunHere(r)) {
7828                    // This provider has been published or is in the process
7829                    // of being published...  but it is also allowed to run
7830                    // in the caller's process, so don't make a connection
7831                    // and just let the caller instantiate its own instance.
7832                    ContentProviderHolder holder = cpr.newHolder(null);
7833                    // don't give caller the provider object, it needs
7834                    // to make its own.
7835                    holder.provider = null;
7836                    return holder;
7837                }
7838
7839                final long origId = Binder.clearCallingIdentity();
7840
7841                // In this case the provider instance already exists, so we can
7842                // return it right away.
7843                conn = incProviderCountLocked(r, cpr, token, stable);
7844                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7845                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7846                        // If this is a perceptible app accessing the provider,
7847                        // make sure to count it as being accessed and thus
7848                        // back up on the LRU list.  This is good because
7849                        // content providers are often expensive to start.
7850                        updateLruProcessLocked(cpr.proc, false, null);
7851                    }
7852                }
7853
7854                if (cpr.proc != null) {
7855                    if (false) {
7856                        if (cpr.name.flattenToShortString().equals(
7857                                "com.android.providers.calendar/.CalendarProvider2")) {
7858                            Slog.v(TAG, "****************** KILLING "
7859                                + cpr.name.flattenToShortString());
7860                            Process.killProcess(cpr.proc.pid);
7861                        }
7862                    }
7863                    boolean success = updateOomAdjLocked(cpr.proc);
7864                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7865                    // NOTE: there is still a race here where a signal could be
7866                    // pending on the process even though we managed to update its
7867                    // adj level.  Not sure what to do about this, but at least
7868                    // the race is now smaller.
7869                    if (!success) {
7870                        // Uh oh...  it looks like the provider's process
7871                        // has been killed on us.  We need to wait for a new
7872                        // process to be started, and make sure its death
7873                        // doesn't kill our process.
7874                        Slog.i(TAG,
7875                                "Existing provider " + cpr.name.flattenToShortString()
7876                                + " is crashing; detaching " + r);
7877                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7878                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7879                        if (!lastRef) {
7880                            // This wasn't the last ref our process had on
7881                            // the provider...  we have now been killed, bail.
7882                            return null;
7883                        }
7884                        providerRunning = false;
7885                        conn = null;
7886                    }
7887                }
7888
7889                Binder.restoreCallingIdentity(origId);
7890            }
7891
7892            boolean singleton;
7893            if (!providerRunning) {
7894                try {
7895                    cpi = AppGlobals.getPackageManager().
7896                        resolveContentProvider(name,
7897                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7898                } catch (RemoteException ex) {
7899                }
7900                if (cpi == null) {
7901                    return null;
7902                }
7903                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7904                        cpi.name, cpi.flags);
7905                if (singleton) {
7906                    userId = 0;
7907                }
7908                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7909
7910                String msg;
7911                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7912                    throw new SecurityException(msg);
7913                }
7914
7915                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7916                        && !cpi.processName.equals("system")) {
7917                    // If this content provider does not run in the system
7918                    // process, and the system is not yet ready to run other
7919                    // processes, then fail fast instead of hanging.
7920                    throw new IllegalArgumentException(
7921                            "Attempt to launch content provider before system ready");
7922                }
7923
7924                // Make sure that the user who owns this provider is started.  If not,
7925                // we don't want to allow it to run.
7926                if (mStartedUsers.get(userId) == null) {
7927                    Slog.w(TAG, "Unable to launch app "
7928                            + cpi.applicationInfo.packageName + "/"
7929                            + cpi.applicationInfo.uid + " for provider "
7930                            + name + ": user " + userId + " is stopped");
7931                    return null;
7932                }
7933
7934                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7935                cpr = mProviderMap.getProviderByClass(comp, userId);
7936                final boolean firstClass = cpr == null;
7937                if (firstClass) {
7938                    try {
7939                        ApplicationInfo ai =
7940                            AppGlobals.getPackageManager().
7941                                getApplicationInfo(
7942                                        cpi.applicationInfo.packageName,
7943                                        STOCK_PM_FLAGS, userId);
7944                        if (ai == null) {
7945                            Slog.w(TAG, "No package info for content provider "
7946                                    + cpi.name);
7947                            return null;
7948                        }
7949                        ai = getAppInfoForUser(ai, userId);
7950                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7951                    } catch (RemoteException ex) {
7952                        // pm is in same process, this will never happen.
7953                    }
7954                }
7955
7956                if (r != null && cpr.canRunHere(r)) {
7957                    // If this is a multiprocess provider, then just return its
7958                    // info and allow the caller to instantiate it.  Only do
7959                    // this if the provider is the same user as the caller's
7960                    // process, or can run as root (so can be in any process).
7961                    return cpr.newHolder(null);
7962                }
7963
7964                if (DEBUG_PROVIDER) {
7965                    RuntimeException e = new RuntimeException("here");
7966                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7967                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7968                }
7969
7970                // This is single process, and our app is now connecting to it.
7971                // See if we are already in the process of launching this
7972                // provider.
7973                final int N = mLaunchingProviders.size();
7974                int i;
7975                for (i=0; i<N; i++) {
7976                    if (mLaunchingProviders.get(i) == cpr) {
7977                        break;
7978                    }
7979                }
7980
7981                // If the provider is not already being launched, then get it
7982                // started.
7983                if (i >= N) {
7984                    final long origId = Binder.clearCallingIdentity();
7985
7986                    try {
7987                        // Content provider is now in use, its package can't be stopped.
7988                        try {
7989                            AppGlobals.getPackageManager().setPackageStoppedState(
7990                                    cpr.appInfo.packageName, false, userId);
7991                        } catch (RemoteException e) {
7992                        } catch (IllegalArgumentException e) {
7993                            Slog.w(TAG, "Failed trying to unstop package "
7994                                    + cpr.appInfo.packageName + ": " + e);
7995                        }
7996
7997                        // Use existing process if already started
7998                        ProcessRecord proc = getProcessRecordLocked(
7999                                cpi.processName, cpr.appInfo.uid, false);
8000                        if (proc != null && proc.thread != null) {
8001                            if (DEBUG_PROVIDER) {
8002                                Slog.d(TAG, "Installing in existing process " + proc);
8003                            }
8004                            proc.pubProviders.put(cpi.name, cpr);
8005                            try {
8006                                proc.thread.scheduleInstallProvider(cpi);
8007                            } catch (RemoteException e) {
8008                            }
8009                        } else {
8010                            proc = startProcessLocked(cpi.processName,
8011                                    cpr.appInfo, false, 0, "content provider",
8012                                    new ComponentName(cpi.applicationInfo.packageName,
8013                                            cpi.name), false, false, false);
8014                            if (proc == null) {
8015                                Slog.w(TAG, "Unable to launch app "
8016                                        + cpi.applicationInfo.packageName + "/"
8017                                        + cpi.applicationInfo.uid + " for provider "
8018                                        + name + ": process is bad");
8019                                return null;
8020                            }
8021                        }
8022                        cpr.launchingApp = proc;
8023                        mLaunchingProviders.add(cpr);
8024                    } finally {
8025                        Binder.restoreCallingIdentity(origId);
8026                    }
8027                }
8028
8029                // Make sure the provider is published (the same provider class
8030                // may be published under multiple names).
8031                if (firstClass) {
8032                    mProviderMap.putProviderByClass(comp, cpr);
8033                }
8034
8035                mProviderMap.putProviderByName(name, cpr);
8036                conn = incProviderCountLocked(r, cpr, token, stable);
8037                if (conn != null) {
8038                    conn.waiting = true;
8039                }
8040            }
8041        }
8042
8043        // Wait for the provider to be published...
8044        synchronized (cpr) {
8045            while (cpr.provider == null) {
8046                if (cpr.launchingApp == null) {
8047                    Slog.w(TAG, "Unable to launch app "
8048                            + cpi.applicationInfo.packageName + "/"
8049                            + cpi.applicationInfo.uid + " for provider "
8050                            + name + ": launching app became null");
8051                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8052                            UserHandle.getUserId(cpi.applicationInfo.uid),
8053                            cpi.applicationInfo.packageName,
8054                            cpi.applicationInfo.uid, name);
8055                    return null;
8056                }
8057                try {
8058                    if (DEBUG_MU) {
8059                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8060                                + cpr.launchingApp);
8061                    }
8062                    if (conn != null) {
8063                        conn.waiting = true;
8064                    }
8065                    cpr.wait();
8066                } catch (InterruptedException ex) {
8067                } finally {
8068                    if (conn != null) {
8069                        conn.waiting = false;
8070                    }
8071                }
8072            }
8073        }
8074        return cpr != null ? cpr.newHolder(conn) : null;
8075    }
8076
8077    public final ContentProviderHolder getContentProvider(
8078            IApplicationThread caller, String name, int userId, boolean stable) {
8079        enforceNotIsolatedCaller("getContentProvider");
8080        if (caller == null) {
8081            String msg = "null IApplicationThread when getting content provider "
8082                    + name;
8083            Slog.w(TAG, msg);
8084            throw new SecurityException(msg);
8085        }
8086
8087        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8088                false, true, "getContentProvider", null);
8089        return getContentProviderImpl(caller, name, null, stable, userId);
8090    }
8091
8092    public ContentProviderHolder getContentProviderExternal(
8093            String name, int userId, IBinder token) {
8094        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8095            "Do not have permission in call getContentProviderExternal()");
8096        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8097                false, true, "getContentProvider", null);
8098        return getContentProviderExternalUnchecked(name, token, userId);
8099    }
8100
8101    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8102            IBinder token, int userId) {
8103        return getContentProviderImpl(null, name, token, true, userId);
8104    }
8105
8106    /**
8107     * Drop a content provider from a ProcessRecord's bookkeeping
8108     */
8109    public void removeContentProvider(IBinder connection, boolean stable) {
8110        enforceNotIsolatedCaller("removeContentProvider");
8111        long ident = Binder.clearCallingIdentity();
8112        try {
8113            synchronized (this) {
8114                ContentProviderConnection conn;
8115                try {
8116                    conn = (ContentProviderConnection)connection;
8117                } catch (ClassCastException e) {
8118                    String msg ="removeContentProvider: " + connection
8119                            + " not a ContentProviderConnection";
8120                    Slog.w(TAG, msg);
8121                    throw new IllegalArgumentException(msg);
8122                }
8123                if (conn == null) {
8124                    throw new NullPointerException("connection is null");
8125                }
8126                if (decProviderCountLocked(conn, null, null, stable)) {
8127                    updateOomAdjLocked();
8128                }
8129            }
8130        } finally {
8131            Binder.restoreCallingIdentity(ident);
8132        }
8133    }
8134
8135    public void removeContentProviderExternal(String name, IBinder token) {
8136        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8137            "Do not have permission in call removeContentProviderExternal()");
8138        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8139    }
8140
8141    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8142        synchronized (this) {
8143            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8144            if(cpr == null) {
8145                //remove from mProvidersByClass
8146                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8147                return;
8148            }
8149
8150            //update content provider record entry info
8151            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8152            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8153            if (localCpr.hasExternalProcessHandles()) {
8154                if (localCpr.removeExternalProcessHandleLocked(token)) {
8155                    updateOomAdjLocked();
8156                } else {
8157                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8158                            + " with no external reference for token: "
8159                            + token + ".");
8160                }
8161            } else {
8162                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8163                        + " with no external references.");
8164            }
8165        }
8166    }
8167
8168    public final void publishContentProviders(IApplicationThread caller,
8169            List<ContentProviderHolder> providers) {
8170        if (providers == null) {
8171            return;
8172        }
8173
8174        enforceNotIsolatedCaller("publishContentProviders");
8175        synchronized (this) {
8176            final ProcessRecord r = getRecordForAppLocked(caller);
8177            if (DEBUG_MU)
8178                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8179            if (r == null) {
8180                throw new SecurityException(
8181                        "Unable to find app for caller " + caller
8182                      + " (pid=" + Binder.getCallingPid()
8183                      + ") when publishing content providers");
8184            }
8185
8186            final long origId = Binder.clearCallingIdentity();
8187
8188            final int N = providers.size();
8189            for (int i=0; i<N; i++) {
8190                ContentProviderHolder src = providers.get(i);
8191                if (src == null || src.info == null || src.provider == null) {
8192                    continue;
8193                }
8194                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8195                if (DEBUG_MU)
8196                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8197                if (dst != null) {
8198                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8199                    mProviderMap.putProviderByClass(comp, dst);
8200                    String names[] = dst.info.authority.split(";");
8201                    for (int j = 0; j < names.length; j++) {
8202                        mProviderMap.putProviderByName(names[j], dst);
8203                    }
8204
8205                    int NL = mLaunchingProviders.size();
8206                    int j;
8207                    for (j=0; j<NL; j++) {
8208                        if (mLaunchingProviders.get(j) == dst) {
8209                            mLaunchingProviders.remove(j);
8210                            j--;
8211                            NL--;
8212                        }
8213                    }
8214                    synchronized (dst) {
8215                        dst.provider = src.provider;
8216                        dst.proc = r;
8217                        dst.notifyAll();
8218                    }
8219                    updateOomAdjLocked(r);
8220                }
8221            }
8222
8223            Binder.restoreCallingIdentity(origId);
8224        }
8225    }
8226
8227    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8228        ContentProviderConnection conn;
8229        try {
8230            conn = (ContentProviderConnection)connection;
8231        } catch (ClassCastException e) {
8232            String msg ="refContentProvider: " + connection
8233                    + " not a ContentProviderConnection";
8234            Slog.w(TAG, msg);
8235            throw new IllegalArgumentException(msg);
8236        }
8237        if (conn == null) {
8238            throw new NullPointerException("connection is null");
8239        }
8240
8241        synchronized (this) {
8242            if (stable > 0) {
8243                conn.numStableIncs += stable;
8244            }
8245            stable = conn.stableCount + stable;
8246            if (stable < 0) {
8247                throw new IllegalStateException("stableCount < 0: " + stable);
8248            }
8249
8250            if (unstable > 0) {
8251                conn.numUnstableIncs += unstable;
8252            }
8253            unstable = conn.unstableCount + unstable;
8254            if (unstable < 0) {
8255                throw new IllegalStateException("unstableCount < 0: " + unstable);
8256            }
8257
8258            if ((stable+unstable) <= 0) {
8259                throw new IllegalStateException("ref counts can't go to zero here: stable="
8260                        + stable + " unstable=" + unstable);
8261            }
8262            conn.stableCount = stable;
8263            conn.unstableCount = unstable;
8264            return !conn.dead;
8265        }
8266    }
8267
8268    public void unstableProviderDied(IBinder connection) {
8269        ContentProviderConnection conn;
8270        try {
8271            conn = (ContentProviderConnection)connection;
8272        } catch (ClassCastException e) {
8273            String msg ="refContentProvider: " + connection
8274                    + " not a ContentProviderConnection";
8275            Slog.w(TAG, msg);
8276            throw new IllegalArgumentException(msg);
8277        }
8278        if (conn == null) {
8279            throw new NullPointerException("connection is null");
8280        }
8281
8282        // Safely retrieve the content provider associated with the connection.
8283        IContentProvider provider;
8284        synchronized (this) {
8285            provider = conn.provider.provider;
8286        }
8287
8288        if (provider == null) {
8289            // Um, yeah, we're way ahead of you.
8290            return;
8291        }
8292
8293        // Make sure the caller is being honest with us.
8294        if (provider.asBinder().pingBinder()) {
8295            // Er, no, still looks good to us.
8296            synchronized (this) {
8297                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8298                        + " says " + conn + " died, but we don't agree");
8299                return;
8300            }
8301        }
8302
8303        // Well look at that!  It's dead!
8304        synchronized (this) {
8305            if (conn.provider.provider != provider) {
8306                // But something changed...  good enough.
8307                return;
8308            }
8309
8310            ProcessRecord proc = conn.provider.proc;
8311            if (proc == null || proc.thread == null) {
8312                // Seems like the process is already cleaned up.
8313                return;
8314            }
8315
8316            // As far as we're concerned, this is just like receiving a
8317            // death notification...  just a bit prematurely.
8318            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8319                    + ") early provider death");
8320            final long ident = Binder.clearCallingIdentity();
8321            try {
8322                appDiedLocked(proc, proc.pid, proc.thread);
8323            } finally {
8324                Binder.restoreCallingIdentity(ident);
8325            }
8326        }
8327    }
8328
8329    @Override
8330    public void appNotRespondingViaProvider(IBinder connection) {
8331        enforceCallingPermission(
8332                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8333
8334        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8335        if (conn == null) {
8336            Slog.w(TAG, "ContentProviderConnection is null");
8337            return;
8338        }
8339
8340        final ProcessRecord host = conn.provider.proc;
8341        if (host == null) {
8342            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8343            return;
8344        }
8345
8346        final long token = Binder.clearCallingIdentity();
8347        try {
8348            appNotResponding(host, null, null, false, "ContentProvider not responding");
8349        } finally {
8350            Binder.restoreCallingIdentity(token);
8351        }
8352    }
8353
8354    public final void installSystemProviders() {
8355        List<ProviderInfo> providers;
8356        synchronized (this) {
8357            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8358            providers = generateApplicationProvidersLocked(app);
8359            if (providers != null) {
8360                for (int i=providers.size()-1; i>=0; i--) {
8361                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8362                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8363                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8364                                + ": not system .apk");
8365                        providers.remove(i);
8366                    }
8367                }
8368            }
8369        }
8370        if (providers != null) {
8371            mSystemThread.installSystemProviders(providers);
8372        }
8373
8374        mCoreSettingsObserver = new CoreSettingsObserver(this);
8375
8376        mUsageStatsService.monitorPackages();
8377    }
8378
8379    /**
8380     * Allows app to retrieve the MIME type of a URI without having permission
8381     * to access its content provider.
8382     *
8383     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8384     *
8385     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8386     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8387     */
8388    public String getProviderMimeType(Uri uri, int userId) {
8389        enforceNotIsolatedCaller("getProviderMimeType");
8390        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8391                userId, false, true, "getProviderMimeType", null);
8392        final String name = uri.getAuthority();
8393        final long ident = Binder.clearCallingIdentity();
8394        ContentProviderHolder holder = null;
8395
8396        try {
8397            holder = getContentProviderExternalUnchecked(name, null, userId);
8398            if (holder != null) {
8399                return holder.provider.getType(uri);
8400            }
8401        } catch (RemoteException e) {
8402            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8403            return null;
8404        } finally {
8405            if (holder != null) {
8406                removeContentProviderExternalUnchecked(name, null, userId);
8407            }
8408            Binder.restoreCallingIdentity(ident);
8409        }
8410
8411        return null;
8412    }
8413
8414    // =========================================================
8415    // GLOBAL MANAGEMENT
8416    // =========================================================
8417
8418    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8419            boolean isolated) {
8420        String proc = customProcess != null ? customProcess : info.processName;
8421        BatteryStatsImpl.Uid.Proc ps = null;
8422        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8423        int uid = info.uid;
8424        if (isolated) {
8425            int userId = UserHandle.getUserId(uid);
8426            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8427            while (true) {
8428                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8429                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8430                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8431                }
8432                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8433                mNextIsolatedProcessUid++;
8434                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8435                    // No process for this uid, use it.
8436                    break;
8437                }
8438                stepsLeft--;
8439                if (stepsLeft <= 0) {
8440                    return null;
8441                }
8442            }
8443        }
8444        return new ProcessRecord(stats, info, proc, uid);
8445    }
8446
8447    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8448        ProcessRecord app;
8449        if (!isolated) {
8450            app = getProcessRecordLocked(info.processName, info.uid, true);
8451        } else {
8452            app = null;
8453        }
8454
8455        if (app == null) {
8456            app = newProcessRecordLocked(info, null, isolated);
8457            mProcessNames.put(info.processName, app.uid, app);
8458            if (isolated) {
8459                mIsolatedProcesses.put(app.uid, app);
8460            }
8461            updateLruProcessLocked(app, false, null);
8462            updateOomAdjLocked();
8463        }
8464
8465        // This package really, really can not be stopped.
8466        try {
8467            AppGlobals.getPackageManager().setPackageStoppedState(
8468                    info.packageName, false, UserHandle.getUserId(app.uid));
8469        } catch (RemoteException e) {
8470        } catch (IllegalArgumentException e) {
8471            Slog.w(TAG, "Failed trying to unstop package "
8472                    + info.packageName + ": " + e);
8473        }
8474
8475        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8476                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8477            app.persistent = true;
8478            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8479        }
8480        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8481            mPersistentStartingProcesses.add(app);
8482            startProcessLocked(app, "added application", app.processName);
8483        }
8484
8485        return app;
8486    }
8487
8488    public void unhandledBack() {
8489        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8490                "unhandledBack()");
8491
8492        synchronized(this) {
8493            final long origId = Binder.clearCallingIdentity();
8494            try {
8495                getFocusedStack().unhandledBackLocked();
8496            } finally {
8497                Binder.restoreCallingIdentity(origId);
8498            }
8499        }
8500    }
8501
8502    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8503        enforceNotIsolatedCaller("openContentUri");
8504        final int userId = UserHandle.getCallingUserId();
8505        String name = uri.getAuthority();
8506        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8507        ParcelFileDescriptor pfd = null;
8508        if (cph != null) {
8509            // We record the binder invoker's uid in thread-local storage before
8510            // going to the content provider to open the file.  Later, in the code
8511            // that handles all permissions checks, we look for this uid and use
8512            // that rather than the Activity Manager's own uid.  The effect is that
8513            // we do the check against the caller's permissions even though it looks
8514            // to the content provider like the Activity Manager itself is making
8515            // the request.
8516            sCallerIdentity.set(new Identity(
8517                    Binder.getCallingPid(), Binder.getCallingUid()));
8518            try {
8519                pfd = cph.provider.openFile(null, uri, "r", null);
8520            } catch (FileNotFoundException e) {
8521                // do nothing; pfd will be returned null
8522            } finally {
8523                // Ensure that whatever happens, we clean up the identity state
8524                sCallerIdentity.remove();
8525            }
8526
8527            // We've got the fd now, so we're done with the provider.
8528            removeContentProviderExternalUnchecked(name, null, userId);
8529        } else {
8530            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8531        }
8532        return pfd;
8533    }
8534
8535    // Actually is sleeping or shutting down or whatever else in the future
8536    // is an inactive state.
8537    public boolean isSleepingOrShuttingDown() {
8538        return mSleeping || mShuttingDown;
8539    }
8540
8541    public boolean isSleeping() {
8542        return mSleeping;
8543    }
8544
8545    void goingToSleep() {
8546        synchronized(this) {
8547            mWentToSleep = true;
8548            updateEventDispatchingLocked();
8549            goToSleepIfNeededLocked();
8550        }
8551    }
8552
8553    void finishRunningVoiceLocked() {
8554        if (mRunningVoice) {
8555            mRunningVoice = false;
8556            goToSleepIfNeededLocked();
8557        }
8558    }
8559
8560    void goToSleepIfNeededLocked() {
8561        if (mWentToSleep && !mRunningVoice) {
8562            if (!mSleeping) {
8563                mSleeping = true;
8564                mStackSupervisor.goingToSleepLocked();
8565
8566                // Initialize the wake times of all processes.
8567                checkExcessivePowerUsageLocked(false);
8568                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8569                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8570                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8571            }
8572        }
8573    }
8574
8575    @Override
8576    public boolean shutdown(int timeout) {
8577        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8578                != PackageManager.PERMISSION_GRANTED) {
8579            throw new SecurityException("Requires permission "
8580                    + android.Manifest.permission.SHUTDOWN);
8581        }
8582
8583        boolean timedout = false;
8584
8585        synchronized(this) {
8586            mShuttingDown = true;
8587            updateEventDispatchingLocked();
8588            timedout = mStackSupervisor.shutdownLocked(timeout);
8589        }
8590
8591        mAppOpsService.shutdown();
8592        mUsageStatsService.shutdown();
8593        mBatteryStatsService.shutdown();
8594        synchronized (this) {
8595            mProcessStats.shutdownLocked();
8596        }
8597
8598        return timedout;
8599    }
8600
8601    public final void activitySlept(IBinder token) {
8602        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8603
8604        final long origId = Binder.clearCallingIdentity();
8605
8606        synchronized (this) {
8607            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8608            if (r != null) {
8609                mStackSupervisor.activitySleptLocked(r);
8610            }
8611        }
8612
8613        Binder.restoreCallingIdentity(origId);
8614    }
8615
8616    void logLockScreen(String msg) {
8617        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8618                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8619                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8620                mStackSupervisor.mDismissKeyguardOnNextActivity);
8621    }
8622
8623    private void comeOutOfSleepIfNeededLocked() {
8624        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8625            if (mSleeping) {
8626                mSleeping = false;
8627                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8628            }
8629        }
8630    }
8631
8632    void wakingUp() {
8633        synchronized(this) {
8634            mWentToSleep = false;
8635            updateEventDispatchingLocked();
8636            comeOutOfSleepIfNeededLocked();
8637        }
8638    }
8639
8640    void startRunningVoiceLocked() {
8641        if (!mRunningVoice) {
8642            mRunningVoice = true;
8643            comeOutOfSleepIfNeededLocked();
8644        }
8645    }
8646
8647    private void updateEventDispatchingLocked() {
8648        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8649    }
8650
8651    public void setLockScreenShown(boolean shown) {
8652        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8653                != PackageManager.PERMISSION_GRANTED) {
8654            throw new SecurityException("Requires permission "
8655                    + android.Manifest.permission.DEVICE_POWER);
8656        }
8657
8658        synchronized(this) {
8659            long ident = Binder.clearCallingIdentity();
8660            try {
8661                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8662                mLockScreenShown = shown;
8663                comeOutOfSleepIfNeededLocked();
8664            } finally {
8665                Binder.restoreCallingIdentity(ident);
8666            }
8667        }
8668    }
8669
8670    public void stopAppSwitches() {
8671        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8672                != PackageManager.PERMISSION_GRANTED) {
8673            throw new SecurityException("Requires permission "
8674                    + android.Manifest.permission.STOP_APP_SWITCHES);
8675        }
8676
8677        synchronized(this) {
8678            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8679                    + APP_SWITCH_DELAY_TIME;
8680            mDidAppSwitch = false;
8681            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8682            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8683            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8684        }
8685    }
8686
8687    public void resumeAppSwitches() {
8688        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8689                != PackageManager.PERMISSION_GRANTED) {
8690            throw new SecurityException("Requires permission "
8691                    + android.Manifest.permission.STOP_APP_SWITCHES);
8692        }
8693
8694        synchronized(this) {
8695            // Note that we don't execute any pending app switches... we will
8696            // let those wait until either the timeout, or the next start
8697            // activity request.
8698            mAppSwitchesAllowedTime = 0;
8699        }
8700    }
8701
8702    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8703            String name) {
8704        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8705            return true;
8706        }
8707
8708        final int perm = checkComponentPermission(
8709                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8710                callingUid, -1, true);
8711        if (perm == PackageManager.PERMISSION_GRANTED) {
8712            return true;
8713        }
8714
8715        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8716        return false;
8717    }
8718
8719    public void setDebugApp(String packageName, boolean waitForDebugger,
8720            boolean persistent) {
8721        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8722                "setDebugApp()");
8723
8724        long ident = Binder.clearCallingIdentity();
8725        try {
8726            // Note that this is not really thread safe if there are multiple
8727            // callers into it at the same time, but that's not a situation we
8728            // care about.
8729            if (persistent) {
8730                final ContentResolver resolver = mContext.getContentResolver();
8731                Settings.Global.putString(
8732                    resolver, Settings.Global.DEBUG_APP,
8733                    packageName);
8734                Settings.Global.putInt(
8735                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8736                    waitForDebugger ? 1 : 0);
8737            }
8738
8739            synchronized (this) {
8740                if (!persistent) {
8741                    mOrigDebugApp = mDebugApp;
8742                    mOrigWaitForDebugger = mWaitForDebugger;
8743                }
8744                mDebugApp = packageName;
8745                mWaitForDebugger = waitForDebugger;
8746                mDebugTransient = !persistent;
8747                if (packageName != null) {
8748                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8749                            false, UserHandle.USER_ALL, "set debug app");
8750                }
8751            }
8752        } finally {
8753            Binder.restoreCallingIdentity(ident);
8754        }
8755    }
8756
8757    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8758        synchronized (this) {
8759            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8760            if (!isDebuggable) {
8761                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8762                    throw new SecurityException("Process not debuggable: " + app.packageName);
8763                }
8764            }
8765
8766            mOpenGlTraceApp = processName;
8767        }
8768    }
8769
8770    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8771            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8772        synchronized (this) {
8773            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8774            if (!isDebuggable) {
8775                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8776                    throw new SecurityException("Process not debuggable: " + app.packageName);
8777                }
8778            }
8779            mProfileApp = processName;
8780            mProfileFile = profileFile;
8781            if (mProfileFd != null) {
8782                try {
8783                    mProfileFd.close();
8784                } catch (IOException e) {
8785                }
8786                mProfileFd = null;
8787            }
8788            mProfileFd = profileFd;
8789            mProfileType = 0;
8790            mAutoStopProfiler = autoStopProfiler;
8791        }
8792    }
8793
8794    @Override
8795    public void setAlwaysFinish(boolean enabled) {
8796        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8797                "setAlwaysFinish()");
8798
8799        Settings.Global.putInt(
8800                mContext.getContentResolver(),
8801                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8802
8803        synchronized (this) {
8804            mAlwaysFinishActivities = enabled;
8805        }
8806    }
8807
8808    @Override
8809    public void setActivityController(IActivityController controller) {
8810        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8811                "setActivityController()");
8812        synchronized (this) {
8813            mController = controller;
8814            Watchdog.getInstance().setActivityController(controller);
8815        }
8816    }
8817
8818    @Override
8819    public void setUserIsMonkey(boolean userIsMonkey) {
8820        synchronized (this) {
8821            synchronized (mPidsSelfLocked) {
8822                final int callingPid = Binder.getCallingPid();
8823                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8824                if (precessRecord == null) {
8825                    throw new SecurityException("Unknown process: " + callingPid);
8826                }
8827                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8828                    throw new SecurityException("Only an instrumentation process "
8829                            + "with a UiAutomation can call setUserIsMonkey");
8830                }
8831            }
8832            mUserIsMonkey = userIsMonkey;
8833        }
8834    }
8835
8836    @Override
8837    public boolean isUserAMonkey() {
8838        synchronized (this) {
8839            // If there is a controller also implies the user is a monkey.
8840            return (mUserIsMonkey || mController != null);
8841        }
8842    }
8843
8844    public void requestBugReport() {
8845        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8846        SystemProperties.set("ctl.start", "bugreport");
8847    }
8848
8849    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8850        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8851    }
8852
8853    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8854        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8855            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8856        }
8857        return KEY_DISPATCHING_TIMEOUT;
8858    }
8859
8860    @Override
8861    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8862        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8863                != PackageManager.PERMISSION_GRANTED) {
8864            throw new SecurityException("Requires permission "
8865                    + android.Manifest.permission.FILTER_EVENTS);
8866        }
8867        ProcessRecord proc;
8868        long timeout;
8869        synchronized (this) {
8870            synchronized (mPidsSelfLocked) {
8871                proc = mPidsSelfLocked.get(pid);
8872            }
8873            timeout = getInputDispatchingTimeoutLocked(proc);
8874        }
8875
8876        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8877            return -1;
8878        }
8879
8880        return timeout;
8881    }
8882
8883    /**
8884     * Handle input dispatching timeouts.
8885     * Returns whether input dispatching should be aborted or not.
8886     */
8887    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8888            final ActivityRecord activity, final ActivityRecord parent,
8889            final boolean aboveSystem, String reason) {
8890        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8891                != PackageManager.PERMISSION_GRANTED) {
8892            throw new SecurityException("Requires permission "
8893                    + android.Manifest.permission.FILTER_EVENTS);
8894        }
8895
8896        final String annotation;
8897        if (reason == null) {
8898            annotation = "Input dispatching timed out";
8899        } else {
8900            annotation = "Input dispatching timed out (" + reason + ")";
8901        }
8902
8903        if (proc != null) {
8904            synchronized (this) {
8905                if (proc.debugging) {
8906                    return false;
8907                }
8908
8909                if (mDidDexOpt) {
8910                    // Give more time since we were dexopting.
8911                    mDidDexOpt = false;
8912                    return false;
8913                }
8914
8915                if (proc.instrumentationClass != null) {
8916                    Bundle info = new Bundle();
8917                    info.putString("shortMsg", "keyDispatchingTimedOut");
8918                    info.putString("longMsg", annotation);
8919                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8920                    return true;
8921                }
8922            }
8923            mHandler.post(new Runnable() {
8924                @Override
8925                public void run() {
8926                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8927                }
8928            });
8929        }
8930
8931        return true;
8932    }
8933
8934    public Bundle getAssistContextExtras(int requestType) {
8935        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8936                "getAssistContextExtras()");
8937        PendingAssistExtras pae;
8938        Bundle extras = new Bundle();
8939        synchronized (this) {
8940            ActivityRecord activity = getFocusedStack().mResumedActivity;
8941            if (activity == null) {
8942                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8943                return null;
8944            }
8945            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8946            if (activity.app == null || activity.app.thread == null) {
8947                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8948                return extras;
8949            }
8950            if (activity.app.pid == Binder.getCallingPid()) {
8951                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8952                return extras;
8953            }
8954            pae = new PendingAssistExtras(activity);
8955            try {
8956                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8957                        requestType);
8958                mPendingAssistExtras.add(pae);
8959                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8960            } catch (RemoteException e) {
8961                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8962                return extras;
8963            }
8964        }
8965        synchronized (pae) {
8966            while (!pae.haveResult) {
8967                try {
8968                    pae.wait();
8969                } catch (InterruptedException e) {
8970                }
8971            }
8972            if (pae.result != null) {
8973                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8974            }
8975        }
8976        synchronized (this) {
8977            mPendingAssistExtras.remove(pae);
8978            mHandler.removeCallbacks(pae);
8979        }
8980        return extras;
8981    }
8982
8983    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8984        PendingAssistExtras pae = (PendingAssistExtras)token;
8985        synchronized (pae) {
8986            pae.result = extras;
8987            pae.haveResult = true;
8988            pae.notifyAll();
8989        }
8990    }
8991
8992    public void registerProcessObserver(IProcessObserver observer) {
8993        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8994                "registerProcessObserver()");
8995        synchronized (this) {
8996            mProcessObservers.register(observer);
8997        }
8998    }
8999
9000    @Override
9001    public void unregisterProcessObserver(IProcessObserver observer) {
9002        synchronized (this) {
9003            mProcessObservers.unregister(observer);
9004        }
9005    }
9006
9007    @Override
9008    public boolean convertFromTranslucent(IBinder token) {
9009        final long origId = Binder.clearCallingIdentity();
9010        try {
9011            synchronized (this) {
9012                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9013                if (r == null) {
9014                    return false;
9015                }
9016                if (r.changeWindowTranslucency(true)) {
9017                    mWindowManager.setAppFullscreen(token, true);
9018                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9019                    return true;
9020                }
9021                return false;
9022            }
9023        } finally {
9024            Binder.restoreCallingIdentity(origId);
9025        }
9026    }
9027
9028    @Override
9029    public boolean convertToTranslucent(IBinder token) {
9030        final long origId = Binder.clearCallingIdentity();
9031        try {
9032            synchronized (this) {
9033                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9034                if (r == null) {
9035                    return false;
9036                }
9037                if (r.changeWindowTranslucency(false)) {
9038                    r.task.stack.convertToTranslucent(r);
9039                    mWindowManager.setAppFullscreen(token, false);
9040                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9041                    return true;
9042                }
9043                return false;
9044            }
9045        } finally {
9046            Binder.restoreCallingIdentity(origId);
9047        }
9048    }
9049
9050    @Override
9051    public void setImmersive(IBinder token, boolean immersive) {
9052        synchronized(this) {
9053            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9054            if (r == null) {
9055                throw new IllegalArgumentException();
9056            }
9057            r.immersive = immersive;
9058
9059            // update associated state if we're frontmost
9060            if (r == mFocusedActivity) {
9061                if (DEBUG_IMMERSIVE) {
9062                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9063                }
9064                applyUpdateLockStateLocked(r);
9065            }
9066        }
9067    }
9068
9069    @Override
9070    public boolean isImmersive(IBinder token) {
9071        synchronized (this) {
9072            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9073            if (r == null) {
9074                throw new IllegalArgumentException();
9075            }
9076            return r.immersive;
9077        }
9078    }
9079
9080    public boolean isTopActivityImmersive() {
9081        enforceNotIsolatedCaller("startActivity");
9082        synchronized (this) {
9083            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9084            return (r != null) ? r.immersive : false;
9085        }
9086    }
9087
9088    public final void enterSafeMode() {
9089        synchronized(this) {
9090            // It only makes sense to do this before the system is ready
9091            // and started launching other packages.
9092            if (!mSystemReady) {
9093                try {
9094                    AppGlobals.getPackageManager().enterSafeMode();
9095                } catch (RemoteException e) {
9096                }
9097            }
9098
9099            mSafeMode = true;
9100        }
9101    }
9102
9103    public final void showSafeModeOverlay() {
9104        View v = LayoutInflater.from(mContext).inflate(
9105                com.android.internal.R.layout.safe_mode, null);
9106        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9107        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9108        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9109        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9110        lp.gravity = Gravity.BOTTOM | Gravity.START;
9111        lp.format = v.getBackground().getOpacity();
9112        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9113                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9114        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9115        ((WindowManager)mContext.getSystemService(
9116                Context.WINDOW_SERVICE)).addView(v, lp);
9117    }
9118
9119    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9120        if (!(sender instanceof PendingIntentRecord)) {
9121            return;
9122        }
9123        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9124        synchronized (stats) {
9125            if (mBatteryStatsService.isOnBattery()) {
9126                mBatteryStatsService.enforceCallingPermission();
9127                PendingIntentRecord rec = (PendingIntentRecord)sender;
9128                int MY_UID = Binder.getCallingUid();
9129                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9130                BatteryStatsImpl.Uid.Pkg pkg =
9131                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9132                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9133                pkg.incWakeupsLocked();
9134            }
9135        }
9136    }
9137
9138    public boolean killPids(int[] pids, String pReason, boolean secure) {
9139        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9140            throw new SecurityException("killPids only available to the system");
9141        }
9142        String reason = (pReason == null) ? "Unknown" : pReason;
9143        // XXX Note: don't acquire main activity lock here, because the window
9144        // manager calls in with its locks held.
9145
9146        boolean killed = false;
9147        synchronized (mPidsSelfLocked) {
9148            int[] types = new int[pids.length];
9149            int worstType = 0;
9150            for (int i=0; i<pids.length; i++) {
9151                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9152                if (proc != null) {
9153                    int type = proc.setAdj;
9154                    types[i] = type;
9155                    if (type > worstType) {
9156                        worstType = type;
9157                    }
9158                }
9159            }
9160
9161            // If the worst oom_adj is somewhere in the cached proc LRU range,
9162            // then constrain it so we will kill all cached procs.
9163            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9164                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9165                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9166            }
9167
9168            // If this is not a secure call, don't let it kill processes that
9169            // are important.
9170            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9171                worstType = ProcessList.SERVICE_ADJ;
9172            }
9173
9174            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9175            for (int i=0; i<pids.length; i++) {
9176                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9177                if (proc == null) {
9178                    continue;
9179                }
9180                int adj = proc.setAdj;
9181                if (adj >= worstType && !proc.killedByAm) {
9182                    killUnneededProcessLocked(proc, reason);
9183                    killed = true;
9184                }
9185            }
9186        }
9187        return killed;
9188    }
9189
9190    @Override
9191    public void killUid(int uid, String reason) {
9192        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9193            throw new SecurityException("killUid only available to the system");
9194        }
9195        synchronized (this) {
9196            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9197                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9198                    reason != null ? reason : "kill uid");
9199        }
9200    }
9201
9202    @Override
9203    public boolean killProcessesBelowForeground(String reason) {
9204        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9205            throw new SecurityException("killProcessesBelowForeground() only available to system");
9206        }
9207
9208        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9209    }
9210
9211    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9212        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9213            throw new SecurityException("killProcessesBelowAdj() only available to system");
9214        }
9215
9216        boolean killed = false;
9217        synchronized (mPidsSelfLocked) {
9218            final int size = mPidsSelfLocked.size();
9219            for (int i = 0; i < size; i++) {
9220                final int pid = mPidsSelfLocked.keyAt(i);
9221                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9222                if (proc == null) continue;
9223
9224                final int adj = proc.setAdj;
9225                if (adj > belowAdj && !proc.killedByAm) {
9226                    killUnneededProcessLocked(proc, reason);
9227                    killed = true;
9228                }
9229            }
9230        }
9231        return killed;
9232    }
9233
9234    @Override
9235    public void hang(final IBinder who, boolean allowRestart) {
9236        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9237                != PackageManager.PERMISSION_GRANTED) {
9238            throw new SecurityException("Requires permission "
9239                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9240        }
9241
9242        final IBinder.DeathRecipient death = new DeathRecipient() {
9243            @Override
9244            public void binderDied() {
9245                synchronized (this) {
9246                    notifyAll();
9247                }
9248            }
9249        };
9250
9251        try {
9252            who.linkToDeath(death, 0);
9253        } catch (RemoteException e) {
9254            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9255            return;
9256        }
9257
9258        synchronized (this) {
9259            Watchdog.getInstance().setAllowRestart(allowRestart);
9260            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9261            synchronized (death) {
9262                while (who.isBinderAlive()) {
9263                    try {
9264                        death.wait();
9265                    } catch (InterruptedException e) {
9266                    }
9267                }
9268            }
9269            Watchdog.getInstance().setAllowRestart(true);
9270        }
9271    }
9272
9273    @Override
9274    public void restart() {
9275        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9276                != PackageManager.PERMISSION_GRANTED) {
9277            throw new SecurityException("Requires permission "
9278                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9279        }
9280
9281        Log.i(TAG, "Sending shutdown broadcast...");
9282
9283        BroadcastReceiver br = new BroadcastReceiver() {
9284            @Override public void onReceive(Context context, Intent intent) {
9285                // Now the broadcast is done, finish up the low-level shutdown.
9286                Log.i(TAG, "Shutting down activity manager...");
9287                shutdown(10000);
9288                Log.i(TAG, "Shutdown complete, restarting!");
9289                Process.killProcess(Process.myPid());
9290                System.exit(10);
9291            }
9292        };
9293
9294        // First send the high-level shut down broadcast.
9295        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9296        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9297        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9298        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9299        mContext.sendOrderedBroadcastAsUser(intent,
9300                UserHandle.ALL, null, br, mHandler, 0, null, null);
9301        */
9302        br.onReceive(mContext, intent);
9303    }
9304
9305    private long getLowRamTimeSinceIdle(long now) {
9306        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9307    }
9308
9309    @Override
9310    public void performIdleMaintenance() {
9311        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9312                != PackageManager.PERMISSION_GRANTED) {
9313            throw new SecurityException("Requires permission "
9314                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9315        }
9316
9317        synchronized (this) {
9318            final long now = SystemClock.uptimeMillis();
9319            final long timeSinceLastIdle = now - mLastIdleTime;
9320            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9321            mLastIdleTime = now;
9322            mLowRamTimeSinceLastIdle = 0;
9323            if (mLowRamStartTime != 0) {
9324                mLowRamStartTime = now;
9325            }
9326
9327            StringBuilder sb = new StringBuilder(128);
9328            sb.append("Idle maintenance over ");
9329            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9330            sb.append(" low RAM for ");
9331            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9332            Slog.i(TAG, sb.toString());
9333
9334            // If at least 1/3 of our time since the last idle period has been spent
9335            // with RAM low, then we want to kill processes.
9336            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9337
9338            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9339                ProcessRecord proc = mLruProcesses.get(i);
9340                if (proc.notCachedSinceIdle) {
9341                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9342                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9343                        if (doKilling && proc.initialIdlePss != 0
9344                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9345                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9346                                    + " from " + proc.initialIdlePss + ")");
9347                        }
9348                    }
9349                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9350                    proc.notCachedSinceIdle = true;
9351                    proc.initialIdlePss = 0;
9352                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9353                            isSleeping(), now);
9354                }
9355            }
9356
9357            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9358            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9359        }
9360    }
9361
9362    private void retrieveSettings() {
9363        final ContentResolver resolver = mContext.getContentResolver();
9364        String debugApp = Settings.Global.getString(
9365            resolver, Settings.Global.DEBUG_APP);
9366        boolean waitForDebugger = Settings.Global.getInt(
9367            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9368        boolean alwaysFinishActivities = Settings.Global.getInt(
9369            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9370        boolean forceRtl = Settings.Global.getInt(
9371                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9372        // Transfer any global setting for forcing RTL layout, into a System Property
9373        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9374
9375        Configuration configuration = new Configuration();
9376        Settings.System.getConfiguration(resolver, configuration);
9377        if (forceRtl) {
9378            // This will take care of setting the correct layout direction flags
9379            configuration.setLayoutDirection(configuration.locale);
9380        }
9381
9382        synchronized (this) {
9383            mDebugApp = mOrigDebugApp = debugApp;
9384            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9385            mAlwaysFinishActivities = alwaysFinishActivities;
9386            // This happens before any activities are started, so we can
9387            // change mConfiguration in-place.
9388            updateConfigurationLocked(configuration, null, false, true);
9389            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9390        }
9391    }
9392
9393    public boolean testIsSystemReady() {
9394        // no need to synchronize(this) just to read & return the value
9395        return mSystemReady;
9396    }
9397
9398    private static File getCalledPreBootReceiversFile() {
9399        File dataDir = Environment.getDataDirectory();
9400        File systemDir = new File(dataDir, "system");
9401        File fname = new File(systemDir, "called_pre_boots.dat");
9402        return fname;
9403    }
9404
9405    static final int LAST_DONE_VERSION = 10000;
9406
9407    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9408        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9409        File file = getCalledPreBootReceiversFile();
9410        FileInputStream fis = null;
9411        try {
9412            fis = new FileInputStream(file);
9413            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9414            int fvers = dis.readInt();
9415            if (fvers == LAST_DONE_VERSION) {
9416                String vers = dis.readUTF();
9417                String codename = dis.readUTF();
9418                String build = dis.readUTF();
9419                if (android.os.Build.VERSION.RELEASE.equals(vers)
9420                        && android.os.Build.VERSION.CODENAME.equals(codename)
9421                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9422                    int num = dis.readInt();
9423                    while (num > 0) {
9424                        num--;
9425                        String pkg = dis.readUTF();
9426                        String cls = dis.readUTF();
9427                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9428                    }
9429                }
9430            }
9431        } catch (FileNotFoundException e) {
9432        } catch (IOException e) {
9433            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9434        } finally {
9435            if (fis != null) {
9436                try {
9437                    fis.close();
9438                } catch (IOException e) {
9439                }
9440            }
9441        }
9442        return lastDoneReceivers;
9443    }
9444
9445    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9446        File file = getCalledPreBootReceiversFile();
9447        FileOutputStream fos = null;
9448        DataOutputStream dos = null;
9449        try {
9450            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9451            fos = new FileOutputStream(file);
9452            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9453            dos.writeInt(LAST_DONE_VERSION);
9454            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9455            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9456            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9457            dos.writeInt(list.size());
9458            for (int i=0; i<list.size(); i++) {
9459                dos.writeUTF(list.get(i).getPackageName());
9460                dos.writeUTF(list.get(i).getClassName());
9461            }
9462        } catch (IOException e) {
9463            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9464            file.delete();
9465        } finally {
9466            FileUtils.sync(fos);
9467            if (dos != null) {
9468                try {
9469                    dos.close();
9470                } catch (IOException e) {
9471                    // TODO Auto-generated catch block
9472                    e.printStackTrace();
9473                }
9474            }
9475        }
9476    }
9477
9478    public void systemReady(final Runnable goingCallback) {
9479        synchronized(this) {
9480            if (mSystemReady) {
9481                if (goingCallback != null) goingCallback.run();
9482                return;
9483            }
9484
9485            // Check to see if there are any update receivers to run.
9486            if (!mDidUpdate) {
9487                if (mWaitingUpdate) {
9488                    return;
9489                }
9490                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9491                List<ResolveInfo> ris = null;
9492                try {
9493                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9494                            intent, null, 0, 0);
9495                } catch (RemoteException e) {
9496                }
9497                if (ris != null) {
9498                    for (int i=ris.size()-1; i>=0; i--) {
9499                        if ((ris.get(i).activityInfo.applicationInfo.flags
9500                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9501                            ris.remove(i);
9502                        }
9503                    }
9504                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9505
9506                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9507
9508                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9509                    for (int i=0; i<ris.size(); i++) {
9510                        ActivityInfo ai = ris.get(i).activityInfo;
9511                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9512                        if (lastDoneReceivers.contains(comp)) {
9513                            // We already did the pre boot receiver for this app with the current
9514                            // platform version, so don't do it again...
9515                            ris.remove(i);
9516                            i--;
9517                            // ...however, do keep it as one that has been done, so we don't
9518                            // forget about it when rewriting the file of last done receivers.
9519                            doneReceivers.add(comp);
9520                        }
9521                    }
9522
9523                    final int[] users = getUsersLocked();
9524                    for (int i=0; i<ris.size(); i++) {
9525                        ActivityInfo ai = ris.get(i).activityInfo;
9526                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9527                        doneReceivers.add(comp);
9528                        intent.setComponent(comp);
9529                        for (int j=0; j<users.length; j++) {
9530                            IIntentReceiver finisher = null;
9531                            if (i == ris.size()-1 && j == users.length-1) {
9532                                finisher = new IIntentReceiver.Stub() {
9533                                    public void performReceive(Intent intent, int resultCode,
9534                                            String data, Bundle extras, boolean ordered,
9535                                            boolean sticky, int sendingUser) {
9536                                        // The raw IIntentReceiver interface is called
9537                                        // with the AM lock held, so redispatch to
9538                                        // execute our code without the lock.
9539                                        mHandler.post(new Runnable() {
9540                                            public void run() {
9541                                                synchronized (ActivityManagerService.this) {
9542                                                    mDidUpdate = true;
9543                                                }
9544                                                writeLastDonePreBootReceivers(doneReceivers);
9545                                                showBootMessage(mContext.getText(
9546                                                        R.string.android_upgrading_complete),
9547                                                        false);
9548                                                systemReady(goingCallback);
9549                                            }
9550                                        });
9551                                    }
9552                                };
9553                            }
9554                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9555                                    + " for user " + users[j]);
9556                            broadcastIntentLocked(null, null, intent, null, finisher,
9557                                    0, null, null, null, AppOpsManager.OP_NONE,
9558                                    true, false, MY_PID, Process.SYSTEM_UID,
9559                                    users[j]);
9560                            if (finisher != null) {
9561                                mWaitingUpdate = true;
9562                            }
9563                        }
9564                    }
9565                }
9566                if (mWaitingUpdate) {
9567                    return;
9568                }
9569                mDidUpdate = true;
9570            }
9571
9572            mAppOpsService.systemReady();
9573            mUsageStatsService.systemReady();
9574            mSystemReady = true;
9575        }
9576
9577        ArrayList<ProcessRecord> procsToKill = null;
9578        synchronized(mPidsSelfLocked) {
9579            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9580                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9581                if (!isAllowedWhileBooting(proc.info)){
9582                    if (procsToKill == null) {
9583                        procsToKill = new ArrayList<ProcessRecord>();
9584                    }
9585                    procsToKill.add(proc);
9586                }
9587            }
9588        }
9589
9590        synchronized(this) {
9591            if (procsToKill != null) {
9592                for (int i=procsToKill.size()-1; i>=0; i--) {
9593                    ProcessRecord proc = procsToKill.get(i);
9594                    Slog.i(TAG, "Removing system update proc: " + proc);
9595                    removeProcessLocked(proc, true, false, "system update done");
9596                }
9597            }
9598
9599            // Now that we have cleaned up any update processes, we
9600            // are ready to start launching real processes and know that
9601            // we won't trample on them any more.
9602            mProcessesReady = true;
9603        }
9604
9605        Slog.i(TAG, "System now ready");
9606        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9607            SystemClock.uptimeMillis());
9608
9609        synchronized(this) {
9610            // Make sure we have no pre-ready processes sitting around.
9611
9612            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9613                ResolveInfo ri = mContext.getPackageManager()
9614                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9615                                STOCK_PM_FLAGS);
9616                CharSequence errorMsg = null;
9617                if (ri != null) {
9618                    ActivityInfo ai = ri.activityInfo;
9619                    ApplicationInfo app = ai.applicationInfo;
9620                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9621                        mTopAction = Intent.ACTION_FACTORY_TEST;
9622                        mTopData = null;
9623                        mTopComponent = new ComponentName(app.packageName,
9624                                ai.name);
9625                    } else {
9626                        errorMsg = mContext.getResources().getText(
9627                                com.android.internal.R.string.factorytest_not_system);
9628                    }
9629                } else {
9630                    errorMsg = mContext.getResources().getText(
9631                            com.android.internal.R.string.factorytest_no_action);
9632                }
9633                if (errorMsg != null) {
9634                    mTopAction = null;
9635                    mTopData = null;
9636                    mTopComponent = null;
9637                    Message msg = Message.obtain();
9638                    msg.what = SHOW_FACTORY_ERROR_MSG;
9639                    msg.getData().putCharSequence("msg", errorMsg);
9640                    mHandler.sendMessage(msg);
9641                }
9642            }
9643        }
9644
9645        retrieveSettings();
9646
9647        synchronized (this) {
9648            readGrantedUriPermissionsLocked();
9649        }
9650
9651        if (goingCallback != null) goingCallback.run();
9652
9653        mSystemServiceManager.startUser(mCurrentUserId);
9654
9655        synchronized (this) {
9656            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9657                try {
9658                    List apps = AppGlobals.getPackageManager().
9659                        getPersistentApplications(STOCK_PM_FLAGS);
9660                    if (apps != null) {
9661                        int N = apps.size();
9662                        int i;
9663                        for (i=0; i<N; i++) {
9664                            ApplicationInfo info
9665                                = (ApplicationInfo)apps.get(i);
9666                            if (info != null &&
9667                                    !info.packageName.equals("android")) {
9668                                addAppLocked(info, false);
9669                            }
9670                        }
9671                    }
9672                } catch (RemoteException ex) {
9673                    // pm is in same process, this will never happen.
9674                }
9675            }
9676
9677            // Start up initial activity.
9678            mBooting = true;
9679
9680            try {
9681                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9682                    Message msg = Message.obtain();
9683                    msg.what = SHOW_UID_ERROR_MSG;
9684                    mHandler.sendMessage(msg);
9685                }
9686            } catch (RemoteException e) {
9687            }
9688
9689            long ident = Binder.clearCallingIdentity();
9690            try {
9691                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9692                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9693                        | Intent.FLAG_RECEIVER_FOREGROUND);
9694                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9695                broadcastIntentLocked(null, null, intent,
9696                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9697                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9698                intent = new Intent(Intent.ACTION_USER_STARTING);
9699                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9700                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9701                broadcastIntentLocked(null, null, intent,
9702                        null, new IIntentReceiver.Stub() {
9703                            @Override
9704                            public void performReceive(Intent intent, int resultCode, String data,
9705                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9706                                    throws RemoteException {
9707                            }
9708                        }, 0, null, null,
9709                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9710                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9711            } catch (Throwable t) {
9712                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9713            } finally {
9714                Binder.restoreCallingIdentity(ident);
9715            }
9716            mStackSupervisor.resumeTopActivitiesLocked();
9717            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9718        }
9719    }
9720
9721    private boolean makeAppCrashingLocked(ProcessRecord app,
9722            String shortMsg, String longMsg, String stackTrace) {
9723        app.crashing = true;
9724        app.crashingReport = generateProcessError(app,
9725                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9726        startAppProblemLocked(app);
9727        app.stopFreezingAllLocked();
9728        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9729    }
9730
9731    private void makeAppNotRespondingLocked(ProcessRecord app,
9732            String activity, String shortMsg, String longMsg) {
9733        app.notResponding = true;
9734        app.notRespondingReport = generateProcessError(app,
9735                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9736                activity, shortMsg, longMsg, null);
9737        startAppProblemLocked(app);
9738        app.stopFreezingAllLocked();
9739    }
9740
9741    /**
9742     * Generate a process error record, suitable for attachment to a ProcessRecord.
9743     *
9744     * @param app The ProcessRecord in which the error occurred.
9745     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9746     *                      ActivityManager.AppErrorStateInfo
9747     * @param activity The activity associated with the crash, if known.
9748     * @param shortMsg Short message describing the crash.
9749     * @param longMsg Long message describing the crash.
9750     * @param stackTrace Full crash stack trace, may be null.
9751     *
9752     * @return Returns a fully-formed AppErrorStateInfo record.
9753     */
9754    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9755            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9756        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9757
9758        report.condition = condition;
9759        report.processName = app.processName;
9760        report.pid = app.pid;
9761        report.uid = app.info.uid;
9762        report.tag = activity;
9763        report.shortMsg = shortMsg;
9764        report.longMsg = longMsg;
9765        report.stackTrace = stackTrace;
9766
9767        return report;
9768    }
9769
9770    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9771        synchronized (this) {
9772            app.crashing = false;
9773            app.crashingReport = null;
9774            app.notResponding = false;
9775            app.notRespondingReport = null;
9776            if (app.anrDialog == fromDialog) {
9777                app.anrDialog = null;
9778            }
9779            if (app.waitDialog == fromDialog) {
9780                app.waitDialog = null;
9781            }
9782            if (app.pid > 0 && app.pid != MY_PID) {
9783                handleAppCrashLocked(app, null, null, null);
9784                killUnneededProcessLocked(app, "user request after error");
9785            }
9786        }
9787    }
9788
9789    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9790            String stackTrace) {
9791        long now = SystemClock.uptimeMillis();
9792
9793        Long crashTime;
9794        if (!app.isolated) {
9795            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9796        } else {
9797            crashTime = null;
9798        }
9799        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9800            // This process loses!
9801            Slog.w(TAG, "Process " + app.info.processName
9802                    + " has crashed too many times: killing!");
9803            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9804                    app.userId, app.info.processName, app.uid);
9805            mStackSupervisor.handleAppCrashLocked(app);
9806            if (!app.persistent) {
9807                // We don't want to start this process again until the user
9808                // explicitly does so...  but for persistent process, we really
9809                // need to keep it running.  If a persistent process is actually
9810                // repeatedly crashing, then badness for everyone.
9811                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9812                        app.info.processName);
9813                if (!app.isolated) {
9814                    // XXX We don't have a way to mark isolated processes
9815                    // as bad, since they don't have a peristent identity.
9816                    mBadProcesses.put(app.info.processName, app.uid,
9817                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9818                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9819                }
9820                app.bad = true;
9821                app.removed = true;
9822                // Don't let services in this process be restarted and potentially
9823                // annoy the user repeatedly.  Unless it is persistent, since those
9824                // processes run critical code.
9825                removeProcessLocked(app, false, false, "crash");
9826                mStackSupervisor.resumeTopActivitiesLocked();
9827                return false;
9828            }
9829            mStackSupervisor.resumeTopActivitiesLocked();
9830        } else {
9831            mStackSupervisor.finishTopRunningActivityLocked(app);
9832        }
9833
9834        // Bump up the crash count of any services currently running in the proc.
9835        for (int i=app.services.size()-1; i>=0; i--) {
9836            // Any services running in the application need to be placed
9837            // back in the pending list.
9838            ServiceRecord sr = app.services.valueAt(i);
9839            sr.crashCount++;
9840        }
9841
9842        // If the crashing process is what we consider to be the "home process" and it has been
9843        // replaced by a third-party app, clear the package preferred activities from packages
9844        // with a home activity running in the process to prevent a repeatedly crashing app
9845        // from blocking the user to manually clear the list.
9846        final ArrayList<ActivityRecord> activities = app.activities;
9847        if (app == mHomeProcess && activities.size() > 0
9848                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9849            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9850                final ActivityRecord r = activities.get(activityNdx);
9851                if (r.isHomeActivity()) {
9852                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9853                    try {
9854                        ActivityThread.getPackageManager()
9855                                .clearPackagePreferredActivities(r.packageName);
9856                    } catch (RemoteException c) {
9857                        // pm is in same process, this will never happen.
9858                    }
9859                }
9860            }
9861        }
9862
9863        if (!app.isolated) {
9864            // XXX Can't keep track of crash times for isolated processes,
9865            // because they don't have a perisistent identity.
9866            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9867        }
9868
9869        return true;
9870    }
9871
9872    void startAppProblemLocked(ProcessRecord app) {
9873        if (app.userId == mCurrentUserId) {
9874            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9875                    mContext, app.info.packageName, app.info.flags);
9876        } else {
9877            // If this app is not running under the current user, then we
9878            // can't give it a report button because that would require
9879            // launching the report UI under a different user.
9880            app.errorReportReceiver = null;
9881        }
9882        skipCurrentReceiverLocked(app);
9883    }
9884
9885    void skipCurrentReceiverLocked(ProcessRecord app) {
9886        for (BroadcastQueue queue : mBroadcastQueues) {
9887            queue.skipCurrentReceiverLocked(app);
9888        }
9889    }
9890
9891    /**
9892     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9893     * The application process will exit immediately after this call returns.
9894     * @param app object of the crashing app, null for the system server
9895     * @param crashInfo describing the exception
9896     */
9897    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9898        ProcessRecord r = findAppProcess(app, "Crash");
9899        final String processName = app == null ? "system_server"
9900                : (r == null ? "unknown" : r.processName);
9901
9902        handleApplicationCrashInner("crash", r, processName, crashInfo);
9903    }
9904
9905    /* Native crash reporting uses this inner version because it needs to be somewhat
9906     * decoupled from the AM-managed cleanup lifecycle
9907     */
9908    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9909            ApplicationErrorReport.CrashInfo crashInfo) {
9910        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9911                UserHandle.getUserId(Binder.getCallingUid()), processName,
9912                r == null ? -1 : r.info.flags,
9913                crashInfo.exceptionClassName,
9914                crashInfo.exceptionMessage,
9915                crashInfo.throwFileName,
9916                crashInfo.throwLineNumber);
9917
9918        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9919
9920        crashApplication(r, crashInfo);
9921    }
9922
9923    public void handleApplicationStrictModeViolation(
9924            IBinder app,
9925            int violationMask,
9926            StrictMode.ViolationInfo info) {
9927        ProcessRecord r = findAppProcess(app, "StrictMode");
9928        if (r == null) {
9929            return;
9930        }
9931
9932        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9933            Integer stackFingerprint = info.hashCode();
9934            boolean logIt = true;
9935            synchronized (mAlreadyLoggedViolatedStacks) {
9936                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9937                    logIt = false;
9938                    // TODO: sub-sample into EventLog for these, with
9939                    // the info.durationMillis?  Then we'd get
9940                    // the relative pain numbers, without logging all
9941                    // the stack traces repeatedly.  We'd want to do
9942                    // likewise in the client code, which also does
9943                    // dup suppression, before the Binder call.
9944                } else {
9945                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9946                        mAlreadyLoggedViolatedStacks.clear();
9947                    }
9948                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9949                }
9950            }
9951            if (logIt) {
9952                logStrictModeViolationToDropBox(r, info);
9953            }
9954        }
9955
9956        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9957            AppErrorResult result = new AppErrorResult();
9958            synchronized (this) {
9959                final long origId = Binder.clearCallingIdentity();
9960
9961                Message msg = Message.obtain();
9962                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9963                HashMap<String, Object> data = new HashMap<String, Object>();
9964                data.put("result", result);
9965                data.put("app", r);
9966                data.put("violationMask", violationMask);
9967                data.put("info", info);
9968                msg.obj = data;
9969                mHandler.sendMessage(msg);
9970
9971                Binder.restoreCallingIdentity(origId);
9972            }
9973            int res = result.get();
9974            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9975        }
9976    }
9977
9978    // Depending on the policy in effect, there could be a bunch of
9979    // these in quick succession so we try to batch these together to
9980    // minimize disk writes, number of dropbox entries, and maximize
9981    // compression, by having more fewer, larger records.
9982    private void logStrictModeViolationToDropBox(
9983            ProcessRecord process,
9984            StrictMode.ViolationInfo info) {
9985        if (info == null) {
9986            return;
9987        }
9988        final boolean isSystemApp = process == null ||
9989                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9990                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9991        final String processName = process == null ? "unknown" : process.processName;
9992        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9993        final DropBoxManager dbox = (DropBoxManager)
9994                mContext.getSystemService(Context.DROPBOX_SERVICE);
9995
9996        // Exit early if the dropbox isn't configured to accept this report type.
9997        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9998
9999        boolean bufferWasEmpty;
10000        boolean needsFlush;
10001        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10002        synchronized (sb) {
10003            bufferWasEmpty = sb.length() == 0;
10004            appendDropBoxProcessHeaders(process, processName, sb);
10005            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10006            sb.append("System-App: ").append(isSystemApp).append("\n");
10007            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10008            if (info.violationNumThisLoop != 0) {
10009                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10010            }
10011            if (info.numAnimationsRunning != 0) {
10012                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10013            }
10014            if (info.broadcastIntentAction != null) {
10015                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10016            }
10017            if (info.durationMillis != -1) {
10018                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10019            }
10020            if (info.numInstances != -1) {
10021                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10022            }
10023            if (info.tags != null) {
10024                for (String tag : info.tags) {
10025                    sb.append("Span-Tag: ").append(tag).append("\n");
10026                }
10027            }
10028            sb.append("\n");
10029            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10030                sb.append(info.crashInfo.stackTrace);
10031            }
10032            sb.append("\n");
10033
10034            // Only buffer up to ~64k.  Various logging bits truncate
10035            // things at 128k.
10036            needsFlush = (sb.length() > 64 * 1024);
10037        }
10038
10039        // Flush immediately if the buffer's grown too large, or this
10040        // is a non-system app.  Non-system apps are isolated with a
10041        // different tag & policy and not batched.
10042        //
10043        // Batching is useful during internal testing with
10044        // StrictMode settings turned up high.  Without batching,
10045        // thousands of separate files could be created on boot.
10046        if (!isSystemApp || needsFlush) {
10047            new Thread("Error dump: " + dropboxTag) {
10048                @Override
10049                public void run() {
10050                    String report;
10051                    synchronized (sb) {
10052                        report = sb.toString();
10053                        sb.delete(0, sb.length());
10054                        sb.trimToSize();
10055                    }
10056                    if (report.length() != 0) {
10057                        dbox.addText(dropboxTag, report);
10058                    }
10059                }
10060            }.start();
10061            return;
10062        }
10063
10064        // System app batching:
10065        if (!bufferWasEmpty) {
10066            // An existing dropbox-writing thread is outstanding, so
10067            // we don't need to start it up.  The existing thread will
10068            // catch the buffer appends we just did.
10069            return;
10070        }
10071
10072        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10073        // (After this point, we shouldn't access AMS internal data structures.)
10074        new Thread("Error dump: " + dropboxTag) {
10075            @Override
10076            public void run() {
10077                // 5 second sleep to let stacks arrive and be batched together
10078                try {
10079                    Thread.sleep(5000);  // 5 seconds
10080                } catch (InterruptedException e) {}
10081
10082                String errorReport;
10083                synchronized (mStrictModeBuffer) {
10084                    errorReport = mStrictModeBuffer.toString();
10085                    if (errorReport.length() == 0) {
10086                        return;
10087                    }
10088                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10089                    mStrictModeBuffer.trimToSize();
10090                }
10091                dbox.addText(dropboxTag, errorReport);
10092            }
10093        }.start();
10094    }
10095
10096    /**
10097     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10098     * @param app object of the crashing app, null for the system server
10099     * @param tag reported by the caller
10100     * @param crashInfo describing the context of the error
10101     * @return true if the process should exit immediately (WTF is fatal)
10102     */
10103    public boolean handleApplicationWtf(IBinder app, String tag,
10104            ApplicationErrorReport.CrashInfo crashInfo) {
10105        ProcessRecord r = findAppProcess(app, "WTF");
10106        final String processName = app == null ? "system_server"
10107                : (r == null ? "unknown" : r.processName);
10108
10109        EventLog.writeEvent(EventLogTags.AM_WTF,
10110                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10111                processName,
10112                r == null ? -1 : r.info.flags,
10113                tag, crashInfo.exceptionMessage);
10114
10115        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10116
10117        if (r != null && r.pid != Process.myPid() &&
10118                Settings.Global.getInt(mContext.getContentResolver(),
10119                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10120            crashApplication(r, crashInfo);
10121            return true;
10122        } else {
10123            return false;
10124        }
10125    }
10126
10127    /**
10128     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10129     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10130     */
10131    private ProcessRecord findAppProcess(IBinder app, String reason) {
10132        if (app == null) {
10133            return null;
10134        }
10135
10136        synchronized (this) {
10137            final int NP = mProcessNames.getMap().size();
10138            for (int ip=0; ip<NP; ip++) {
10139                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10140                final int NA = apps.size();
10141                for (int ia=0; ia<NA; ia++) {
10142                    ProcessRecord p = apps.valueAt(ia);
10143                    if (p.thread != null && p.thread.asBinder() == app) {
10144                        return p;
10145                    }
10146                }
10147            }
10148
10149            Slog.w(TAG, "Can't find mystery application for " + reason
10150                    + " from pid=" + Binder.getCallingPid()
10151                    + " uid=" + Binder.getCallingUid() + ": " + app);
10152            return null;
10153        }
10154    }
10155
10156    /**
10157     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10158     * to append various headers to the dropbox log text.
10159     */
10160    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10161            StringBuilder sb) {
10162        // Watchdog thread ends up invoking this function (with
10163        // a null ProcessRecord) to add the stack file to dropbox.
10164        // Do not acquire a lock on this (am) in such cases, as it
10165        // could cause a potential deadlock, if and when watchdog
10166        // is invoked due to unavailability of lock on am and it
10167        // would prevent watchdog from killing system_server.
10168        if (process == null) {
10169            sb.append("Process: ").append(processName).append("\n");
10170            return;
10171        }
10172        // Note: ProcessRecord 'process' is guarded by the service
10173        // instance.  (notably process.pkgList, which could otherwise change
10174        // concurrently during execution of this method)
10175        synchronized (this) {
10176            sb.append("Process: ").append(processName).append("\n");
10177            int flags = process.info.flags;
10178            IPackageManager pm = AppGlobals.getPackageManager();
10179            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10180            for (int ip=0; ip<process.pkgList.size(); ip++) {
10181                String pkg = process.pkgList.keyAt(ip);
10182                sb.append("Package: ").append(pkg);
10183                try {
10184                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10185                    if (pi != null) {
10186                        sb.append(" v").append(pi.versionCode);
10187                        if (pi.versionName != null) {
10188                            sb.append(" (").append(pi.versionName).append(")");
10189                        }
10190                    }
10191                } catch (RemoteException e) {
10192                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10193                }
10194                sb.append("\n");
10195            }
10196        }
10197    }
10198
10199    private static String processClass(ProcessRecord process) {
10200        if (process == null || process.pid == MY_PID) {
10201            return "system_server";
10202        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10203            return "system_app";
10204        } else {
10205            return "data_app";
10206        }
10207    }
10208
10209    /**
10210     * Write a description of an error (crash, WTF, ANR) to the drop box.
10211     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10212     * @param process which caused the error, null means the system server
10213     * @param activity which triggered the error, null if unknown
10214     * @param parent activity related to the error, null if unknown
10215     * @param subject line related to the error, null if absent
10216     * @param report in long form describing the error, null if absent
10217     * @param logFile to include in the report, null if none
10218     * @param crashInfo giving an application stack trace, null if absent
10219     */
10220    public void addErrorToDropBox(String eventType,
10221            ProcessRecord process, String processName, ActivityRecord activity,
10222            ActivityRecord parent, String subject,
10223            final String report, final File logFile,
10224            final ApplicationErrorReport.CrashInfo crashInfo) {
10225        // NOTE -- this must never acquire the ActivityManagerService lock,
10226        // otherwise the watchdog may be prevented from resetting the system.
10227
10228        final String dropboxTag = processClass(process) + "_" + eventType;
10229        final DropBoxManager dbox = (DropBoxManager)
10230                mContext.getSystemService(Context.DROPBOX_SERVICE);
10231
10232        // Exit early if the dropbox isn't configured to accept this report type.
10233        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10234
10235        final StringBuilder sb = new StringBuilder(1024);
10236        appendDropBoxProcessHeaders(process, processName, sb);
10237        if (activity != null) {
10238            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10239        }
10240        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10241            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10242        }
10243        if (parent != null && parent != activity) {
10244            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10245        }
10246        if (subject != null) {
10247            sb.append("Subject: ").append(subject).append("\n");
10248        }
10249        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10250        if (Debug.isDebuggerConnected()) {
10251            sb.append("Debugger: Connected\n");
10252        }
10253        sb.append("\n");
10254
10255        // Do the rest in a worker thread to avoid blocking the caller on I/O
10256        // (After this point, we shouldn't access AMS internal data structures.)
10257        Thread worker = new Thread("Error dump: " + dropboxTag) {
10258            @Override
10259            public void run() {
10260                if (report != null) {
10261                    sb.append(report);
10262                }
10263                if (logFile != null) {
10264                    try {
10265                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10266                                    "\n\n[[TRUNCATED]]"));
10267                    } catch (IOException e) {
10268                        Slog.e(TAG, "Error reading " + logFile, e);
10269                    }
10270                }
10271                if (crashInfo != null && crashInfo.stackTrace != null) {
10272                    sb.append(crashInfo.stackTrace);
10273                }
10274
10275                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10276                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10277                if (lines > 0) {
10278                    sb.append("\n");
10279
10280                    // Merge several logcat streams, and take the last N lines
10281                    InputStreamReader input = null;
10282                    try {
10283                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10284                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10285                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10286
10287                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10288                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10289                        input = new InputStreamReader(logcat.getInputStream());
10290
10291                        int num;
10292                        char[] buf = new char[8192];
10293                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10294                    } catch (IOException e) {
10295                        Slog.e(TAG, "Error running logcat", e);
10296                    } finally {
10297                        if (input != null) try { input.close(); } catch (IOException e) {}
10298                    }
10299                }
10300
10301                dbox.addText(dropboxTag, sb.toString());
10302            }
10303        };
10304
10305        if (process == null) {
10306            // If process is null, we are being called from some internal code
10307            // and may be about to die -- run this synchronously.
10308            worker.run();
10309        } else {
10310            worker.start();
10311        }
10312    }
10313
10314    /**
10315     * Bring up the "unexpected error" dialog box for a crashing app.
10316     * Deal with edge cases (intercepts from instrumented applications,
10317     * ActivityController, error intent receivers, that sort of thing).
10318     * @param r the application crashing
10319     * @param crashInfo describing the failure
10320     */
10321    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10322        long timeMillis = System.currentTimeMillis();
10323        String shortMsg = crashInfo.exceptionClassName;
10324        String longMsg = crashInfo.exceptionMessage;
10325        String stackTrace = crashInfo.stackTrace;
10326        if (shortMsg != null && longMsg != null) {
10327            longMsg = shortMsg + ": " + longMsg;
10328        } else if (shortMsg != null) {
10329            longMsg = shortMsg;
10330        }
10331
10332        AppErrorResult result = new AppErrorResult();
10333        synchronized (this) {
10334            if (mController != null) {
10335                try {
10336                    String name = r != null ? r.processName : null;
10337                    int pid = r != null ? r.pid : Binder.getCallingPid();
10338                    if (!mController.appCrashed(name, pid,
10339                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10340                        Slog.w(TAG, "Force-killing crashed app " + name
10341                                + " at watcher's request");
10342                        Process.killProcess(pid);
10343                        return;
10344                    }
10345                } catch (RemoteException e) {
10346                    mController = null;
10347                    Watchdog.getInstance().setActivityController(null);
10348                }
10349            }
10350
10351            final long origId = Binder.clearCallingIdentity();
10352
10353            // If this process is running instrumentation, finish it.
10354            if (r != null && r.instrumentationClass != null) {
10355                Slog.w(TAG, "Error in app " + r.processName
10356                      + " running instrumentation " + r.instrumentationClass + ":");
10357                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10358                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10359                Bundle info = new Bundle();
10360                info.putString("shortMsg", shortMsg);
10361                info.putString("longMsg", longMsg);
10362                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10363                Binder.restoreCallingIdentity(origId);
10364                return;
10365            }
10366
10367            // If we can't identify the process or it's already exceeded its crash quota,
10368            // quit right away without showing a crash dialog.
10369            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10370                Binder.restoreCallingIdentity(origId);
10371                return;
10372            }
10373
10374            Message msg = Message.obtain();
10375            msg.what = SHOW_ERROR_MSG;
10376            HashMap data = new HashMap();
10377            data.put("result", result);
10378            data.put("app", r);
10379            msg.obj = data;
10380            mHandler.sendMessage(msg);
10381
10382            Binder.restoreCallingIdentity(origId);
10383        }
10384
10385        int res = result.get();
10386
10387        Intent appErrorIntent = null;
10388        synchronized (this) {
10389            if (r != null && !r.isolated) {
10390                // XXX Can't keep track of crash time for isolated processes,
10391                // since they don't have a persistent identity.
10392                mProcessCrashTimes.put(r.info.processName, r.uid,
10393                        SystemClock.uptimeMillis());
10394            }
10395            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10396                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10397            }
10398        }
10399
10400        if (appErrorIntent != null) {
10401            try {
10402                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10403            } catch (ActivityNotFoundException e) {
10404                Slog.w(TAG, "bug report receiver dissappeared", e);
10405            }
10406        }
10407    }
10408
10409    Intent createAppErrorIntentLocked(ProcessRecord r,
10410            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10411        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10412        if (report == null) {
10413            return null;
10414        }
10415        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10416        result.setComponent(r.errorReportReceiver);
10417        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10418        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10419        return result;
10420    }
10421
10422    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10423            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10424        if (r.errorReportReceiver == null) {
10425            return null;
10426        }
10427
10428        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10429            return null;
10430        }
10431
10432        ApplicationErrorReport report = new ApplicationErrorReport();
10433        report.packageName = r.info.packageName;
10434        report.installerPackageName = r.errorReportReceiver.getPackageName();
10435        report.processName = r.processName;
10436        report.time = timeMillis;
10437        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10438
10439        if (r.crashing || r.forceCrashReport) {
10440            report.type = ApplicationErrorReport.TYPE_CRASH;
10441            report.crashInfo = crashInfo;
10442        } else if (r.notResponding) {
10443            report.type = ApplicationErrorReport.TYPE_ANR;
10444            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10445
10446            report.anrInfo.activity = r.notRespondingReport.tag;
10447            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10448            report.anrInfo.info = r.notRespondingReport.longMsg;
10449        }
10450
10451        return report;
10452    }
10453
10454    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10455        enforceNotIsolatedCaller("getProcessesInErrorState");
10456        // assume our apps are happy - lazy create the list
10457        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10458
10459        final boolean allUsers = ActivityManager.checkUidPermission(
10460                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10461                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10462        int userId = UserHandle.getUserId(Binder.getCallingUid());
10463
10464        synchronized (this) {
10465
10466            // iterate across all processes
10467            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10468                ProcessRecord app = mLruProcesses.get(i);
10469                if (!allUsers && app.userId != userId) {
10470                    continue;
10471                }
10472                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10473                    // This one's in trouble, so we'll generate a report for it
10474                    // crashes are higher priority (in case there's a crash *and* an anr)
10475                    ActivityManager.ProcessErrorStateInfo report = null;
10476                    if (app.crashing) {
10477                        report = app.crashingReport;
10478                    } else if (app.notResponding) {
10479                        report = app.notRespondingReport;
10480                    }
10481
10482                    if (report != null) {
10483                        if (errList == null) {
10484                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10485                        }
10486                        errList.add(report);
10487                    } else {
10488                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10489                                " crashing = " + app.crashing +
10490                                " notResponding = " + app.notResponding);
10491                    }
10492                }
10493            }
10494        }
10495
10496        return errList;
10497    }
10498
10499    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10500        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10501            if (currApp != null) {
10502                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10503            }
10504            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10505        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10506            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10507        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10508            if (currApp != null) {
10509                currApp.lru = 0;
10510            }
10511            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10512        } else if (adj >= ProcessList.SERVICE_ADJ) {
10513            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10514        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10515            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10516        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10517            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10518        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10519            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10520        } else {
10521            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10522        }
10523    }
10524
10525    private void fillInProcMemInfo(ProcessRecord app,
10526            ActivityManager.RunningAppProcessInfo outInfo) {
10527        outInfo.pid = app.pid;
10528        outInfo.uid = app.info.uid;
10529        if (mHeavyWeightProcess == app) {
10530            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10531        }
10532        if (app.persistent) {
10533            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10534        }
10535        if (app.activities.size() > 0) {
10536            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10537        }
10538        outInfo.lastTrimLevel = app.trimMemoryLevel;
10539        int adj = app.curAdj;
10540        outInfo.importance = oomAdjToImportance(adj, outInfo);
10541        outInfo.importanceReasonCode = app.adjTypeCode;
10542        outInfo.processState = app.curProcState;
10543    }
10544
10545    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10546        enforceNotIsolatedCaller("getRunningAppProcesses");
10547        // Lazy instantiation of list
10548        List<ActivityManager.RunningAppProcessInfo> runList = null;
10549        final boolean allUsers = ActivityManager.checkUidPermission(
10550                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10551                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10552        int userId = UserHandle.getUserId(Binder.getCallingUid());
10553        synchronized (this) {
10554            // Iterate across all processes
10555            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10556                ProcessRecord app = mLruProcesses.get(i);
10557                if (!allUsers && app.userId != userId) {
10558                    continue;
10559                }
10560                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10561                    // Generate process state info for running application
10562                    ActivityManager.RunningAppProcessInfo currApp =
10563                        new ActivityManager.RunningAppProcessInfo(app.processName,
10564                                app.pid, app.getPackageList());
10565                    fillInProcMemInfo(app, currApp);
10566                    if (app.adjSource instanceof ProcessRecord) {
10567                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10568                        currApp.importanceReasonImportance = oomAdjToImportance(
10569                                app.adjSourceOom, null);
10570                    } else if (app.adjSource instanceof ActivityRecord) {
10571                        ActivityRecord r = (ActivityRecord)app.adjSource;
10572                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10573                    }
10574                    if (app.adjTarget instanceof ComponentName) {
10575                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10576                    }
10577                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10578                    //        + " lru=" + currApp.lru);
10579                    if (runList == null) {
10580                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10581                    }
10582                    runList.add(currApp);
10583                }
10584            }
10585        }
10586        return runList;
10587    }
10588
10589    public List<ApplicationInfo> getRunningExternalApplications() {
10590        enforceNotIsolatedCaller("getRunningExternalApplications");
10591        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10592        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10593        if (runningApps != null && runningApps.size() > 0) {
10594            Set<String> extList = new HashSet<String>();
10595            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10596                if (app.pkgList != null) {
10597                    for (String pkg : app.pkgList) {
10598                        extList.add(pkg);
10599                    }
10600                }
10601            }
10602            IPackageManager pm = AppGlobals.getPackageManager();
10603            for (String pkg : extList) {
10604                try {
10605                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10606                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10607                        retList.add(info);
10608                    }
10609                } catch (RemoteException e) {
10610                }
10611            }
10612        }
10613        return retList;
10614    }
10615
10616    @Override
10617    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10618        enforceNotIsolatedCaller("getMyMemoryState");
10619        synchronized (this) {
10620            ProcessRecord proc;
10621            synchronized (mPidsSelfLocked) {
10622                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10623            }
10624            fillInProcMemInfo(proc, outInfo);
10625        }
10626    }
10627
10628    @Override
10629    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10630        if (checkCallingPermission(android.Manifest.permission.DUMP)
10631                != PackageManager.PERMISSION_GRANTED) {
10632            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10633                    + Binder.getCallingPid()
10634                    + ", uid=" + Binder.getCallingUid()
10635                    + " without permission "
10636                    + android.Manifest.permission.DUMP);
10637            return;
10638        }
10639
10640        boolean dumpAll = false;
10641        boolean dumpClient = false;
10642        String dumpPackage = null;
10643
10644        int opti = 0;
10645        while (opti < args.length) {
10646            String opt = args[opti];
10647            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10648                break;
10649            }
10650            opti++;
10651            if ("-a".equals(opt)) {
10652                dumpAll = true;
10653            } else if ("-c".equals(opt)) {
10654                dumpClient = true;
10655            } else if ("-h".equals(opt)) {
10656                pw.println("Activity manager dump options:");
10657                pw.println("  [-a] [-c] [-h] [cmd] ...");
10658                pw.println("  cmd may be one of:");
10659                pw.println("    a[ctivities]: activity stack state");
10660                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10661                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10662                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10663                pw.println("    o[om]: out of memory management");
10664                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10665                pw.println("    provider [COMP_SPEC]: provider client-side state");
10666                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10667                pw.println("    service [COMP_SPEC]: service client-side state");
10668                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10669                pw.println("    all: dump all activities");
10670                pw.println("    top: dump the top activity");
10671                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10672                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10673                pw.println("    a partial substring in a component name, a");
10674                pw.println("    hex object identifier.");
10675                pw.println("  -a: include all available server state.");
10676                pw.println("  -c: include client state.");
10677                return;
10678            } else {
10679                pw.println("Unknown argument: " + opt + "; use -h for help");
10680            }
10681        }
10682
10683        long origId = Binder.clearCallingIdentity();
10684        boolean more = false;
10685        // Is the caller requesting to dump a particular piece of data?
10686        if (opti < args.length) {
10687            String cmd = args[opti];
10688            opti++;
10689            if ("activities".equals(cmd) || "a".equals(cmd)) {
10690                synchronized (this) {
10691                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10692                }
10693            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10694                String[] newArgs;
10695                String name;
10696                if (opti >= args.length) {
10697                    name = null;
10698                    newArgs = EMPTY_STRING_ARRAY;
10699                } else {
10700                    name = args[opti];
10701                    opti++;
10702                    newArgs = new String[args.length - opti];
10703                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10704                            args.length - opti);
10705                }
10706                synchronized (this) {
10707                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10708                }
10709            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10710                String[] newArgs;
10711                String name;
10712                if (opti >= args.length) {
10713                    name = null;
10714                    newArgs = EMPTY_STRING_ARRAY;
10715                } else {
10716                    name = args[opti];
10717                    opti++;
10718                    newArgs = new String[args.length - opti];
10719                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10720                            args.length - opti);
10721                }
10722                synchronized (this) {
10723                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10724                }
10725            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10726                String[] newArgs;
10727                String name;
10728                if (opti >= args.length) {
10729                    name = null;
10730                    newArgs = EMPTY_STRING_ARRAY;
10731                } else {
10732                    name = args[opti];
10733                    opti++;
10734                    newArgs = new String[args.length - opti];
10735                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10736                            args.length - opti);
10737                }
10738                synchronized (this) {
10739                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10740                }
10741            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10742                synchronized (this) {
10743                    dumpOomLocked(fd, pw, args, opti, true);
10744                }
10745            } else if ("provider".equals(cmd)) {
10746                String[] newArgs;
10747                String name;
10748                if (opti >= args.length) {
10749                    name = null;
10750                    newArgs = EMPTY_STRING_ARRAY;
10751                } else {
10752                    name = args[opti];
10753                    opti++;
10754                    newArgs = new String[args.length - opti];
10755                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10756                }
10757                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10758                    pw.println("No providers match: " + name);
10759                    pw.println("Use -h for help.");
10760                }
10761            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10762                synchronized (this) {
10763                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10764                }
10765            } else if ("service".equals(cmd)) {
10766                String[] newArgs;
10767                String name;
10768                if (opti >= args.length) {
10769                    name = null;
10770                    newArgs = EMPTY_STRING_ARRAY;
10771                } else {
10772                    name = args[opti];
10773                    opti++;
10774                    newArgs = new String[args.length - opti];
10775                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10776                            args.length - opti);
10777                }
10778                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10779                    pw.println("No services match: " + name);
10780                    pw.println("Use -h for help.");
10781                }
10782            } else if ("package".equals(cmd)) {
10783                String[] newArgs;
10784                if (opti >= args.length) {
10785                    pw.println("package: no package name specified");
10786                    pw.println("Use -h for help.");
10787                } else {
10788                    dumpPackage = args[opti];
10789                    opti++;
10790                    newArgs = new String[args.length - opti];
10791                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10792                            args.length - opti);
10793                    args = newArgs;
10794                    opti = 0;
10795                    more = true;
10796                }
10797            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10798                synchronized (this) {
10799                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10800                }
10801            } else {
10802                // Dumping a single activity?
10803                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10804                    pw.println("Bad activity command, or no activities match: " + cmd);
10805                    pw.println("Use -h for help.");
10806                }
10807            }
10808            if (!more) {
10809                Binder.restoreCallingIdentity(origId);
10810                return;
10811            }
10812        }
10813
10814        // No piece of data specified, dump everything.
10815        synchronized (this) {
10816            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10817            pw.println();
10818            if (dumpAll) {
10819                pw.println("-------------------------------------------------------------------------------");
10820            }
10821            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10822            pw.println();
10823            if (dumpAll) {
10824                pw.println("-------------------------------------------------------------------------------");
10825            }
10826            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10827            pw.println();
10828            if (dumpAll) {
10829                pw.println("-------------------------------------------------------------------------------");
10830            }
10831            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10832            pw.println();
10833            if (dumpAll) {
10834                pw.println("-------------------------------------------------------------------------------");
10835            }
10836            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10837            pw.println();
10838            if (dumpAll) {
10839                pw.println("-------------------------------------------------------------------------------");
10840            }
10841            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10842        }
10843        Binder.restoreCallingIdentity(origId);
10844    }
10845
10846    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10847            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10848        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10849
10850        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10851                dumpPackage);
10852        boolean needSep = printedAnything;
10853
10854        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10855                dumpPackage, needSep, "  mFocusedActivity: ");
10856        if (printed) {
10857            printedAnything = true;
10858            needSep = false;
10859        }
10860
10861        if (dumpPackage == null) {
10862            if (needSep) {
10863                pw.println();
10864            }
10865            needSep = true;
10866            printedAnything = true;
10867            mStackSupervisor.dump(pw, "  ");
10868        }
10869
10870        if (mRecentTasks.size() > 0) {
10871            boolean printedHeader = false;
10872
10873            final int N = mRecentTasks.size();
10874            for (int i=0; i<N; i++) {
10875                TaskRecord tr = mRecentTasks.get(i);
10876                if (dumpPackage != null) {
10877                    if (tr.realActivity == null ||
10878                            !dumpPackage.equals(tr.realActivity)) {
10879                        continue;
10880                    }
10881                }
10882                if (!printedHeader) {
10883                    if (needSep) {
10884                        pw.println();
10885                    }
10886                    pw.println("  Recent tasks:");
10887                    printedHeader = true;
10888                    printedAnything = true;
10889                }
10890                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10891                        pw.println(tr);
10892                if (dumpAll) {
10893                    mRecentTasks.get(i).dump(pw, "    ");
10894                }
10895            }
10896        }
10897
10898        if (!printedAnything) {
10899            pw.println("  (nothing)");
10900        }
10901    }
10902
10903    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10904            int opti, boolean dumpAll, String dumpPackage) {
10905        boolean needSep = false;
10906        boolean printedAnything = false;
10907        int numPers = 0;
10908
10909        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10910
10911        if (dumpAll) {
10912            final int NP = mProcessNames.getMap().size();
10913            for (int ip=0; ip<NP; ip++) {
10914                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10915                final int NA = procs.size();
10916                for (int ia=0; ia<NA; ia++) {
10917                    ProcessRecord r = procs.valueAt(ia);
10918                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10919                        continue;
10920                    }
10921                    if (!needSep) {
10922                        pw.println("  All known processes:");
10923                        needSep = true;
10924                        printedAnything = true;
10925                    }
10926                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10927                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10928                        pw.print(" "); pw.println(r);
10929                    r.dump(pw, "    ");
10930                    if (r.persistent) {
10931                        numPers++;
10932                    }
10933                }
10934            }
10935        }
10936
10937        if (mIsolatedProcesses.size() > 0) {
10938            boolean printed = false;
10939            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10940                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10941                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10942                    continue;
10943                }
10944                if (!printed) {
10945                    if (needSep) {
10946                        pw.println();
10947                    }
10948                    pw.println("  Isolated process list (sorted by uid):");
10949                    printedAnything = true;
10950                    printed = true;
10951                    needSep = true;
10952                }
10953                pw.println(String.format("%sIsolated #%2d: %s",
10954                        "    ", i, r.toString()));
10955            }
10956        }
10957
10958        if (mLruProcesses.size() > 0) {
10959            if (needSep) {
10960                pw.println();
10961            }
10962            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10963                    pw.print(" total, non-act at ");
10964                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10965                    pw.print(", non-svc at ");
10966                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10967                    pw.println("):");
10968            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10969            needSep = true;
10970            printedAnything = true;
10971        }
10972
10973        if (dumpAll || dumpPackage != null) {
10974            synchronized (mPidsSelfLocked) {
10975                boolean printed = false;
10976                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10977                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10978                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10979                        continue;
10980                    }
10981                    if (!printed) {
10982                        if (needSep) pw.println();
10983                        needSep = true;
10984                        pw.println("  PID mappings:");
10985                        printed = true;
10986                        printedAnything = true;
10987                    }
10988                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10989                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10990                }
10991            }
10992        }
10993
10994        if (mForegroundProcesses.size() > 0) {
10995            synchronized (mPidsSelfLocked) {
10996                boolean printed = false;
10997                for (int i=0; i<mForegroundProcesses.size(); i++) {
10998                    ProcessRecord r = mPidsSelfLocked.get(
10999                            mForegroundProcesses.valueAt(i).pid);
11000                    if (dumpPackage != null && (r == null
11001                            || !r.pkgList.containsKey(dumpPackage))) {
11002                        continue;
11003                    }
11004                    if (!printed) {
11005                        if (needSep) pw.println();
11006                        needSep = true;
11007                        pw.println("  Foreground Processes:");
11008                        printed = true;
11009                        printedAnything = true;
11010                    }
11011                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11012                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11013                }
11014            }
11015        }
11016
11017        if (mPersistentStartingProcesses.size() > 0) {
11018            if (needSep) pw.println();
11019            needSep = true;
11020            printedAnything = true;
11021            pw.println("  Persisent processes that are starting:");
11022            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11023                    "Starting Norm", "Restarting PERS", dumpPackage);
11024        }
11025
11026        if (mRemovedProcesses.size() > 0) {
11027            if (needSep) pw.println();
11028            needSep = true;
11029            printedAnything = true;
11030            pw.println("  Processes that are being removed:");
11031            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11032                    "Removed Norm", "Removed PERS", dumpPackage);
11033        }
11034
11035        if (mProcessesOnHold.size() > 0) {
11036            if (needSep) pw.println();
11037            needSep = true;
11038            printedAnything = true;
11039            pw.println("  Processes that are on old until the system is ready:");
11040            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11041                    "OnHold Norm", "OnHold PERS", dumpPackage);
11042        }
11043
11044        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11045
11046        if (mProcessCrashTimes.getMap().size() > 0) {
11047            boolean printed = false;
11048            long now = SystemClock.uptimeMillis();
11049            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11050            final int NP = pmap.size();
11051            for (int ip=0; ip<NP; ip++) {
11052                String pname = pmap.keyAt(ip);
11053                SparseArray<Long> uids = pmap.valueAt(ip);
11054                final int N = uids.size();
11055                for (int i=0; i<N; i++) {
11056                    int puid = uids.keyAt(i);
11057                    ProcessRecord r = mProcessNames.get(pname, puid);
11058                    if (dumpPackage != null && (r == null
11059                            || !r.pkgList.containsKey(dumpPackage))) {
11060                        continue;
11061                    }
11062                    if (!printed) {
11063                        if (needSep) pw.println();
11064                        needSep = true;
11065                        pw.println("  Time since processes crashed:");
11066                        printed = true;
11067                        printedAnything = true;
11068                    }
11069                    pw.print("    Process "); pw.print(pname);
11070                            pw.print(" uid "); pw.print(puid);
11071                            pw.print(": last crashed ");
11072                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11073                            pw.println(" ago");
11074                }
11075            }
11076        }
11077
11078        if (mBadProcesses.getMap().size() > 0) {
11079            boolean printed = false;
11080            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11081            final int NP = pmap.size();
11082            for (int ip=0; ip<NP; ip++) {
11083                String pname = pmap.keyAt(ip);
11084                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11085                final int N = uids.size();
11086                for (int i=0; i<N; i++) {
11087                    int puid = uids.keyAt(i);
11088                    ProcessRecord r = mProcessNames.get(pname, puid);
11089                    if (dumpPackage != null && (r == null
11090                            || !r.pkgList.containsKey(dumpPackage))) {
11091                        continue;
11092                    }
11093                    if (!printed) {
11094                        if (needSep) pw.println();
11095                        needSep = true;
11096                        pw.println("  Bad processes:");
11097                        printedAnything = true;
11098                    }
11099                    BadProcessInfo info = uids.valueAt(i);
11100                    pw.print("    Bad process "); pw.print(pname);
11101                            pw.print(" uid "); pw.print(puid);
11102                            pw.print(": crashed at time "); pw.println(info.time);
11103                    if (info.shortMsg != null) {
11104                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11105                    }
11106                    if (info.longMsg != null) {
11107                        pw.print("      Long msg: "); pw.println(info.longMsg);
11108                    }
11109                    if (info.stack != null) {
11110                        pw.println("      Stack:");
11111                        int lastPos = 0;
11112                        for (int pos=0; pos<info.stack.length(); pos++) {
11113                            if (info.stack.charAt(pos) == '\n') {
11114                                pw.print("        ");
11115                                pw.write(info.stack, lastPos, pos-lastPos);
11116                                pw.println();
11117                                lastPos = pos+1;
11118                            }
11119                        }
11120                        if (lastPos < info.stack.length()) {
11121                            pw.print("        ");
11122                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11123                            pw.println();
11124                        }
11125                    }
11126                }
11127            }
11128        }
11129
11130        if (dumpPackage == null) {
11131            pw.println();
11132            needSep = false;
11133            pw.println("  mStartedUsers:");
11134            for (int i=0; i<mStartedUsers.size(); i++) {
11135                UserStartedState uss = mStartedUsers.valueAt(i);
11136                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11137                        pw.print(": "); uss.dump("", pw);
11138            }
11139            pw.print("  mStartedUserArray: [");
11140            for (int i=0; i<mStartedUserArray.length; i++) {
11141                if (i > 0) pw.print(", ");
11142                pw.print(mStartedUserArray[i]);
11143            }
11144            pw.println("]");
11145            pw.print("  mUserLru: [");
11146            for (int i=0; i<mUserLru.size(); i++) {
11147                if (i > 0) pw.print(", ");
11148                pw.print(mUserLru.get(i));
11149            }
11150            pw.println("]");
11151            if (dumpAll) {
11152                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11153            }
11154        }
11155        if (mHomeProcess != null && (dumpPackage == null
11156                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11157            if (needSep) {
11158                pw.println();
11159                needSep = false;
11160            }
11161            pw.println("  mHomeProcess: " + mHomeProcess);
11162        }
11163        if (mPreviousProcess != null && (dumpPackage == null
11164                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11165            if (needSep) {
11166                pw.println();
11167                needSep = false;
11168            }
11169            pw.println("  mPreviousProcess: " + mPreviousProcess);
11170        }
11171        if (dumpAll) {
11172            StringBuilder sb = new StringBuilder(128);
11173            sb.append("  mPreviousProcessVisibleTime: ");
11174            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11175            pw.println(sb);
11176        }
11177        if (mHeavyWeightProcess != null && (dumpPackage == null
11178                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11179            if (needSep) {
11180                pw.println();
11181                needSep = false;
11182            }
11183            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11184        }
11185        if (dumpPackage == null) {
11186            pw.println("  mConfiguration: " + mConfiguration);
11187        }
11188        if (dumpAll) {
11189            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11190            if (mCompatModePackages.getPackages().size() > 0) {
11191                boolean printed = false;
11192                for (Map.Entry<String, Integer> entry
11193                        : mCompatModePackages.getPackages().entrySet()) {
11194                    String pkg = entry.getKey();
11195                    int mode = entry.getValue();
11196                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11197                        continue;
11198                    }
11199                    if (!printed) {
11200                        pw.println("  mScreenCompatPackages:");
11201                        printed = true;
11202                    }
11203                    pw.print("    "); pw.print(pkg); pw.print(": ");
11204                            pw.print(mode); pw.println();
11205                }
11206            }
11207        }
11208        if (dumpPackage == null) {
11209            if (mSleeping || mWentToSleep || mLockScreenShown) {
11210                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11211                        + " mLockScreenShown " + mLockScreenShown);
11212            }
11213            if (mShuttingDown || mRunningVoice) {
11214                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11215            }
11216        }
11217        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11218                || mOrigWaitForDebugger) {
11219            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11220                    || dumpPackage.equals(mOrigDebugApp)) {
11221                if (needSep) {
11222                    pw.println();
11223                    needSep = false;
11224                }
11225                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11226                        + " mDebugTransient=" + mDebugTransient
11227                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11228            }
11229        }
11230        if (mOpenGlTraceApp != null) {
11231            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11232                if (needSep) {
11233                    pw.println();
11234                    needSep = false;
11235                }
11236                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11237            }
11238        }
11239        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11240                || mProfileFd != null) {
11241            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11242                if (needSep) {
11243                    pw.println();
11244                    needSep = false;
11245                }
11246                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11247                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11248                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11249                        + mAutoStopProfiler);
11250            }
11251        }
11252        if (dumpPackage == null) {
11253            if (mAlwaysFinishActivities || mController != null) {
11254                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11255                        + " mController=" + mController);
11256            }
11257            if (dumpAll) {
11258                pw.println("  Total persistent processes: " + numPers);
11259                pw.println("  mProcessesReady=" + mProcessesReady
11260                        + " mSystemReady=" + mSystemReady);
11261                pw.println("  mBooting=" + mBooting
11262                        + " mBooted=" + mBooted
11263                        + " mFactoryTest=" + mFactoryTest);
11264                pw.print("  mLastPowerCheckRealtime=");
11265                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11266                        pw.println("");
11267                pw.print("  mLastPowerCheckUptime=");
11268                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11269                        pw.println("");
11270                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11271                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11272                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11273                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11274                        + " (" + mLruProcesses.size() + " total)"
11275                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11276                        + " mNumServiceProcs=" + mNumServiceProcs
11277                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11278                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11279                        + " mLastMemoryLevel" + mLastMemoryLevel
11280                        + " mLastNumProcesses" + mLastNumProcesses);
11281                long now = SystemClock.uptimeMillis();
11282                pw.print("  mLastIdleTime=");
11283                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11284                        pw.print(" mLowRamSinceLastIdle=");
11285                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11286                        pw.println();
11287            }
11288        }
11289
11290        if (!printedAnything) {
11291            pw.println("  (nothing)");
11292        }
11293    }
11294
11295    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11296            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11297        if (mProcessesToGc.size() > 0) {
11298            boolean printed = false;
11299            long now = SystemClock.uptimeMillis();
11300            for (int i=0; i<mProcessesToGc.size(); i++) {
11301                ProcessRecord proc = mProcessesToGc.get(i);
11302                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11303                    continue;
11304                }
11305                if (!printed) {
11306                    if (needSep) pw.println();
11307                    needSep = true;
11308                    pw.println("  Processes that are waiting to GC:");
11309                    printed = true;
11310                }
11311                pw.print("    Process "); pw.println(proc);
11312                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11313                        pw.print(", last gced=");
11314                        pw.print(now-proc.lastRequestedGc);
11315                        pw.print(" ms ago, last lowMem=");
11316                        pw.print(now-proc.lastLowMemory);
11317                        pw.println(" ms ago");
11318
11319            }
11320        }
11321        return needSep;
11322    }
11323
11324    void printOomLevel(PrintWriter pw, String name, int adj) {
11325        pw.print("    ");
11326        if (adj >= 0) {
11327            pw.print(' ');
11328            if (adj < 10) pw.print(' ');
11329        } else {
11330            if (adj > -10) pw.print(' ');
11331        }
11332        pw.print(adj);
11333        pw.print(": ");
11334        pw.print(name);
11335        pw.print(" (");
11336        pw.print(mProcessList.getMemLevel(adj)/1024);
11337        pw.println(" kB)");
11338    }
11339
11340    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11341            int opti, boolean dumpAll) {
11342        boolean needSep = false;
11343
11344        if (mLruProcesses.size() > 0) {
11345            if (needSep) pw.println();
11346            needSep = true;
11347            pw.println("  OOM levels:");
11348            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11349            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11350            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11351            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11352            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11353            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11354            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11355            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11356            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11357            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11358            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11359            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11360            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11361
11362            if (needSep) pw.println();
11363            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11364                    pw.print(" total, non-act at ");
11365                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11366                    pw.print(", non-svc at ");
11367                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11368                    pw.println("):");
11369            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11370            needSep = true;
11371        }
11372
11373        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11374
11375        pw.println();
11376        pw.println("  mHomeProcess: " + mHomeProcess);
11377        pw.println("  mPreviousProcess: " + mPreviousProcess);
11378        if (mHeavyWeightProcess != null) {
11379            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11380        }
11381
11382        return true;
11383    }
11384
11385    /**
11386     * There are three ways to call this:
11387     *  - no provider specified: dump all the providers
11388     *  - a flattened component name that matched an existing provider was specified as the
11389     *    first arg: dump that one provider
11390     *  - the first arg isn't the flattened component name of an existing provider:
11391     *    dump all providers whose component contains the first arg as a substring
11392     */
11393    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11394            int opti, boolean dumpAll) {
11395        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11396    }
11397
11398    static class ItemMatcher {
11399        ArrayList<ComponentName> components;
11400        ArrayList<String> strings;
11401        ArrayList<Integer> objects;
11402        boolean all;
11403
11404        ItemMatcher() {
11405            all = true;
11406        }
11407
11408        void build(String name) {
11409            ComponentName componentName = ComponentName.unflattenFromString(name);
11410            if (componentName != null) {
11411                if (components == null) {
11412                    components = new ArrayList<ComponentName>();
11413                }
11414                components.add(componentName);
11415                all = false;
11416            } else {
11417                int objectId = 0;
11418                // Not a '/' separated full component name; maybe an object ID?
11419                try {
11420                    objectId = Integer.parseInt(name, 16);
11421                    if (objects == null) {
11422                        objects = new ArrayList<Integer>();
11423                    }
11424                    objects.add(objectId);
11425                    all = false;
11426                } catch (RuntimeException e) {
11427                    // Not an integer; just do string match.
11428                    if (strings == null) {
11429                        strings = new ArrayList<String>();
11430                    }
11431                    strings.add(name);
11432                    all = false;
11433                }
11434            }
11435        }
11436
11437        int build(String[] args, int opti) {
11438            for (; opti<args.length; opti++) {
11439                String name = args[opti];
11440                if ("--".equals(name)) {
11441                    return opti+1;
11442                }
11443                build(name);
11444            }
11445            return opti;
11446        }
11447
11448        boolean match(Object object, ComponentName comp) {
11449            if (all) {
11450                return true;
11451            }
11452            if (components != null) {
11453                for (int i=0; i<components.size(); i++) {
11454                    if (components.get(i).equals(comp)) {
11455                        return true;
11456                    }
11457                }
11458            }
11459            if (objects != null) {
11460                for (int i=0; i<objects.size(); i++) {
11461                    if (System.identityHashCode(object) == objects.get(i)) {
11462                        return true;
11463                    }
11464                }
11465            }
11466            if (strings != null) {
11467                String flat = comp.flattenToString();
11468                for (int i=0; i<strings.size(); i++) {
11469                    if (flat.contains(strings.get(i))) {
11470                        return true;
11471                    }
11472                }
11473            }
11474            return false;
11475        }
11476    }
11477
11478    /**
11479     * There are three things that cmd can be:
11480     *  - a flattened component name that matches an existing activity
11481     *  - the cmd arg isn't the flattened component name of an existing activity:
11482     *    dump all activity whose component contains the cmd as a substring
11483     *  - A hex number of the ActivityRecord object instance.
11484     */
11485    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11486            int opti, boolean dumpAll) {
11487        ArrayList<ActivityRecord> activities;
11488
11489        synchronized (this) {
11490            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11491        }
11492
11493        if (activities.size() <= 0) {
11494            return false;
11495        }
11496
11497        String[] newArgs = new String[args.length - opti];
11498        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11499
11500        TaskRecord lastTask = null;
11501        boolean needSep = false;
11502        for (int i=activities.size()-1; i>=0; i--) {
11503            ActivityRecord r = activities.get(i);
11504            if (needSep) {
11505                pw.println();
11506            }
11507            needSep = true;
11508            synchronized (this) {
11509                if (lastTask != r.task) {
11510                    lastTask = r.task;
11511                    pw.print("TASK "); pw.print(lastTask.affinity);
11512                            pw.print(" id="); pw.println(lastTask.taskId);
11513                    if (dumpAll) {
11514                        lastTask.dump(pw, "  ");
11515                    }
11516                }
11517            }
11518            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11519        }
11520        return true;
11521    }
11522
11523    /**
11524     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11525     * there is a thread associated with the activity.
11526     */
11527    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11528            final ActivityRecord r, String[] args, boolean dumpAll) {
11529        String innerPrefix = prefix + "  ";
11530        synchronized (this) {
11531            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11532                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11533                    pw.print(" pid=");
11534                    if (r.app != null) pw.println(r.app.pid);
11535                    else pw.println("(not running)");
11536            if (dumpAll) {
11537                r.dump(pw, innerPrefix);
11538            }
11539        }
11540        if (r.app != null && r.app.thread != null) {
11541            // flush anything that is already in the PrintWriter since the thread is going
11542            // to write to the file descriptor directly
11543            pw.flush();
11544            try {
11545                TransferPipe tp = new TransferPipe();
11546                try {
11547                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11548                            r.appToken, innerPrefix, args);
11549                    tp.go(fd);
11550                } finally {
11551                    tp.kill();
11552                }
11553            } catch (IOException e) {
11554                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11555            } catch (RemoteException e) {
11556                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11557            }
11558        }
11559    }
11560
11561    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11562            int opti, boolean dumpAll, String dumpPackage) {
11563        boolean needSep = false;
11564        boolean onlyHistory = false;
11565        boolean printedAnything = false;
11566
11567        if ("history".equals(dumpPackage)) {
11568            if (opti < args.length && "-s".equals(args[opti])) {
11569                dumpAll = false;
11570            }
11571            onlyHistory = true;
11572            dumpPackage = null;
11573        }
11574
11575        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11576        if (!onlyHistory && dumpAll) {
11577            if (mRegisteredReceivers.size() > 0) {
11578                boolean printed = false;
11579                Iterator it = mRegisteredReceivers.values().iterator();
11580                while (it.hasNext()) {
11581                    ReceiverList r = (ReceiverList)it.next();
11582                    if (dumpPackage != null && (r.app == null ||
11583                            !dumpPackage.equals(r.app.info.packageName))) {
11584                        continue;
11585                    }
11586                    if (!printed) {
11587                        pw.println("  Registered Receivers:");
11588                        needSep = true;
11589                        printed = true;
11590                        printedAnything = true;
11591                    }
11592                    pw.print("  * "); pw.println(r);
11593                    r.dump(pw, "    ");
11594                }
11595            }
11596
11597            if (mReceiverResolver.dump(pw, needSep ?
11598                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11599                    "    ", dumpPackage, false)) {
11600                needSep = true;
11601                printedAnything = true;
11602            }
11603        }
11604
11605        for (BroadcastQueue q : mBroadcastQueues) {
11606            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11607            printedAnything |= needSep;
11608        }
11609
11610        needSep = true;
11611
11612        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11613            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11614                if (needSep) {
11615                    pw.println();
11616                }
11617                needSep = true;
11618                printedAnything = true;
11619                pw.print("  Sticky broadcasts for user ");
11620                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11621                StringBuilder sb = new StringBuilder(128);
11622                for (Map.Entry<String, ArrayList<Intent>> ent
11623                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11624                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11625                    if (dumpAll) {
11626                        pw.println(":");
11627                        ArrayList<Intent> intents = ent.getValue();
11628                        final int N = intents.size();
11629                        for (int i=0; i<N; i++) {
11630                            sb.setLength(0);
11631                            sb.append("    Intent: ");
11632                            intents.get(i).toShortString(sb, false, true, false, false);
11633                            pw.println(sb.toString());
11634                            Bundle bundle = intents.get(i).getExtras();
11635                            if (bundle != null) {
11636                                pw.print("      ");
11637                                pw.println(bundle.toString());
11638                            }
11639                        }
11640                    } else {
11641                        pw.println("");
11642                    }
11643                }
11644            }
11645        }
11646
11647        if (!onlyHistory && dumpAll) {
11648            pw.println();
11649            for (BroadcastQueue queue : mBroadcastQueues) {
11650                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11651                        + queue.mBroadcastsScheduled);
11652            }
11653            pw.println("  mHandler:");
11654            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11655            needSep = true;
11656            printedAnything = true;
11657        }
11658
11659        if (!printedAnything) {
11660            pw.println("  (nothing)");
11661        }
11662    }
11663
11664    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11665            int opti, boolean dumpAll, String dumpPackage) {
11666        boolean needSep;
11667        boolean printedAnything = false;
11668
11669        ItemMatcher matcher = new ItemMatcher();
11670        matcher.build(args, opti);
11671
11672        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11673
11674        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11675        printedAnything |= needSep;
11676
11677        if (mLaunchingProviders.size() > 0) {
11678            boolean printed = false;
11679            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11680                ContentProviderRecord r = mLaunchingProviders.get(i);
11681                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11682                    continue;
11683                }
11684                if (!printed) {
11685                    if (needSep) pw.println();
11686                    needSep = true;
11687                    pw.println("  Launching content providers:");
11688                    printed = true;
11689                    printedAnything = true;
11690                }
11691                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11692                        pw.println(r);
11693            }
11694        }
11695
11696        if (mGrantedUriPermissions.size() > 0) {
11697            boolean printed = false;
11698            int dumpUid = -2;
11699            if (dumpPackage != null) {
11700                try {
11701                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11702                } catch (NameNotFoundException e) {
11703                    dumpUid = -1;
11704                }
11705            }
11706            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11707                int uid = mGrantedUriPermissions.keyAt(i);
11708                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11709                    continue;
11710                }
11711                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11712                if (!printed) {
11713                    if (needSep) pw.println();
11714                    needSep = true;
11715                    pw.println("  Granted Uri Permissions:");
11716                    printed = true;
11717                    printedAnything = true;
11718                }
11719                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11720                for (UriPermission perm : perms.values()) {
11721                    pw.print("    "); pw.println(perm);
11722                    if (dumpAll) {
11723                        perm.dump(pw, "      ");
11724                    }
11725                }
11726            }
11727        }
11728
11729        if (!printedAnything) {
11730            pw.println("  (nothing)");
11731        }
11732    }
11733
11734    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11735            int opti, boolean dumpAll, String dumpPackage) {
11736        boolean printed = false;
11737
11738        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11739
11740        if (mIntentSenderRecords.size() > 0) {
11741            Iterator<WeakReference<PendingIntentRecord>> it
11742                    = mIntentSenderRecords.values().iterator();
11743            while (it.hasNext()) {
11744                WeakReference<PendingIntentRecord> ref = it.next();
11745                PendingIntentRecord rec = ref != null ? ref.get(): null;
11746                if (dumpPackage != null && (rec == null
11747                        || !dumpPackage.equals(rec.key.packageName))) {
11748                    continue;
11749                }
11750                printed = true;
11751                if (rec != null) {
11752                    pw.print("  * "); pw.println(rec);
11753                    if (dumpAll) {
11754                        rec.dump(pw, "    ");
11755                    }
11756                } else {
11757                    pw.print("  * "); pw.println(ref);
11758                }
11759            }
11760        }
11761
11762        if (!printed) {
11763            pw.println("  (nothing)");
11764        }
11765    }
11766
11767    private static final int dumpProcessList(PrintWriter pw,
11768            ActivityManagerService service, List list,
11769            String prefix, String normalLabel, String persistentLabel,
11770            String dumpPackage) {
11771        int numPers = 0;
11772        final int N = list.size()-1;
11773        for (int i=N; i>=0; i--) {
11774            ProcessRecord r = (ProcessRecord)list.get(i);
11775            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11776                continue;
11777            }
11778            pw.println(String.format("%s%s #%2d: %s",
11779                    prefix, (r.persistent ? persistentLabel : normalLabel),
11780                    i, r.toString()));
11781            if (r.persistent) {
11782                numPers++;
11783            }
11784        }
11785        return numPers;
11786    }
11787
11788    private static final boolean dumpProcessOomList(PrintWriter pw,
11789            ActivityManagerService service, List<ProcessRecord> origList,
11790            String prefix, String normalLabel, String persistentLabel,
11791            boolean inclDetails, String dumpPackage) {
11792
11793        ArrayList<Pair<ProcessRecord, Integer>> list
11794                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11795        for (int i=0; i<origList.size(); i++) {
11796            ProcessRecord r = origList.get(i);
11797            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11798                continue;
11799            }
11800            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11801        }
11802
11803        if (list.size() <= 0) {
11804            return false;
11805        }
11806
11807        Comparator<Pair<ProcessRecord, Integer>> comparator
11808                = new Comparator<Pair<ProcessRecord, Integer>>() {
11809            @Override
11810            public int compare(Pair<ProcessRecord, Integer> object1,
11811                    Pair<ProcessRecord, Integer> object2) {
11812                if (object1.first.setAdj != object2.first.setAdj) {
11813                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11814                }
11815                if (object1.second.intValue() != object2.second.intValue()) {
11816                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11817                }
11818                return 0;
11819            }
11820        };
11821
11822        Collections.sort(list, comparator);
11823
11824        final long curRealtime = SystemClock.elapsedRealtime();
11825        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11826        final long curUptime = SystemClock.uptimeMillis();
11827        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11828
11829        for (int i=list.size()-1; i>=0; i--) {
11830            ProcessRecord r = list.get(i).first;
11831            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11832            char schedGroup;
11833            switch (r.setSchedGroup) {
11834                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11835                    schedGroup = 'B';
11836                    break;
11837                case Process.THREAD_GROUP_DEFAULT:
11838                    schedGroup = 'F';
11839                    break;
11840                default:
11841                    schedGroup = '?';
11842                    break;
11843            }
11844            char foreground;
11845            if (r.foregroundActivities) {
11846                foreground = 'A';
11847            } else if (r.foregroundServices) {
11848                foreground = 'S';
11849            } else {
11850                foreground = ' ';
11851            }
11852            String procState = ProcessList.makeProcStateString(r.curProcState);
11853            pw.print(prefix);
11854            pw.print(r.persistent ? persistentLabel : normalLabel);
11855            pw.print(" #");
11856            int num = (origList.size()-1)-list.get(i).second;
11857            if (num < 10) pw.print(' ');
11858            pw.print(num);
11859            pw.print(": ");
11860            pw.print(oomAdj);
11861            pw.print(' ');
11862            pw.print(schedGroup);
11863            pw.print('/');
11864            pw.print(foreground);
11865            pw.print('/');
11866            pw.print(procState);
11867            pw.print(" trm:");
11868            if (r.trimMemoryLevel < 10) pw.print(' ');
11869            pw.print(r.trimMemoryLevel);
11870            pw.print(' ');
11871            pw.print(r.toShortString());
11872            pw.print(" (");
11873            pw.print(r.adjType);
11874            pw.println(')');
11875            if (r.adjSource != null || r.adjTarget != null) {
11876                pw.print(prefix);
11877                pw.print("    ");
11878                if (r.adjTarget instanceof ComponentName) {
11879                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11880                } else if (r.adjTarget != null) {
11881                    pw.print(r.adjTarget.toString());
11882                } else {
11883                    pw.print("{null}");
11884                }
11885                pw.print("<=");
11886                if (r.adjSource instanceof ProcessRecord) {
11887                    pw.print("Proc{");
11888                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11889                    pw.println("}");
11890                } else if (r.adjSource != null) {
11891                    pw.println(r.adjSource.toString());
11892                } else {
11893                    pw.println("{null}");
11894                }
11895            }
11896            if (inclDetails) {
11897                pw.print(prefix);
11898                pw.print("    ");
11899                pw.print("oom: max="); pw.print(r.maxAdj);
11900                pw.print(" curRaw="); pw.print(r.curRawAdj);
11901                pw.print(" setRaw="); pw.print(r.setRawAdj);
11902                pw.print(" cur="); pw.print(r.curAdj);
11903                pw.print(" set="); pw.println(r.setAdj);
11904                pw.print(prefix);
11905                pw.print("    ");
11906                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11907                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11908                pw.print(" lastPss="); pw.print(r.lastPss);
11909                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11910                pw.print(prefix);
11911                pw.print("    ");
11912                pw.print("keeping="); pw.print(r.keeping);
11913                pw.print(" cached="); pw.print(r.cached);
11914                pw.print(" empty="); pw.print(r.empty);
11915                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11916
11917                if (!r.keeping) {
11918                    if (r.lastWakeTime != 0) {
11919                        long wtime;
11920                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11921                        synchronized (stats) {
11922                            wtime = stats.getProcessWakeTime(r.info.uid,
11923                                    r.pid, curRealtime);
11924                        }
11925                        long timeUsed = wtime - r.lastWakeTime;
11926                        pw.print(prefix);
11927                        pw.print("    ");
11928                        pw.print("keep awake over ");
11929                        TimeUtils.formatDuration(realtimeSince, pw);
11930                        pw.print(" used ");
11931                        TimeUtils.formatDuration(timeUsed, pw);
11932                        pw.print(" (");
11933                        pw.print((timeUsed*100)/realtimeSince);
11934                        pw.println("%)");
11935                    }
11936                    if (r.lastCpuTime != 0) {
11937                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11938                        pw.print(prefix);
11939                        pw.print("    ");
11940                        pw.print("run cpu over ");
11941                        TimeUtils.formatDuration(uptimeSince, pw);
11942                        pw.print(" used ");
11943                        TimeUtils.formatDuration(timeUsed, pw);
11944                        pw.print(" (");
11945                        pw.print((timeUsed*100)/uptimeSince);
11946                        pw.println("%)");
11947                    }
11948                }
11949            }
11950        }
11951        return true;
11952    }
11953
11954    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11955        ArrayList<ProcessRecord> procs;
11956        synchronized (this) {
11957            if (args != null && args.length > start
11958                    && args[start].charAt(0) != '-') {
11959                procs = new ArrayList<ProcessRecord>();
11960                int pid = -1;
11961                try {
11962                    pid = Integer.parseInt(args[start]);
11963                } catch (NumberFormatException e) {
11964                }
11965                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11966                    ProcessRecord proc = mLruProcesses.get(i);
11967                    if (proc.pid == pid) {
11968                        procs.add(proc);
11969                    } else if (proc.processName.equals(args[start])) {
11970                        procs.add(proc);
11971                    }
11972                }
11973                if (procs.size() <= 0) {
11974                    return null;
11975                }
11976            } else {
11977                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11978            }
11979        }
11980        return procs;
11981    }
11982
11983    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11984            PrintWriter pw, String[] args) {
11985        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11986        if (procs == null) {
11987            pw.println("No process found for: " + args[0]);
11988            return;
11989        }
11990
11991        long uptime = SystemClock.uptimeMillis();
11992        long realtime = SystemClock.elapsedRealtime();
11993        pw.println("Applications Graphics Acceleration Info:");
11994        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11995
11996        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11997            ProcessRecord r = procs.get(i);
11998            if (r.thread != null) {
11999                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12000                pw.flush();
12001                try {
12002                    TransferPipe tp = new TransferPipe();
12003                    try {
12004                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12005                        tp.go(fd);
12006                    } finally {
12007                        tp.kill();
12008                    }
12009                } catch (IOException e) {
12010                    pw.println("Failure while dumping the app: " + r);
12011                    pw.flush();
12012                } catch (RemoteException e) {
12013                    pw.println("Got a RemoteException while dumping the app " + r);
12014                    pw.flush();
12015                }
12016            }
12017        }
12018    }
12019
12020    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12021        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12022        if (procs == null) {
12023            pw.println("No process found for: " + args[0]);
12024            return;
12025        }
12026
12027        pw.println("Applications Database Info:");
12028
12029        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12030            ProcessRecord r = procs.get(i);
12031            if (r.thread != null) {
12032                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12033                pw.flush();
12034                try {
12035                    TransferPipe tp = new TransferPipe();
12036                    try {
12037                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12038                        tp.go(fd);
12039                    } finally {
12040                        tp.kill();
12041                    }
12042                } catch (IOException e) {
12043                    pw.println("Failure while dumping the app: " + r);
12044                    pw.flush();
12045                } catch (RemoteException e) {
12046                    pw.println("Got a RemoteException while dumping the app " + r);
12047                    pw.flush();
12048                }
12049            }
12050        }
12051    }
12052
12053    final static class MemItem {
12054        final boolean isProc;
12055        final String label;
12056        final String shortLabel;
12057        final long pss;
12058        final int id;
12059        final boolean hasActivities;
12060        ArrayList<MemItem> subitems;
12061
12062        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12063                boolean _hasActivities) {
12064            isProc = true;
12065            label = _label;
12066            shortLabel = _shortLabel;
12067            pss = _pss;
12068            id = _id;
12069            hasActivities = _hasActivities;
12070        }
12071
12072        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12073            isProc = false;
12074            label = _label;
12075            shortLabel = _shortLabel;
12076            pss = _pss;
12077            id = _id;
12078            hasActivities = false;
12079        }
12080    }
12081
12082    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12083            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12084        if (sort && !isCompact) {
12085            Collections.sort(items, new Comparator<MemItem>() {
12086                @Override
12087                public int compare(MemItem lhs, MemItem rhs) {
12088                    if (lhs.pss < rhs.pss) {
12089                        return 1;
12090                    } else if (lhs.pss > rhs.pss) {
12091                        return -1;
12092                    }
12093                    return 0;
12094                }
12095            });
12096        }
12097
12098        for (int i=0; i<items.size(); i++) {
12099            MemItem mi = items.get(i);
12100            if (!isCompact) {
12101                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12102            } else if (mi.isProc) {
12103                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12104                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12105                pw.println(mi.hasActivities ? ",a" : ",e");
12106            } else {
12107                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12108                pw.println(mi.pss);
12109            }
12110            if (mi.subitems != null) {
12111                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12112                        true, isCompact);
12113            }
12114        }
12115    }
12116
12117    // These are in KB.
12118    static final long[] DUMP_MEM_BUCKETS = new long[] {
12119        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12120        120*1024, 160*1024, 200*1024,
12121        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12122        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12123    };
12124
12125    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12126            boolean stackLike) {
12127        int start = label.lastIndexOf('.');
12128        if (start >= 0) start++;
12129        else start = 0;
12130        int end = label.length();
12131        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12132            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12133                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12134                out.append(bucket);
12135                out.append(stackLike ? "MB." : "MB ");
12136                out.append(label, start, end);
12137                return;
12138            }
12139        }
12140        out.append(memKB/1024);
12141        out.append(stackLike ? "MB." : "MB ");
12142        out.append(label, start, end);
12143    }
12144
12145    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12146            ProcessList.NATIVE_ADJ,
12147            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12148            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12149            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12150            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12151            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12152    };
12153    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12154            "Native",
12155            "System", "Persistent", "Foreground",
12156            "Visible", "Perceptible",
12157            "Heavy Weight", "Backup",
12158            "A Services", "Home",
12159            "Previous", "B Services", "Cached"
12160    };
12161    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12162            "native",
12163            "sys", "pers", "fore",
12164            "vis", "percept",
12165            "heavy", "backup",
12166            "servicea", "home",
12167            "prev", "serviceb", "cached"
12168    };
12169
12170    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12171            long realtime, boolean isCheckinRequest, boolean isCompact) {
12172        if (isCheckinRequest || isCompact) {
12173            // short checkin version
12174            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12175        } else {
12176            pw.println("Applications Memory Usage (kB):");
12177            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12178        }
12179    }
12180
12181    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12182            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12183        boolean dumpDetails = false;
12184        boolean dumpFullDetails = false;
12185        boolean dumpDalvik = false;
12186        boolean oomOnly = false;
12187        boolean isCompact = false;
12188        boolean localOnly = false;
12189
12190        int opti = 0;
12191        while (opti < args.length) {
12192            String opt = args[opti];
12193            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12194                break;
12195            }
12196            opti++;
12197            if ("-a".equals(opt)) {
12198                dumpDetails = true;
12199                dumpFullDetails = true;
12200                dumpDalvik = true;
12201            } else if ("-d".equals(opt)) {
12202                dumpDalvik = true;
12203            } else if ("-c".equals(opt)) {
12204                isCompact = true;
12205            } else if ("--oom".equals(opt)) {
12206                oomOnly = true;
12207            } else if ("--local".equals(opt)) {
12208                localOnly = true;
12209            } else if ("-h".equals(opt)) {
12210                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12211                pw.println("  -a: include all available information for each process.");
12212                pw.println("  -d: include dalvik details when dumping process details.");
12213                pw.println("  -c: dump in a compact machine-parseable representation.");
12214                pw.println("  --oom: only show processes organized by oom adj.");
12215                pw.println("  --local: only collect details locally, don't call process.");
12216                pw.println("If [process] is specified it can be the name or ");
12217                pw.println("pid of a specific process to dump.");
12218                return;
12219            } else {
12220                pw.println("Unknown argument: " + opt + "; use -h for help");
12221            }
12222        }
12223
12224        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12225        long uptime = SystemClock.uptimeMillis();
12226        long realtime = SystemClock.elapsedRealtime();
12227        final long[] tmpLong = new long[1];
12228
12229        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12230        if (procs == null) {
12231            // No Java processes.  Maybe they want to print a native process.
12232            if (args != null && args.length > opti
12233                    && args[opti].charAt(0) != '-') {
12234                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12235                        = new ArrayList<ProcessCpuTracker.Stats>();
12236                updateCpuStatsNow();
12237                int findPid = -1;
12238                try {
12239                    findPid = Integer.parseInt(args[opti]);
12240                } catch (NumberFormatException e) {
12241                }
12242                synchronized (mProcessCpuThread) {
12243                    final int N = mProcessCpuTracker.countStats();
12244                    for (int i=0; i<N; i++) {
12245                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12246                        if (st.pid == findPid || (st.baseName != null
12247                                && st.baseName.equals(args[opti]))) {
12248                            nativeProcs.add(st);
12249                        }
12250                    }
12251                }
12252                if (nativeProcs.size() > 0) {
12253                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12254                            isCompact);
12255                    Debug.MemoryInfo mi = null;
12256                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12257                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12258                        final int pid = r.pid;
12259                        if (!isCheckinRequest && dumpDetails) {
12260                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12261                        }
12262                        if (mi == null) {
12263                            mi = new Debug.MemoryInfo();
12264                        }
12265                        if (dumpDetails || (!brief && !oomOnly)) {
12266                            Debug.getMemoryInfo(pid, mi);
12267                        } else {
12268                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12269                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12270                        }
12271                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12272                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12273                        if (isCheckinRequest) {
12274                            pw.println();
12275                        }
12276                    }
12277                    return;
12278                }
12279            }
12280            pw.println("No process found for: " + args[opti]);
12281            return;
12282        }
12283
12284        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12285            dumpDetails = true;
12286        }
12287
12288        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12289
12290        String[] innerArgs = new String[args.length-opti];
12291        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12292
12293        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12294        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12295        long nativePss=0, dalvikPss=0, otherPss=0;
12296        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12297
12298        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12299        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12300                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12301
12302        long totalPss = 0;
12303        long cachedPss = 0;
12304
12305        Debug.MemoryInfo mi = null;
12306        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12307            final ProcessRecord r = procs.get(i);
12308            final IApplicationThread thread;
12309            final int pid;
12310            final int oomAdj;
12311            final boolean hasActivities;
12312            synchronized (this) {
12313                thread = r.thread;
12314                pid = r.pid;
12315                oomAdj = r.getSetAdjWithServices();
12316                hasActivities = r.activities.size() > 0;
12317            }
12318            if (thread != null) {
12319                if (!isCheckinRequest && dumpDetails) {
12320                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12321                }
12322                if (mi == null) {
12323                    mi = new Debug.MemoryInfo();
12324                }
12325                if (dumpDetails || (!brief && !oomOnly)) {
12326                    Debug.getMemoryInfo(pid, mi);
12327                } else {
12328                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12329                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12330                }
12331                if (dumpDetails) {
12332                    if (localOnly) {
12333                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12334                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12335                        if (isCheckinRequest) {
12336                            pw.println();
12337                        }
12338                    } else {
12339                        try {
12340                            pw.flush();
12341                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12342                                    dumpDalvik, innerArgs);
12343                        } catch (RemoteException e) {
12344                            if (!isCheckinRequest) {
12345                                pw.println("Got RemoteException!");
12346                                pw.flush();
12347                            }
12348                        }
12349                    }
12350                }
12351
12352                final long myTotalPss = mi.getTotalPss();
12353                final long myTotalUss = mi.getTotalUss();
12354
12355                synchronized (this) {
12356                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12357                        // Record this for posterity if the process has been stable.
12358                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12359                    }
12360                }
12361
12362                if (!isCheckinRequest && mi != null) {
12363                    totalPss += myTotalPss;
12364                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12365                            (hasActivities ? " / activities)" : ")"),
12366                            r.processName, myTotalPss, pid, hasActivities);
12367                    procMems.add(pssItem);
12368                    procMemsMap.put(pid, pssItem);
12369
12370                    nativePss += mi.nativePss;
12371                    dalvikPss += mi.dalvikPss;
12372                    otherPss += mi.otherPss;
12373                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12374                        long mem = mi.getOtherPss(j);
12375                        miscPss[j] += mem;
12376                        otherPss -= mem;
12377                    }
12378
12379                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12380                        cachedPss += myTotalPss;
12381                    }
12382
12383                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12384                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12385                                || oomIndex == (oomPss.length-1)) {
12386                            oomPss[oomIndex] += myTotalPss;
12387                            if (oomProcs[oomIndex] == null) {
12388                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12389                            }
12390                            oomProcs[oomIndex].add(pssItem);
12391                            break;
12392                        }
12393                    }
12394                }
12395            }
12396        }
12397
12398        if (!isCheckinRequest && procs.size() > 1) {
12399            // If we are showing aggregations, also look for native processes to
12400            // include so that our aggregations are more accurate.
12401            updateCpuStatsNow();
12402            synchronized (mProcessCpuThread) {
12403                final int N = mProcessCpuTracker.countStats();
12404                for (int i=0; i<N; i++) {
12405                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12406                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12407                        if (mi == null) {
12408                            mi = new Debug.MemoryInfo();
12409                        }
12410                        if (!brief && !oomOnly) {
12411                            Debug.getMemoryInfo(st.pid, mi);
12412                        } else {
12413                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12414                            mi.nativePrivateDirty = (int)tmpLong[0];
12415                        }
12416
12417                        final long myTotalPss = mi.getTotalPss();
12418                        totalPss += myTotalPss;
12419
12420                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12421                                st.name, myTotalPss, st.pid, false);
12422                        procMems.add(pssItem);
12423
12424                        nativePss += mi.nativePss;
12425                        dalvikPss += mi.dalvikPss;
12426                        otherPss += mi.otherPss;
12427                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12428                            long mem = mi.getOtherPss(j);
12429                            miscPss[j] += mem;
12430                            otherPss -= mem;
12431                        }
12432                        oomPss[0] += myTotalPss;
12433                        if (oomProcs[0] == null) {
12434                            oomProcs[0] = new ArrayList<MemItem>();
12435                        }
12436                        oomProcs[0].add(pssItem);
12437                    }
12438                }
12439            }
12440
12441            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12442
12443            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12444            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12445            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12446            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12447                String label = Debug.MemoryInfo.getOtherLabel(j);
12448                catMems.add(new MemItem(label, label, miscPss[j], j));
12449            }
12450
12451            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12452            for (int j=0; j<oomPss.length; j++) {
12453                if (oomPss[j] != 0) {
12454                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12455                            : DUMP_MEM_OOM_LABEL[j];
12456                    MemItem item = new MemItem(label, label, oomPss[j],
12457                            DUMP_MEM_OOM_ADJ[j]);
12458                    item.subitems = oomProcs[j];
12459                    oomMems.add(item);
12460                }
12461            }
12462
12463            if (!brief && !oomOnly && !isCompact) {
12464                pw.println();
12465                pw.println("Total PSS by process:");
12466                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12467                pw.println();
12468            }
12469            if (!isCompact) {
12470                pw.println("Total PSS by OOM adjustment:");
12471            }
12472            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12473            if (!brief && !oomOnly) {
12474                PrintWriter out = categoryPw != null ? categoryPw : pw;
12475                if (!isCompact) {
12476                    out.println();
12477                    out.println("Total PSS by category:");
12478                }
12479                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12480            }
12481            if (!isCompact) {
12482                pw.println();
12483            }
12484            MemInfoReader memInfo = new MemInfoReader();
12485            memInfo.readMemInfo();
12486            if (!brief) {
12487                if (!isCompact) {
12488                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12489                    pw.print(" kB (status ");
12490                    switch (mLastMemoryLevel) {
12491                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12492                            pw.println("normal)");
12493                            break;
12494                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12495                            pw.println("moderate)");
12496                            break;
12497                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12498                            pw.println("low)");
12499                            break;
12500                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12501                            pw.println("critical)");
12502                            break;
12503                        default:
12504                            pw.print(mLastMemoryLevel);
12505                            pw.println(")");
12506                            break;
12507                    }
12508                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12509                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12510                            pw.print(cachedPss); pw.print(" cached pss + ");
12511                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12512                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12513                } else {
12514                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12515                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12516                            + memInfo.getFreeSizeKb()); pw.print(",");
12517                    pw.println(totalPss - cachedPss);
12518                }
12519            }
12520            if (!isCompact) {
12521                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12522                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12523                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12524                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12525                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12526                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12527                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12528                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12529                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12530                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12531                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12532            }
12533            if (!brief) {
12534                if (memInfo.getZramTotalSizeKb() != 0) {
12535                    if (!isCompact) {
12536                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12537                                pw.print(" kB physical used for ");
12538                                pw.print(memInfo.getSwapTotalSizeKb()
12539                                        - memInfo.getSwapFreeSizeKb());
12540                                pw.print(" kB in swap (");
12541                                pw.print(memInfo.getSwapTotalSizeKb());
12542                                pw.println(" kB total swap)");
12543                    } else {
12544                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12545                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12546                                pw.println(memInfo.getSwapFreeSizeKb());
12547                    }
12548                }
12549                final int[] SINGLE_LONG_FORMAT = new int[] {
12550                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12551                };
12552                long[] longOut = new long[1];
12553                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12554                        SINGLE_LONG_FORMAT, null, longOut, null);
12555                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12556                longOut[0] = 0;
12557                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12558                        SINGLE_LONG_FORMAT, null, longOut, null);
12559                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12560                longOut[0] = 0;
12561                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12562                        SINGLE_LONG_FORMAT, null, longOut, null);
12563                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12564                longOut[0] = 0;
12565                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12566                        SINGLE_LONG_FORMAT, null, longOut, null);
12567                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12568                if (!isCompact) {
12569                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12570                        pw.print("      KSM: "); pw.print(sharing);
12571                                pw.print(" kB saved from shared ");
12572                                pw.print(shared); pw.println(" kB");
12573                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12574                                pw.print(voltile); pw.println(" kB volatile");
12575                    }
12576                    pw.print("   Tuning: ");
12577                    pw.print(ActivityManager.staticGetMemoryClass());
12578                    pw.print(" (large ");
12579                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12580                    pw.print("), oom ");
12581                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12582                    pw.print(" kB");
12583                    pw.print(", restore limit ");
12584                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12585                    pw.print(" kB");
12586                    if (ActivityManager.isLowRamDeviceStatic()) {
12587                        pw.print(" (low-ram)");
12588                    }
12589                    if (ActivityManager.isHighEndGfx()) {
12590                        pw.print(" (high-end-gfx)");
12591                    }
12592                    pw.println();
12593                } else {
12594                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12595                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12596                    pw.println(voltile);
12597                    pw.print("tuning,");
12598                    pw.print(ActivityManager.staticGetMemoryClass());
12599                    pw.print(',');
12600                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12601                    pw.print(',');
12602                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12603                    if (ActivityManager.isLowRamDeviceStatic()) {
12604                        pw.print(",low-ram");
12605                    }
12606                    if (ActivityManager.isHighEndGfx()) {
12607                        pw.print(",high-end-gfx");
12608                    }
12609                    pw.println();
12610                }
12611            }
12612        }
12613    }
12614
12615    /**
12616     * Searches array of arguments for the specified string
12617     * @param args array of argument strings
12618     * @param value value to search for
12619     * @return true if the value is contained in the array
12620     */
12621    private static boolean scanArgs(String[] args, String value) {
12622        if (args != null) {
12623            for (String arg : args) {
12624                if (value.equals(arg)) {
12625                    return true;
12626                }
12627            }
12628        }
12629        return false;
12630    }
12631
12632    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12633            ContentProviderRecord cpr, boolean always) {
12634        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12635
12636        if (!inLaunching || always) {
12637            synchronized (cpr) {
12638                cpr.launchingApp = null;
12639                cpr.notifyAll();
12640            }
12641            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12642            String names[] = cpr.info.authority.split(";");
12643            for (int j = 0; j < names.length; j++) {
12644                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12645            }
12646        }
12647
12648        for (int i=0; i<cpr.connections.size(); i++) {
12649            ContentProviderConnection conn = cpr.connections.get(i);
12650            if (conn.waiting) {
12651                // If this connection is waiting for the provider, then we don't
12652                // need to mess with its process unless we are always removing
12653                // or for some reason the provider is not currently launching.
12654                if (inLaunching && !always) {
12655                    continue;
12656                }
12657            }
12658            ProcessRecord capp = conn.client;
12659            conn.dead = true;
12660            if (conn.stableCount > 0) {
12661                if (!capp.persistent && capp.thread != null
12662                        && capp.pid != 0
12663                        && capp.pid != MY_PID) {
12664                    killUnneededProcessLocked(capp, "depends on provider "
12665                            + cpr.name.flattenToShortString()
12666                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12667                }
12668            } else if (capp.thread != null && conn.provider.provider != null) {
12669                try {
12670                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12671                } catch (RemoteException e) {
12672                }
12673                // In the protocol here, we don't expect the client to correctly
12674                // clean up this connection, we'll just remove it.
12675                cpr.connections.remove(i);
12676                conn.client.conProviders.remove(conn);
12677            }
12678        }
12679
12680        if (inLaunching && always) {
12681            mLaunchingProviders.remove(cpr);
12682        }
12683        return inLaunching;
12684    }
12685
12686    /**
12687     * Main code for cleaning up a process when it has gone away.  This is
12688     * called both as a result of the process dying, or directly when stopping
12689     * a process when running in single process mode.
12690     */
12691    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12692            boolean restarting, boolean allowRestart, int index) {
12693        if (index >= 0) {
12694            removeLruProcessLocked(app);
12695            ProcessList.remove(app.pid);
12696        }
12697
12698        mProcessesToGc.remove(app);
12699        mPendingPssProcesses.remove(app);
12700
12701        // Dismiss any open dialogs.
12702        if (app.crashDialog != null && !app.forceCrashReport) {
12703            app.crashDialog.dismiss();
12704            app.crashDialog = null;
12705        }
12706        if (app.anrDialog != null) {
12707            app.anrDialog.dismiss();
12708            app.anrDialog = null;
12709        }
12710        if (app.waitDialog != null) {
12711            app.waitDialog.dismiss();
12712            app.waitDialog = null;
12713        }
12714
12715        app.crashing = false;
12716        app.notResponding = false;
12717
12718        app.resetPackageList(mProcessStats);
12719        app.unlinkDeathRecipient();
12720        app.makeInactive(mProcessStats);
12721        app.forcingToForeground = null;
12722        updateProcessForegroundLocked(app, false, false);
12723        app.foregroundActivities = false;
12724        app.hasShownUi = false;
12725        app.treatLikeActivity = false;
12726        app.hasAboveClient = false;
12727        app.hasClientActivities = false;
12728
12729        mServices.killServicesLocked(app, allowRestart);
12730
12731        boolean restart = false;
12732
12733        // Remove published content providers.
12734        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12735            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12736            final boolean always = app.bad || !allowRestart;
12737            if (removeDyingProviderLocked(app, cpr, always) || always) {
12738                // We left the provider in the launching list, need to
12739                // restart it.
12740                restart = true;
12741            }
12742
12743            cpr.provider = null;
12744            cpr.proc = null;
12745        }
12746        app.pubProviders.clear();
12747
12748        // Take care of any launching providers waiting for this process.
12749        if (checkAppInLaunchingProvidersLocked(app, false)) {
12750            restart = true;
12751        }
12752
12753        // Unregister from connected content providers.
12754        if (!app.conProviders.isEmpty()) {
12755            for (int i=0; i<app.conProviders.size(); i++) {
12756                ContentProviderConnection conn = app.conProviders.get(i);
12757                conn.provider.connections.remove(conn);
12758            }
12759            app.conProviders.clear();
12760        }
12761
12762        // At this point there may be remaining entries in mLaunchingProviders
12763        // where we were the only one waiting, so they are no longer of use.
12764        // Look for these and clean up if found.
12765        // XXX Commented out for now.  Trying to figure out a way to reproduce
12766        // the actual situation to identify what is actually going on.
12767        if (false) {
12768            for (int i=0; i<mLaunchingProviders.size(); i++) {
12769                ContentProviderRecord cpr = (ContentProviderRecord)
12770                        mLaunchingProviders.get(i);
12771                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12772                    synchronized (cpr) {
12773                        cpr.launchingApp = null;
12774                        cpr.notifyAll();
12775                    }
12776                }
12777            }
12778        }
12779
12780        skipCurrentReceiverLocked(app);
12781
12782        // Unregister any receivers.
12783        for (int i=app.receivers.size()-1; i>=0; i--) {
12784            removeReceiverLocked(app.receivers.valueAt(i));
12785        }
12786        app.receivers.clear();
12787
12788        // If the app is undergoing backup, tell the backup manager about it
12789        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12790            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12791                    + mBackupTarget.appInfo + " died during backup");
12792            try {
12793                IBackupManager bm = IBackupManager.Stub.asInterface(
12794                        ServiceManager.getService(Context.BACKUP_SERVICE));
12795                bm.agentDisconnected(app.info.packageName);
12796            } catch (RemoteException e) {
12797                // can't happen; backup manager is local
12798            }
12799        }
12800
12801        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12802            ProcessChangeItem item = mPendingProcessChanges.get(i);
12803            if (item.pid == app.pid) {
12804                mPendingProcessChanges.remove(i);
12805                mAvailProcessChanges.add(item);
12806            }
12807        }
12808        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12809
12810        // If the caller is restarting this app, then leave it in its
12811        // current lists and let the caller take care of it.
12812        if (restarting) {
12813            return;
12814        }
12815
12816        if (!app.persistent || app.isolated) {
12817            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12818                    "Removing non-persistent process during cleanup: " + app);
12819            mProcessNames.remove(app.processName, app.uid);
12820            mIsolatedProcesses.remove(app.uid);
12821            if (mHeavyWeightProcess == app) {
12822                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12823                        mHeavyWeightProcess.userId, 0));
12824                mHeavyWeightProcess = null;
12825            }
12826        } else if (!app.removed) {
12827            // This app is persistent, so we need to keep its record around.
12828            // If it is not already on the pending app list, add it there
12829            // and start a new process for it.
12830            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12831                mPersistentStartingProcesses.add(app);
12832                restart = true;
12833            }
12834        }
12835        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12836                "Clean-up removing on hold: " + app);
12837        mProcessesOnHold.remove(app);
12838
12839        if (app == mHomeProcess) {
12840            mHomeProcess = null;
12841        }
12842        if (app == mPreviousProcess) {
12843            mPreviousProcess = null;
12844        }
12845
12846        if (restart && !app.isolated) {
12847            // We have components that still need to be running in the
12848            // process, so re-launch it.
12849            mProcessNames.put(app.processName, app.uid, app);
12850            startProcessLocked(app, "restart", app.processName);
12851        } else if (app.pid > 0 && app.pid != MY_PID) {
12852            // Goodbye!
12853            boolean removed;
12854            synchronized (mPidsSelfLocked) {
12855                mPidsSelfLocked.remove(app.pid);
12856                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12857            }
12858            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12859                    app.processName, app.info.uid);
12860            if (app.isolated) {
12861                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12862            }
12863            app.setPid(0);
12864        }
12865    }
12866
12867    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12868        // Look through the content providers we are waiting to have launched,
12869        // and if any run in this process then either schedule a restart of
12870        // the process or kill the client waiting for it if this process has
12871        // gone bad.
12872        int NL = mLaunchingProviders.size();
12873        boolean restart = false;
12874        for (int i=0; i<NL; i++) {
12875            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12876            if (cpr.launchingApp == app) {
12877                if (!alwaysBad && !app.bad) {
12878                    restart = true;
12879                } else {
12880                    removeDyingProviderLocked(app, cpr, true);
12881                    // cpr should have been removed from mLaunchingProviders
12882                    NL = mLaunchingProviders.size();
12883                    i--;
12884                }
12885            }
12886        }
12887        return restart;
12888    }
12889
12890    // =========================================================
12891    // SERVICES
12892    // =========================================================
12893
12894    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12895            int flags) {
12896        enforceNotIsolatedCaller("getServices");
12897        synchronized (this) {
12898            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12899        }
12900    }
12901
12902    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12903        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12904        synchronized (this) {
12905            return mServices.getRunningServiceControlPanelLocked(name);
12906        }
12907    }
12908
12909    public ComponentName startService(IApplicationThread caller, Intent service,
12910            String resolvedType, int userId) {
12911        enforceNotIsolatedCaller("startService");
12912        // Refuse possible leaked file descriptors
12913        if (service != null && service.hasFileDescriptors() == true) {
12914            throw new IllegalArgumentException("File descriptors passed in Intent");
12915        }
12916
12917        if (DEBUG_SERVICE)
12918            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12919        synchronized(this) {
12920            final int callingPid = Binder.getCallingPid();
12921            final int callingUid = Binder.getCallingUid();
12922            final long origId = Binder.clearCallingIdentity();
12923            ComponentName res = mServices.startServiceLocked(caller, service,
12924                    resolvedType, callingPid, callingUid, userId);
12925            Binder.restoreCallingIdentity(origId);
12926            return res;
12927        }
12928    }
12929
12930    ComponentName startServiceInPackage(int uid,
12931            Intent service, String resolvedType, int userId) {
12932        synchronized(this) {
12933            if (DEBUG_SERVICE)
12934                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12935            final long origId = Binder.clearCallingIdentity();
12936            ComponentName res = mServices.startServiceLocked(null, service,
12937                    resolvedType, -1, uid, userId);
12938            Binder.restoreCallingIdentity(origId);
12939            return res;
12940        }
12941    }
12942
12943    public int stopService(IApplicationThread caller, Intent service,
12944            String resolvedType, int userId) {
12945        enforceNotIsolatedCaller("stopService");
12946        // Refuse possible leaked file descriptors
12947        if (service != null && service.hasFileDescriptors() == true) {
12948            throw new IllegalArgumentException("File descriptors passed in Intent");
12949        }
12950
12951        synchronized(this) {
12952            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12953        }
12954    }
12955
12956    public IBinder peekService(Intent service, String resolvedType) {
12957        enforceNotIsolatedCaller("peekService");
12958        // Refuse possible leaked file descriptors
12959        if (service != null && service.hasFileDescriptors() == true) {
12960            throw new IllegalArgumentException("File descriptors passed in Intent");
12961        }
12962        synchronized(this) {
12963            return mServices.peekServiceLocked(service, resolvedType);
12964        }
12965    }
12966
12967    public boolean stopServiceToken(ComponentName className, IBinder token,
12968            int startId) {
12969        synchronized(this) {
12970            return mServices.stopServiceTokenLocked(className, token, startId);
12971        }
12972    }
12973
12974    public void setServiceForeground(ComponentName className, IBinder token,
12975            int id, Notification notification, boolean removeNotification) {
12976        synchronized(this) {
12977            mServices.setServiceForegroundLocked(className, token, id, notification,
12978                    removeNotification);
12979        }
12980    }
12981
12982    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12983            boolean requireFull, String name, String callerPackage) {
12984        final int callingUserId = UserHandle.getUserId(callingUid);
12985        if (callingUserId != userId) {
12986            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12987                if ((requireFull || checkComponentPermission(
12988                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12989                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12990                        && checkComponentPermission(
12991                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12992                                callingPid, callingUid, -1, true)
12993                                != PackageManager.PERMISSION_GRANTED) {
12994                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12995                        // In this case, they would like to just execute as their
12996                        // owner user instead of failing.
12997                        userId = callingUserId;
12998                    } else {
12999                        StringBuilder builder = new StringBuilder(128);
13000                        builder.append("Permission Denial: ");
13001                        builder.append(name);
13002                        if (callerPackage != null) {
13003                            builder.append(" from ");
13004                            builder.append(callerPackage);
13005                        }
13006                        builder.append(" asks to run as user ");
13007                        builder.append(userId);
13008                        builder.append(" but is calling from user ");
13009                        builder.append(UserHandle.getUserId(callingUid));
13010                        builder.append("; this requires ");
13011                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13012                        if (!requireFull) {
13013                            builder.append(" or ");
13014                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13015                        }
13016                        String msg = builder.toString();
13017                        Slog.w(TAG, msg);
13018                        throw new SecurityException(msg);
13019                    }
13020                }
13021            }
13022            if (userId == UserHandle.USER_CURRENT
13023                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13024                // Note that we may be accessing this outside of a lock...
13025                // shouldn't be a big deal, if this is being called outside
13026                // of a locked context there is intrinsically a race with
13027                // the value the caller will receive and someone else changing it.
13028                userId = mCurrentUserId;
13029            }
13030            if (!allowAll && userId < 0) {
13031                throw new IllegalArgumentException(
13032                        "Call does not support special user #" + userId);
13033            }
13034        }
13035        return userId;
13036    }
13037
13038    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13039            String className, int flags) {
13040        boolean result = false;
13041        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13042            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13043                if (ActivityManager.checkUidPermission(
13044                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13045                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13046                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13047                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13048                            + " requests FLAG_SINGLE_USER, but app does not hold "
13049                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13050                    Slog.w(TAG, msg);
13051                    throw new SecurityException(msg);
13052                }
13053                result = true;
13054            }
13055        } else if (componentProcessName == aInfo.packageName) {
13056            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13057        } else if ("system".equals(componentProcessName)) {
13058            result = true;
13059        }
13060        if (DEBUG_MU) {
13061            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13062                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13063        }
13064        return result;
13065    }
13066
13067    public int bindService(IApplicationThread caller, IBinder token,
13068            Intent service, String resolvedType,
13069            IServiceConnection connection, int flags, int userId) {
13070        enforceNotIsolatedCaller("bindService");
13071        // Refuse possible leaked file descriptors
13072        if (service != null && service.hasFileDescriptors() == true) {
13073            throw new IllegalArgumentException("File descriptors passed in Intent");
13074        }
13075
13076        synchronized(this) {
13077            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13078                    connection, flags, userId);
13079        }
13080    }
13081
13082    public boolean unbindService(IServiceConnection connection) {
13083        synchronized (this) {
13084            return mServices.unbindServiceLocked(connection);
13085        }
13086    }
13087
13088    public void publishService(IBinder token, Intent intent, IBinder service) {
13089        // Refuse possible leaked file descriptors
13090        if (intent != null && intent.hasFileDescriptors() == true) {
13091            throw new IllegalArgumentException("File descriptors passed in Intent");
13092        }
13093
13094        synchronized(this) {
13095            if (!(token instanceof ServiceRecord)) {
13096                throw new IllegalArgumentException("Invalid service token");
13097            }
13098            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13099        }
13100    }
13101
13102    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13103        // Refuse possible leaked file descriptors
13104        if (intent != null && intent.hasFileDescriptors() == true) {
13105            throw new IllegalArgumentException("File descriptors passed in Intent");
13106        }
13107
13108        synchronized(this) {
13109            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13110        }
13111    }
13112
13113    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13114        synchronized(this) {
13115            if (!(token instanceof ServiceRecord)) {
13116                throw new IllegalArgumentException("Invalid service token");
13117            }
13118            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13119        }
13120    }
13121
13122    // =========================================================
13123    // BACKUP AND RESTORE
13124    // =========================================================
13125
13126    // Cause the target app to be launched if necessary and its backup agent
13127    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13128    // activity manager to announce its creation.
13129    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13130        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13131        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13132
13133        synchronized(this) {
13134            // !!! TODO: currently no check here that we're already bound
13135            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13136            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13137            synchronized (stats) {
13138                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13139            }
13140
13141            // Backup agent is now in use, its package can't be stopped.
13142            try {
13143                AppGlobals.getPackageManager().setPackageStoppedState(
13144                        app.packageName, false, UserHandle.getUserId(app.uid));
13145            } catch (RemoteException e) {
13146            } catch (IllegalArgumentException e) {
13147                Slog.w(TAG, "Failed trying to unstop package "
13148                        + app.packageName + ": " + e);
13149            }
13150
13151            BackupRecord r = new BackupRecord(ss, app, backupMode);
13152            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13153                    ? new ComponentName(app.packageName, app.backupAgentName)
13154                    : new ComponentName("android", "FullBackupAgent");
13155            // startProcessLocked() returns existing proc's record if it's already running
13156            ProcessRecord proc = startProcessLocked(app.processName, app,
13157                    false, 0, "backup", hostingName, false, false, false);
13158            if (proc == null) {
13159                Slog.e(TAG, "Unable to start backup agent process " + r);
13160                return false;
13161            }
13162
13163            r.app = proc;
13164            mBackupTarget = r;
13165            mBackupAppName = app.packageName;
13166
13167            // Try not to kill the process during backup
13168            updateOomAdjLocked(proc);
13169
13170            // If the process is already attached, schedule the creation of the backup agent now.
13171            // If it is not yet live, this will be done when it attaches to the framework.
13172            if (proc.thread != null) {
13173                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13174                try {
13175                    proc.thread.scheduleCreateBackupAgent(app,
13176                            compatibilityInfoForPackageLocked(app), backupMode);
13177                } catch (RemoteException e) {
13178                    // Will time out on the backup manager side
13179                }
13180            } else {
13181                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13182            }
13183            // Invariants: at this point, the target app process exists and the application
13184            // is either already running or in the process of coming up.  mBackupTarget and
13185            // mBackupAppName describe the app, so that when it binds back to the AM we
13186            // know that it's scheduled for a backup-agent operation.
13187        }
13188
13189        return true;
13190    }
13191
13192    @Override
13193    public void clearPendingBackup() {
13194        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13195        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13196
13197        synchronized (this) {
13198            mBackupTarget = null;
13199            mBackupAppName = null;
13200        }
13201    }
13202
13203    // A backup agent has just come up
13204    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13205        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13206                + " = " + agent);
13207
13208        synchronized(this) {
13209            if (!agentPackageName.equals(mBackupAppName)) {
13210                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13211                return;
13212            }
13213        }
13214
13215        long oldIdent = Binder.clearCallingIdentity();
13216        try {
13217            IBackupManager bm = IBackupManager.Stub.asInterface(
13218                    ServiceManager.getService(Context.BACKUP_SERVICE));
13219            bm.agentConnected(agentPackageName, agent);
13220        } catch (RemoteException e) {
13221            // can't happen; the backup manager service is local
13222        } catch (Exception e) {
13223            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13224            e.printStackTrace();
13225        } finally {
13226            Binder.restoreCallingIdentity(oldIdent);
13227        }
13228    }
13229
13230    // done with this agent
13231    public void unbindBackupAgent(ApplicationInfo appInfo) {
13232        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13233        if (appInfo == null) {
13234            Slog.w(TAG, "unbind backup agent for null app");
13235            return;
13236        }
13237
13238        synchronized(this) {
13239            try {
13240                if (mBackupAppName == null) {
13241                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13242                    return;
13243                }
13244
13245                if (!mBackupAppName.equals(appInfo.packageName)) {
13246                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13247                    return;
13248                }
13249
13250                // Not backing this app up any more; reset its OOM adjustment
13251                final ProcessRecord proc = mBackupTarget.app;
13252                updateOomAdjLocked(proc);
13253
13254                // If the app crashed during backup, 'thread' will be null here
13255                if (proc.thread != null) {
13256                    try {
13257                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13258                                compatibilityInfoForPackageLocked(appInfo));
13259                    } catch (Exception e) {
13260                        Slog.e(TAG, "Exception when unbinding backup agent:");
13261                        e.printStackTrace();
13262                    }
13263                }
13264            } finally {
13265                mBackupTarget = null;
13266                mBackupAppName = null;
13267            }
13268        }
13269    }
13270    // =========================================================
13271    // BROADCASTS
13272    // =========================================================
13273
13274    private final List getStickiesLocked(String action, IntentFilter filter,
13275            List cur, int userId) {
13276        final ContentResolver resolver = mContext.getContentResolver();
13277        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13278        if (stickies == null) {
13279            return cur;
13280        }
13281        final ArrayList<Intent> list = stickies.get(action);
13282        if (list == null) {
13283            return cur;
13284        }
13285        int N = list.size();
13286        for (int i=0; i<N; i++) {
13287            Intent intent = list.get(i);
13288            if (filter.match(resolver, intent, true, TAG) >= 0) {
13289                if (cur == null) {
13290                    cur = new ArrayList<Intent>();
13291                }
13292                cur.add(intent);
13293            }
13294        }
13295        return cur;
13296    }
13297
13298    boolean isPendingBroadcastProcessLocked(int pid) {
13299        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13300                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13301    }
13302
13303    void skipPendingBroadcastLocked(int pid) {
13304            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13305            for (BroadcastQueue queue : mBroadcastQueues) {
13306                queue.skipPendingBroadcastLocked(pid);
13307            }
13308    }
13309
13310    // The app just attached; send any pending broadcasts that it should receive
13311    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13312        boolean didSomething = false;
13313        for (BroadcastQueue queue : mBroadcastQueues) {
13314            didSomething |= queue.sendPendingBroadcastsLocked(app);
13315        }
13316        return didSomething;
13317    }
13318
13319    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13320            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13321        enforceNotIsolatedCaller("registerReceiver");
13322        int callingUid;
13323        int callingPid;
13324        synchronized(this) {
13325            ProcessRecord callerApp = null;
13326            if (caller != null) {
13327                callerApp = getRecordForAppLocked(caller);
13328                if (callerApp == null) {
13329                    throw new SecurityException(
13330                            "Unable to find app for caller " + caller
13331                            + " (pid=" + Binder.getCallingPid()
13332                            + ") when registering receiver " + receiver);
13333                }
13334                if (callerApp.info.uid != Process.SYSTEM_UID &&
13335                        !callerApp.pkgList.containsKey(callerPackage) &&
13336                        !"android".equals(callerPackage)) {
13337                    throw new SecurityException("Given caller package " + callerPackage
13338                            + " is not running in process " + callerApp);
13339                }
13340                callingUid = callerApp.info.uid;
13341                callingPid = callerApp.pid;
13342            } else {
13343                callerPackage = null;
13344                callingUid = Binder.getCallingUid();
13345                callingPid = Binder.getCallingPid();
13346            }
13347
13348            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13349                    true, true, "registerReceiver", callerPackage);
13350
13351            List allSticky = null;
13352
13353            // Look for any matching sticky broadcasts...
13354            Iterator actions = filter.actionsIterator();
13355            if (actions != null) {
13356                while (actions.hasNext()) {
13357                    String action = (String)actions.next();
13358                    allSticky = getStickiesLocked(action, filter, allSticky,
13359                            UserHandle.USER_ALL);
13360                    allSticky = getStickiesLocked(action, filter, allSticky,
13361                            UserHandle.getUserId(callingUid));
13362                }
13363            } else {
13364                allSticky = getStickiesLocked(null, filter, allSticky,
13365                        UserHandle.USER_ALL);
13366                allSticky = getStickiesLocked(null, filter, allSticky,
13367                        UserHandle.getUserId(callingUid));
13368            }
13369
13370            // The first sticky in the list is returned directly back to
13371            // the client.
13372            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13373
13374            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13375                    + ": " + sticky);
13376
13377            if (receiver == null) {
13378                return sticky;
13379            }
13380
13381            ReceiverList rl
13382                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13383            if (rl == null) {
13384                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13385                        userId, receiver);
13386                if (rl.app != null) {
13387                    rl.app.receivers.add(rl);
13388                } else {
13389                    try {
13390                        receiver.asBinder().linkToDeath(rl, 0);
13391                    } catch (RemoteException e) {
13392                        return sticky;
13393                    }
13394                    rl.linkedToDeath = true;
13395                }
13396                mRegisteredReceivers.put(receiver.asBinder(), rl);
13397            } else if (rl.uid != callingUid) {
13398                throw new IllegalArgumentException(
13399                        "Receiver requested to register for uid " + callingUid
13400                        + " was previously registered for uid " + rl.uid);
13401            } else if (rl.pid != callingPid) {
13402                throw new IllegalArgumentException(
13403                        "Receiver requested to register for pid " + callingPid
13404                        + " was previously registered for pid " + rl.pid);
13405            } else if (rl.userId != userId) {
13406                throw new IllegalArgumentException(
13407                        "Receiver requested to register for user " + userId
13408                        + " was previously registered for user " + rl.userId);
13409            }
13410            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13411                    permission, callingUid, userId);
13412            rl.add(bf);
13413            if (!bf.debugCheck()) {
13414                Slog.w(TAG, "==> For Dynamic broadast");
13415            }
13416            mReceiverResolver.addFilter(bf);
13417
13418            // Enqueue broadcasts for all existing stickies that match
13419            // this filter.
13420            if (allSticky != null) {
13421                ArrayList receivers = new ArrayList();
13422                receivers.add(bf);
13423
13424                int N = allSticky.size();
13425                for (int i=0; i<N; i++) {
13426                    Intent intent = (Intent)allSticky.get(i);
13427                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13428                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13429                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13430                            null, null, false, true, true, -1);
13431                    queue.enqueueParallelBroadcastLocked(r);
13432                    queue.scheduleBroadcastsLocked();
13433                }
13434            }
13435
13436            return sticky;
13437        }
13438    }
13439
13440    public void unregisterReceiver(IIntentReceiver receiver) {
13441        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13442
13443        final long origId = Binder.clearCallingIdentity();
13444        try {
13445            boolean doTrim = false;
13446
13447            synchronized(this) {
13448                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13449                if (rl != null) {
13450                    if (rl.curBroadcast != null) {
13451                        BroadcastRecord r = rl.curBroadcast;
13452                        final boolean doNext = finishReceiverLocked(
13453                                receiver.asBinder(), r.resultCode, r.resultData,
13454                                r.resultExtras, r.resultAbort);
13455                        if (doNext) {
13456                            doTrim = true;
13457                            r.queue.processNextBroadcast(false);
13458                        }
13459                    }
13460
13461                    if (rl.app != null) {
13462                        rl.app.receivers.remove(rl);
13463                    }
13464                    removeReceiverLocked(rl);
13465                    if (rl.linkedToDeath) {
13466                        rl.linkedToDeath = false;
13467                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13468                    }
13469                }
13470            }
13471
13472            // If we actually concluded any broadcasts, we might now be able
13473            // to trim the recipients' apps from our working set
13474            if (doTrim) {
13475                trimApplications();
13476                return;
13477            }
13478
13479        } finally {
13480            Binder.restoreCallingIdentity(origId);
13481        }
13482    }
13483
13484    void removeReceiverLocked(ReceiverList rl) {
13485        mRegisteredReceivers.remove(rl.receiver.asBinder());
13486        int N = rl.size();
13487        for (int i=0; i<N; i++) {
13488            mReceiverResolver.removeFilter(rl.get(i));
13489        }
13490    }
13491
13492    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13493        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13494            ProcessRecord r = mLruProcesses.get(i);
13495            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13496                try {
13497                    r.thread.dispatchPackageBroadcast(cmd, packages);
13498                } catch (RemoteException ex) {
13499                }
13500            }
13501        }
13502    }
13503
13504    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13505            int[] users) {
13506        List<ResolveInfo> receivers = null;
13507        try {
13508            HashSet<ComponentName> singleUserReceivers = null;
13509            boolean scannedFirstReceivers = false;
13510            for (int user : users) {
13511                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13512                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13513                if (user != 0 && newReceivers != null) {
13514                    // If this is not the primary user, we need to check for
13515                    // any receivers that should be filtered out.
13516                    for (int i=0; i<newReceivers.size(); i++) {
13517                        ResolveInfo ri = newReceivers.get(i);
13518                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13519                            newReceivers.remove(i);
13520                            i--;
13521                        }
13522                    }
13523                }
13524                if (newReceivers != null && newReceivers.size() == 0) {
13525                    newReceivers = null;
13526                }
13527                if (receivers == null) {
13528                    receivers = newReceivers;
13529                } else if (newReceivers != null) {
13530                    // We need to concatenate the additional receivers
13531                    // found with what we have do far.  This would be easy,
13532                    // but we also need to de-dup any receivers that are
13533                    // singleUser.
13534                    if (!scannedFirstReceivers) {
13535                        // Collect any single user receivers we had already retrieved.
13536                        scannedFirstReceivers = true;
13537                        for (int i=0; i<receivers.size(); i++) {
13538                            ResolveInfo ri = receivers.get(i);
13539                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13540                                ComponentName cn = new ComponentName(
13541                                        ri.activityInfo.packageName, ri.activityInfo.name);
13542                                if (singleUserReceivers == null) {
13543                                    singleUserReceivers = new HashSet<ComponentName>();
13544                                }
13545                                singleUserReceivers.add(cn);
13546                            }
13547                        }
13548                    }
13549                    // Add the new results to the existing results, tracking
13550                    // and de-dupping single user receivers.
13551                    for (int i=0; i<newReceivers.size(); i++) {
13552                        ResolveInfo ri = newReceivers.get(i);
13553                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13554                            ComponentName cn = new ComponentName(
13555                                    ri.activityInfo.packageName, ri.activityInfo.name);
13556                            if (singleUserReceivers == null) {
13557                                singleUserReceivers = new HashSet<ComponentName>();
13558                            }
13559                            if (!singleUserReceivers.contains(cn)) {
13560                                singleUserReceivers.add(cn);
13561                                receivers.add(ri);
13562                            }
13563                        } else {
13564                            receivers.add(ri);
13565                        }
13566                    }
13567                }
13568            }
13569        } catch (RemoteException ex) {
13570            // pm is in same process, this will never happen.
13571        }
13572        return receivers;
13573    }
13574
13575    private final int broadcastIntentLocked(ProcessRecord callerApp,
13576            String callerPackage, Intent intent, String resolvedType,
13577            IIntentReceiver resultTo, int resultCode, String resultData,
13578            Bundle map, String requiredPermission, int appOp,
13579            boolean ordered, boolean sticky, int callingPid, int callingUid,
13580            int userId) {
13581        intent = new Intent(intent);
13582
13583        // By default broadcasts do not go to stopped apps.
13584        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13585
13586        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13587            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13588            + " ordered=" + ordered + " userid=" + userId);
13589        if ((resultTo != null) && !ordered) {
13590            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13591        }
13592
13593        userId = handleIncomingUser(callingPid, callingUid, userId,
13594                true, false, "broadcast", callerPackage);
13595
13596        // Make sure that the user who is receiving this broadcast is started.
13597        // If not, we will just skip it.
13598        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13599            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13600                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13601                Slog.w(TAG, "Skipping broadcast of " + intent
13602                        + ": user " + userId + " is stopped");
13603                return ActivityManager.BROADCAST_SUCCESS;
13604            }
13605        }
13606
13607        /*
13608         * Prevent non-system code (defined here to be non-persistent
13609         * processes) from sending protected broadcasts.
13610         */
13611        int callingAppId = UserHandle.getAppId(callingUid);
13612        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13613            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13614            callingUid == 0) {
13615            // Always okay.
13616        } else if (callerApp == null || !callerApp.persistent) {
13617            try {
13618                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13619                        intent.getAction())) {
13620                    String msg = "Permission Denial: not allowed to send broadcast "
13621                            + intent.getAction() + " from pid="
13622                            + callingPid + ", uid=" + callingUid;
13623                    Slog.w(TAG, msg);
13624                    throw new SecurityException(msg);
13625                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13626                    // Special case for compatibility: we don't want apps to send this,
13627                    // but historically it has not been protected and apps may be using it
13628                    // to poke their own app widget.  So, instead of making it protected,
13629                    // just limit it to the caller.
13630                    if (callerApp == null) {
13631                        String msg = "Permission Denial: not allowed to send broadcast "
13632                                + intent.getAction() + " from unknown caller.";
13633                        Slog.w(TAG, msg);
13634                        throw new SecurityException(msg);
13635                    } else if (intent.getComponent() != null) {
13636                        // They are good enough to send to an explicit component...  verify
13637                        // it is being sent to the calling app.
13638                        if (!intent.getComponent().getPackageName().equals(
13639                                callerApp.info.packageName)) {
13640                            String msg = "Permission Denial: not allowed to send broadcast "
13641                                    + intent.getAction() + " to "
13642                                    + intent.getComponent().getPackageName() + " from "
13643                                    + callerApp.info.packageName;
13644                            Slog.w(TAG, msg);
13645                            throw new SecurityException(msg);
13646                        }
13647                    } else {
13648                        // Limit broadcast to their own package.
13649                        intent.setPackage(callerApp.info.packageName);
13650                    }
13651                }
13652            } catch (RemoteException e) {
13653                Slog.w(TAG, "Remote exception", e);
13654                return ActivityManager.BROADCAST_SUCCESS;
13655            }
13656        }
13657
13658        // Handle special intents: if this broadcast is from the package
13659        // manager about a package being removed, we need to remove all of
13660        // its activities from the history stack.
13661        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13662                intent.getAction());
13663        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13664                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13665                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13666                || uidRemoved) {
13667            if (checkComponentPermission(
13668                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13669                    callingPid, callingUid, -1, true)
13670                    == PackageManager.PERMISSION_GRANTED) {
13671                if (uidRemoved) {
13672                    final Bundle intentExtras = intent.getExtras();
13673                    final int uid = intentExtras != null
13674                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13675                    if (uid >= 0) {
13676                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13677                        synchronized (bs) {
13678                            bs.removeUidStatsLocked(uid);
13679                        }
13680                        mAppOpsService.uidRemoved(uid);
13681                    }
13682                } else {
13683                    // If resources are unavailable just force stop all
13684                    // those packages and flush the attribute cache as well.
13685                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13686                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13687                        if (list != null && (list.length > 0)) {
13688                            for (String pkg : list) {
13689                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13690                                        "storage unmount");
13691                            }
13692                            sendPackageBroadcastLocked(
13693                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13694                        }
13695                    } else {
13696                        Uri data = intent.getData();
13697                        String ssp;
13698                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13699                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13700                                    intent.getAction());
13701                            boolean fullUninstall = removed &&
13702                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13703                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13704                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13705                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13706                                        false, fullUninstall, userId,
13707                                        removed ? "pkg removed" : "pkg changed");
13708                            }
13709                            if (removed) {
13710                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13711                                        new String[] {ssp}, userId);
13712                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13713                                    mAppOpsService.packageRemoved(
13714                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13715
13716                                    // Remove all permissions granted from/to this package
13717                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13718                                }
13719                            }
13720                        }
13721                    }
13722                }
13723            } else {
13724                String msg = "Permission Denial: " + intent.getAction()
13725                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13726                        + ", uid=" + callingUid + ")"
13727                        + " requires "
13728                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13729                Slog.w(TAG, msg);
13730                throw new SecurityException(msg);
13731            }
13732
13733        // Special case for adding a package: by default turn on compatibility
13734        // mode.
13735        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13736            Uri data = intent.getData();
13737            String ssp;
13738            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13739                mCompatModePackages.handlePackageAddedLocked(ssp,
13740                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13741            }
13742        }
13743
13744        /*
13745         * If this is the time zone changed action, queue up a message that will reset the timezone
13746         * of all currently running processes. This message will get queued up before the broadcast
13747         * happens.
13748         */
13749        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13750            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13751        }
13752
13753        /*
13754         * If the user set the time, let all running processes know.
13755         */
13756        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13757            final int is24Hour = intent.getBooleanExtra(
13758                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13759            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13760        }
13761
13762        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13763            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13764        }
13765
13766        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13767            ProxyInfo proxy = intent.getParcelableExtra("proxy");
13768            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13769        }
13770
13771        // Add to the sticky list if requested.
13772        if (sticky) {
13773            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13774                    callingPid, callingUid)
13775                    != PackageManager.PERMISSION_GRANTED) {
13776                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13777                        + callingPid + ", uid=" + callingUid
13778                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13779                Slog.w(TAG, msg);
13780                throw new SecurityException(msg);
13781            }
13782            if (requiredPermission != null) {
13783                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13784                        + " and enforce permission " + requiredPermission);
13785                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13786            }
13787            if (intent.getComponent() != null) {
13788                throw new SecurityException(
13789                        "Sticky broadcasts can't target a specific component");
13790            }
13791            // We use userId directly here, since the "all" target is maintained
13792            // as a separate set of sticky broadcasts.
13793            if (userId != UserHandle.USER_ALL) {
13794                // But first, if this is not a broadcast to all users, then
13795                // make sure it doesn't conflict with an existing broadcast to
13796                // all users.
13797                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13798                        UserHandle.USER_ALL);
13799                if (stickies != null) {
13800                    ArrayList<Intent> list = stickies.get(intent.getAction());
13801                    if (list != null) {
13802                        int N = list.size();
13803                        int i;
13804                        for (i=0; i<N; i++) {
13805                            if (intent.filterEquals(list.get(i))) {
13806                                throw new IllegalArgumentException(
13807                                        "Sticky broadcast " + intent + " for user "
13808                                        + userId + " conflicts with existing global broadcast");
13809                            }
13810                        }
13811                    }
13812                }
13813            }
13814            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13815            if (stickies == null) {
13816                stickies = new ArrayMap<String, ArrayList<Intent>>();
13817                mStickyBroadcasts.put(userId, stickies);
13818            }
13819            ArrayList<Intent> list = stickies.get(intent.getAction());
13820            if (list == null) {
13821                list = new ArrayList<Intent>();
13822                stickies.put(intent.getAction(), list);
13823            }
13824            int N = list.size();
13825            int i;
13826            for (i=0; i<N; i++) {
13827                if (intent.filterEquals(list.get(i))) {
13828                    // This sticky already exists, replace it.
13829                    list.set(i, new Intent(intent));
13830                    break;
13831                }
13832            }
13833            if (i >= N) {
13834                list.add(new Intent(intent));
13835            }
13836        }
13837
13838        int[] users;
13839        if (userId == UserHandle.USER_ALL) {
13840            // Caller wants broadcast to go to all started users.
13841            users = mStartedUserArray;
13842        } else {
13843            // Caller wants broadcast to go to one specific user.
13844            users = new int[] {userId};
13845        }
13846
13847        // Figure out who all will receive this broadcast.
13848        List receivers = null;
13849        List<BroadcastFilter> registeredReceivers = null;
13850        // Need to resolve the intent to interested receivers...
13851        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13852                 == 0) {
13853            receivers = collectReceiverComponents(intent, resolvedType, users);
13854        }
13855        if (intent.getComponent() == null) {
13856            registeredReceivers = mReceiverResolver.queryIntent(intent,
13857                    resolvedType, false, userId);
13858        }
13859
13860        final boolean replacePending =
13861                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13862
13863        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13864                + " replacePending=" + replacePending);
13865
13866        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13867        if (!ordered && NR > 0) {
13868            // If we are not serializing this broadcast, then send the
13869            // registered receivers separately so they don't wait for the
13870            // components to be launched.
13871            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13872            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13873                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13874                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13875                    ordered, sticky, false, userId);
13876            if (DEBUG_BROADCAST) Slog.v(
13877                    TAG, "Enqueueing parallel broadcast " + r);
13878            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13879            if (!replaced) {
13880                queue.enqueueParallelBroadcastLocked(r);
13881                queue.scheduleBroadcastsLocked();
13882            }
13883            registeredReceivers = null;
13884            NR = 0;
13885        }
13886
13887        // Merge into one list.
13888        int ir = 0;
13889        if (receivers != null) {
13890            // A special case for PACKAGE_ADDED: do not allow the package
13891            // being added to see this broadcast.  This prevents them from
13892            // using this as a back door to get run as soon as they are
13893            // installed.  Maybe in the future we want to have a special install
13894            // broadcast or such for apps, but we'd like to deliberately make
13895            // this decision.
13896            String skipPackages[] = null;
13897            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13898                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13899                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13900                Uri data = intent.getData();
13901                if (data != null) {
13902                    String pkgName = data.getSchemeSpecificPart();
13903                    if (pkgName != null) {
13904                        skipPackages = new String[] { pkgName };
13905                    }
13906                }
13907            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13908                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13909            }
13910            if (skipPackages != null && (skipPackages.length > 0)) {
13911                for (String skipPackage : skipPackages) {
13912                    if (skipPackage != null) {
13913                        int NT = receivers.size();
13914                        for (int it=0; it<NT; it++) {
13915                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13916                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13917                                receivers.remove(it);
13918                                it--;
13919                                NT--;
13920                            }
13921                        }
13922                    }
13923                }
13924            }
13925
13926            int NT = receivers != null ? receivers.size() : 0;
13927            int it = 0;
13928            ResolveInfo curt = null;
13929            BroadcastFilter curr = null;
13930            while (it < NT && ir < NR) {
13931                if (curt == null) {
13932                    curt = (ResolveInfo)receivers.get(it);
13933                }
13934                if (curr == null) {
13935                    curr = registeredReceivers.get(ir);
13936                }
13937                if (curr.getPriority() >= curt.priority) {
13938                    // Insert this broadcast record into the final list.
13939                    receivers.add(it, curr);
13940                    ir++;
13941                    curr = null;
13942                    it++;
13943                    NT++;
13944                } else {
13945                    // Skip to the next ResolveInfo in the final list.
13946                    it++;
13947                    curt = null;
13948                }
13949            }
13950        }
13951        while (ir < NR) {
13952            if (receivers == null) {
13953                receivers = new ArrayList();
13954            }
13955            receivers.add(registeredReceivers.get(ir));
13956            ir++;
13957        }
13958
13959        if ((receivers != null && receivers.size() > 0)
13960                || resultTo != null) {
13961            BroadcastQueue queue = broadcastQueueForIntent(intent);
13962            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13963                    callerPackage, callingPid, callingUid, resolvedType,
13964                    requiredPermission, appOp, receivers, resultTo, resultCode,
13965                    resultData, map, ordered, sticky, false, userId);
13966            if (DEBUG_BROADCAST) Slog.v(
13967                    TAG, "Enqueueing ordered broadcast " + r
13968                    + ": prev had " + queue.mOrderedBroadcasts.size());
13969            if (DEBUG_BROADCAST) {
13970                int seq = r.intent.getIntExtra("seq", -1);
13971                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13972            }
13973            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13974            if (!replaced) {
13975                queue.enqueueOrderedBroadcastLocked(r);
13976                queue.scheduleBroadcastsLocked();
13977            }
13978        }
13979
13980        return ActivityManager.BROADCAST_SUCCESS;
13981    }
13982
13983    final Intent verifyBroadcastLocked(Intent intent) {
13984        // Refuse possible leaked file descriptors
13985        if (intent != null && intent.hasFileDescriptors() == true) {
13986            throw new IllegalArgumentException("File descriptors passed in Intent");
13987        }
13988
13989        int flags = intent.getFlags();
13990
13991        if (!mProcessesReady) {
13992            // if the caller really truly claims to know what they're doing, go
13993            // ahead and allow the broadcast without launching any receivers
13994            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13995                intent = new Intent(intent);
13996                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13997            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13998                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13999                        + " before boot completion");
14000                throw new IllegalStateException("Cannot broadcast before boot completed");
14001            }
14002        }
14003
14004        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14005            throw new IllegalArgumentException(
14006                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14007        }
14008
14009        return intent;
14010    }
14011
14012    public final int broadcastIntent(IApplicationThread caller,
14013            Intent intent, String resolvedType, IIntentReceiver resultTo,
14014            int resultCode, String resultData, Bundle map,
14015            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14016        enforceNotIsolatedCaller("broadcastIntent");
14017        synchronized(this) {
14018            intent = verifyBroadcastLocked(intent);
14019
14020            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14021            final int callingPid = Binder.getCallingPid();
14022            final int callingUid = Binder.getCallingUid();
14023            final long origId = Binder.clearCallingIdentity();
14024            int res = broadcastIntentLocked(callerApp,
14025                    callerApp != null ? callerApp.info.packageName : null,
14026                    intent, resolvedType, resultTo,
14027                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14028                    callingPid, callingUid, userId);
14029            Binder.restoreCallingIdentity(origId);
14030            return res;
14031        }
14032    }
14033
14034    int broadcastIntentInPackage(String packageName, int uid,
14035            Intent intent, String resolvedType, IIntentReceiver resultTo,
14036            int resultCode, String resultData, Bundle map,
14037            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14038        synchronized(this) {
14039            intent = verifyBroadcastLocked(intent);
14040
14041            final long origId = Binder.clearCallingIdentity();
14042            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14043                    resultTo, resultCode, resultData, map, requiredPermission,
14044                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14045            Binder.restoreCallingIdentity(origId);
14046            return res;
14047        }
14048    }
14049
14050    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14051        // Refuse possible leaked file descriptors
14052        if (intent != null && intent.hasFileDescriptors() == true) {
14053            throw new IllegalArgumentException("File descriptors passed in Intent");
14054        }
14055
14056        userId = handleIncomingUser(Binder.getCallingPid(),
14057                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14058
14059        synchronized(this) {
14060            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14061                    != PackageManager.PERMISSION_GRANTED) {
14062                String msg = "Permission Denial: unbroadcastIntent() from pid="
14063                        + Binder.getCallingPid()
14064                        + ", uid=" + Binder.getCallingUid()
14065                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14066                Slog.w(TAG, msg);
14067                throw new SecurityException(msg);
14068            }
14069            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14070            if (stickies != null) {
14071                ArrayList<Intent> list = stickies.get(intent.getAction());
14072                if (list != null) {
14073                    int N = list.size();
14074                    int i;
14075                    for (i=0; i<N; i++) {
14076                        if (intent.filterEquals(list.get(i))) {
14077                            list.remove(i);
14078                            break;
14079                        }
14080                    }
14081                    if (list.size() <= 0) {
14082                        stickies.remove(intent.getAction());
14083                    }
14084                }
14085                if (stickies.size() <= 0) {
14086                    mStickyBroadcasts.remove(userId);
14087                }
14088            }
14089        }
14090    }
14091
14092    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14093            String resultData, Bundle resultExtras, boolean resultAbort) {
14094        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14095        if (r == null) {
14096            Slog.w(TAG, "finishReceiver called but not found on queue");
14097            return false;
14098        }
14099
14100        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14101    }
14102
14103    void backgroundServicesFinishedLocked(int userId) {
14104        for (BroadcastQueue queue : mBroadcastQueues) {
14105            queue.backgroundServicesFinishedLocked(userId);
14106        }
14107    }
14108
14109    public void finishReceiver(IBinder who, int resultCode, String resultData,
14110            Bundle resultExtras, boolean resultAbort) {
14111        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14112
14113        // Refuse possible leaked file descriptors
14114        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14115            throw new IllegalArgumentException("File descriptors passed in Bundle");
14116        }
14117
14118        final long origId = Binder.clearCallingIdentity();
14119        try {
14120            boolean doNext = false;
14121            BroadcastRecord r;
14122
14123            synchronized(this) {
14124                r = broadcastRecordForReceiverLocked(who);
14125                if (r != null) {
14126                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14127                        resultData, resultExtras, resultAbort, true);
14128                }
14129            }
14130
14131            if (doNext) {
14132                r.queue.processNextBroadcast(false);
14133            }
14134            trimApplications();
14135        } finally {
14136            Binder.restoreCallingIdentity(origId);
14137        }
14138    }
14139
14140    // =========================================================
14141    // INSTRUMENTATION
14142    // =========================================================
14143
14144    public boolean startInstrumentation(ComponentName className,
14145            String profileFile, int flags, Bundle arguments,
14146            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14147            int userId) {
14148        enforceNotIsolatedCaller("startInstrumentation");
14149        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14150                userId, false, true, "startInstrumentation", null);
14151        // Refuse possible leaked file descriptors
14152        if (arguments != null && arguments.hasFileDescriptors()) {
14153            throw new IllegalArgumentException("File descriptors passed in Bundle");
14154        }
14155
14156        synchronized(this) {
14157            InstrumentationInfo ii = null;
14158            ApplicationInfo ai = null;
14159            try {
14160                ii = mContext.getPackageManager().getInstrumentationInfo(
14161                    className, STOCK_PM_FLAGS);
14162                ai = AppGlobals.getPackageManager().getApplicationInfo(
14163                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14164            } catch (PackageManager.NameNotFoundException e) {
14165            } catch (RemoteException e) {
14166            }
14167            if (ii == null) {
14168                reportStartInstrumentationFailure(watcher, className,
14169                        "Unable to find instrumentation info for: " + className);
14170                return false;
14171            }
14172            if (ai == null) {
14173                reportStartInstrumentationFailure(watcher, className,
14174                        "Unable to find instrumentation target package: " + ii.targetPackage);
14175                return false;
14176            }
14177
14178            int match = mContext.getPackageManager().checkSignatures(
14179                    ii.targetPackage, ii.packageName);
14180            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14181                String msg = "Permission Denial: starting instrumentation "
14182                        + className + " from pid="
14183                        + Binder.getCallingPid()
14184                        + ", uid=" + Binder.getCallingPid()
14185                        + " not allowed because package " + ii.packageName
14186                        + " does not have a signature matching the target "
14187                        + ii.targetPackage;
14188                reportStartInstrumentationFailure(watcher, className, msg);
14189                throw new SecurityException(msg);
14190            }
14191
14192            final long origId = Binder.clearCallingIdentity();
14193            // Instrumentation can kill and relaunch even persistent processes
14194            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14195                    "start instr");
14196            ProcessRecord app = addAppLocked(ai, false);
14197            app.instrumentationClass = className;
14198            app.instrumentationInfo = ai;
14199            app.instrumentationProfileFile = profileFile;
14200            app.instrumentationArguments = arguments;
14201            app.instrumentationWatcher = watcher;
14202            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14203            app.instrumentationResultClass = className;
14204            Binder.restoreCallingIdentity(origId);
14205        }
14206
14207        return true;
14208    }
14209
14210    /**
14211     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14212     * error to the logs, but if somebody is watching, send the report there too.  This enables
14213     * the "am" command to report errors with more information.
14214     *
14215     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14216     * @param cn The component name of the instrumentation.
14217     * @param report The error report.
14218     */
14219    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14220            ComponentName cn, String report) {
14221        Slog.w(TAG, report);
14222        try {
14223            if (watcher != null) {
14224                Bundle results = new Bundle();
14225                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14226                results.putString("Error", report);
14227                watcher.instrumentationStatus(cn, -1, results);
14228            }
14229        } catch (RemoteException e) {
14230            Slog.w(TAG, e);
14231        }
14232    }
14233
14234    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14235        if (app.instrumentationWatcher != null) {
14236            try {
14237                // NOTE:  IInstrumentationWatcher *must* be oneway here
14238                app.instrumentationWatcher.instrumentationFinished(
14239                    app.instrumentationClass,
14240                    resultCode,
14241                    results);
14242            } catch (RemoteException e) {
14243            }
14244        }
14245        if (app.instrumentationUiAutomationConnection != null) {
14246            try {
14247                app.instrumentationUiAutomationConnection.shutdown();
14248            } catch (RemoteException re) {
14249                /* ignore */
14250            }
14251            // Only a UiAutomation can set this flag and now that
14252            // it is finished we make sure it is reset to its default.
14253            mUserIsMonkey = false;
14254        }
14255        app.instrumentationWatcher = null;
14256        app.instrumentationUiAutomationConnection = null;
14257        app.instrumentationClass = null;
14258        app.instrumentationInfo = null;
14259        app.instrumentationProfileFile = null;
14260        app.instrumentationArguments = null;
14261
14262        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14263                "finished inst");
14264    }
14265
14266    public void finishInstrumentation(IApplicationThread target,
14267            int resultCode, Bundle results) {
14268        int userId = UserHandle.getCallingUserId();
14269        // Refuse possible leaked file descriptors
14270        if (results != null && results.hasFileDescriptors()) {
14271            throw new IllegalArgumentException("File descriptors passed in Intent");
14272        }
14273
14274        synchronized(this) {
14275            ProcessRecord app = getRecordForAppLocked(target);
14276            if (app == null) {
14277                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14278                return;
14279            }
14280            final long origId = Binder.clearCallingIdentity();
14281            finishInstrumentationLocked(app, resultCode, results);
14282            Binder.restoreCallingIdentity(origId);
14283        }
14284    }
14285
14286    // =========================================================
14287    // CONFIGURATION
14288    // =========================================================
14289
14290    public ConfigurationInfo getDeviceConfigurationInfo() {
14291        ConfigurationInfo config = new ConfigurationInfo();
14292        synchronized (this) {
14293            config.reqTouchScreen = mConfiguration.touchscreen;
14294            config.reqKeyboardType = mConfiguration.keyboard;
14295            config.reqNavigation = mConfiguration.navigation;
14296            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14297                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14298                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14299            }
14300            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14301                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14302                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14303            }
14304            config.reqGlEsVersion = GL_ES_VERSION;
14305        }
14306        return config;
14307    }
14308
14309    ActivityStack getFocusedStack() {
14310        return mStackSupervisor.getFocusedStack();
14311    }
14312
14313    public Configuration getConfiguration() {
14314        Configuration ci;
14315        synchronized(this) {
14316            ci = new Configuration(mConfiguration);
14317        }
14318        return ci;
14319    }
14320
14321    public void updatePersistentConfiguration(Configuration values) {
14322        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14323                "updateConfiguration()");
14324        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14325                "updateConfiguration()");
14326        if (values == null) {
14327            throw new NullPointerException("Configuration must not be null");
14328        }
14329
14330        synchronized(this) {
14331            final long origId = Binder.clearCallingIdentity();
14332            updateConfigurationLocked(values, null, true, false);
14333            Binder.restoreCallingIdentity(origId);
14334        }
14335    }
14336
14337    public void updateConfiguration(Configuration values) {
14338        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14339                "updateConfiguration()");
14340
14341        synchronized(this) {
14342            if (values == null && mWindowManager != null) {
14343                // sentinel: fetch the current configuration from the window manager
14344                values = mWindowManager.computeNewConfiguration();
14345            }
14346
14347            if (mWindowManager != null) {
14348                mProcessList.applyDisplaySize(mWindowManager);
14349            }
14350
14351            final long origId = Binder.clearCallingIdentity();
14352            if (values != null) {
14353                Settings.System.clearConfiguration(values);
14354            }
14355            updateConfigurationLocked(values, null, false, false);
14356            Binder.restoreCallingIdentity(origId);
14357        }
14358    }
14359
14360    /**
14361     * Do either or both things: (1) change the current configuration, and (2)
14362     * make sure the given activity is running with the (now) current
14363     * configuration.  Returns true if the activity has been left running, or
14364     * false if <var>starting</var> is being destroyed to match the new
14365     * configuration.
14366     * @param persistent TODO
14367     */
14368    boolean updateConfigurationLocked(Configuration values,
14369            ActivityRecord starting, boolean persistent, boolean initLocale) {
14370        int changes = 0;
14371
14372        if (values != null) {
14373            Configuration newConfig = new Configuration(mConfiguration);
14374            changes = newConfig.updateFrom(values);
14375            if (changes != 0) {
14376                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14377                    Slog.i(TAG, "Updating configuration to: " + values);
14378                }
14379
14380                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14381
14382                if (values.locale != null && !initLocale) {
14383                    saveLocaleLocked(values.locale,
14384                                     !values.locale.equals(mConfiguration.locale),
14385                                     values.userSetLocale);
14386                }
14387
14388                mConfigurationSeq++;
14389                if (mConfigurationSeq <= 0) {
14390                    mConfigurationSeq = 1;
14391                }
14392                newConfig.seq = mConfigurationSeq;
14393                mConfiguration = newConfig;
14394                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14395                mUsageStatsService.noteStartConfig(newConfig);
14396
14397                final Configuration configCopy = new Configuration(mConfiguration);
14398
14399                // TODO: If our config changes, should we auto dismiss any currently
14400                // showing dialogs?
14401                mShowDialogs = shouldShowDialogs(newConfig);
14402
14403                AttributeCache ac = AttributeCache.instance();
14404                if (ac != null) {
14405                    ac.updateConfiguration(configCopy);
14406                }
14407
14408                // Make sure all resources in our process are updated
14409                // right now, so that anyone who is going to retrieve
14410                // resource values after we return will be sure to get
14411                // the new ones.  This is especially important during
14412                // boot, where the first config change needs to guarantee
14413                // all resources have that config before following boot
14414                // code is executed.
14415                mSystemThread.applyConfigurationToResources(configCopy);
14416
14417                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14418                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14419                    msg.obj = new Configuration(configCopy);
14420                    mHandler.sendMessage(msg);
14421                }
14422
14423                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14424                    ProcessRecord app = mLruProcesses.get(i);
14425                    try {
14426                        if (app.thread != null) {
14427                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14428                                    + app.processName + " new config " + mConfiguration);
14429                            app.thread.scheduleConfigurationChanged(configCopy);
14430                        }
14431                    } catch (Exception e) {
14432                    }
14433                }
14434                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14435                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14436                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14437                        | Intent.FLAG_RECEIVER_FOREGROUND);
14438                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14439                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14440                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14441                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14442                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14443                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14444                    broadcastIntentLocked(null, null, intent,
14445                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14446                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14447                }
14448            }
14449        }
14450
14451        boolean kept = true;
14452        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14453        // mainStack is null during startup.
14454        if (mainStack != null) {
14455            if (changes != 0 && starting == null) {
14456                // If the configuration changed, and the caller is not already
14457                // in the process of starting an activity, then find the top
14458                // activity to check if its configuration needs to change.
14459                starting = mainStack.topRunningActivityLocked(null);
14460            }
14461
14462            if (starting != null) {
14463                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14464                // And we need to make sure at this point that all other activities
14465                // are made visible with the correct configuration.
14466                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14467            }
14468        }
14469
14470        if (values != null && mWindowManager != null) {
14471            mWindowManager.setNewConfiguration(mConfiguration);
14472        }
14473
14474        return kept;
14475    }
14476
14477    /**
14478     * Decide based on the configuration whether we should shouw the ANR,
14479     * crash, etc dialogs.  The idea is that if there is no affordnace to
14480     * press the on-screen buttons, we shouldn't show the dialog.
14481     *
14482     * A thought: SystemUI might also want to get told about this, the Power
14483     * dialog / global actions also might want different behaviors.
14484     */
14485    private static final boolean shouldShowDialogs(Configuration config) {
14486        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14487                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14488    }
14489
14490    /**
14491     * Save the locale.  You must be inside a synchronized (this) block.
14492     */
14493    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14494        if(isDiff) {
14495            SystemProperties.set("user.language", l.getLanguage());
14496            SystemProperties.set("user.region", l.getCountry());
14497        }
14498
14499        if(isPersist) {
14500            SystemProperties.set("persist.sys.language", l.getLanguage());
14501            SystemProperties.set("persist.sys.country", l.getCountry());
14502            SystemProperties.set("persist.sys.localevar", l.getVariant());
14503        }
14504    }
14505
14506    @Override
14507    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14508        ActivityRecord srec = ActivityRecord.forToken(token);
14509        return srec != null && srec.task.affinity != null &&
14510                srec.task.affinity.equals(destAffinity);
14511    }
14512
14513    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14514            Intent resultData) {
14515
14516        synchronized (this) {
14517            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14518            if (stack != null) {
14519                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14520            }
14521            return false;
14522        }
14523    }
14524
14525    public int getLaunchedFromUid(IBinder activityToken) {
14526        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14527        if (srec == null) {
14528            return -1;
14529        }
14530        return srec.launchedFromUid;
14531    }
14532
14533    public String getLaunchedFromPackage(IBinder activityToken) {
14534        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14535        if (srec == null) {
14536            return null;
14537        }
14538        return srec.launchedFromPackage;
14539    }
14540
14541    // =========================================================
14542    // LIFETIME MANAGEMENT
14543    // =========================================================
14544
14545    // Returns which broadcast queue the app is the current [or imminent] receiver
14546    // on, or 'null' if the app is not an active broadcast recipient.
14547    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14548        BroadcastRecord r = app.curReceiver;
14549        if (r != null) {
14550            return r.queue;
14551        }
14552
14553        // It's not the current receiver, but it might be starting up to become one
14554        synchronized (this) {
14555            for (BroadcastQueue queue : mBroadcastQueues) {
14556                r = queue.mPendingBroadcast;
14557                if (r != null && r.curApp == app) {
14558                    // found it; report which queue it's in
14559                    return queue;
14560                }
14561            }
14562        }
14563
14564        return null;
14565    }
14566
14567    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14568            boolean doingAll, long now) {
14569        if (mAdjSeq == app.adjSeq) {
14570            // This adjustment has already been computed.
14571            return app.curRawAdj;
14572        }
14573
14574        if (app.thread == null) {
14575            app.adjSeq = mAdjSeq;
14576            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14577            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14578            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14579        }
14580
14581        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14582        app.adjSource = null;
14583        app.adjTarget = null;
14584        app.empty = false;
14585        app.cached = false;
14586
14587        final int activitiesSize = app.activities.size();
14588
14589        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14590            // The max adjustment doesn't allow this app to be anything
14591            // below foreground, so it is not worth doing work for it.
14592            app.adjType = "fixed";
14593            app.adjSeq = mAdjSeq;
14594            app.curRawAdj = app.maxAdj;
14595            app.foregroundActivities = false;
14596            app.keeping = true;
14597            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14598            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14599            // System processes can do UI, and when they do we want to have
14600            // them trim their memory after the user leaves the UI.  To
14601            // facilitate this, here we need to determine whether or not it
14602            // is currently showing UI.
14603            app.systemNoUi = true;
14604            if (app == TOP_APP) {
14605                app.systemNoUi = false;
14606            } else if (activitiesSize > 0) {
14607                for (int j = 0; j < activitiesSize; j++) {
14608                    final ActivityRecord r = app.activities.get(j);
14609                    if (r.visible) {
14610                        app.systemNoUi = false;
14611                    }
14612                }
14613            }
14614            if (!app.systemNoUi) {
14615                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14616            }
14617            return (app.curAdj=app.maxAdj);
14618        }
14619
14620        app.keeping = false;
14621        app.systemNoUi = false;
14622
14623        // Determine the importance of the process, starting with most
14624        // important to least, and assign an appropriate OOM adjustment.
14625        int adj;
14626        int schedGroup;
14627        int procState;
14628        boolean foregroundActivities = false;
14629        boolean interesting = false;
14630        BroadcastQueue queue;
14631        if (app == TOP_APP) {
14632            // The last app on the list is the foreground app.
14633            adj = ProcessList.FOREGROUND_APP_ADJ;
14634            schedGroup = Process.THREAD_GROUP_DEFAULT;
14635            app.adjType = "top-activity";
14636            foregroundActivities = true;
14637            interesting = true;
14638            procState = ActivityManager.PROCESS_STATE_TOP;
14639        } else if (app.instrumentationClass != null) {
14640            // Don't want to kill running instrumentation.
14641            adj = ProcessList.FOREGROUND_APP_ADJ;
14642            schedGroup = Process.THREAD_GROUP_DEFAULT;
14643            app.adjType = "instrumentation";
14644            interesting = true;
14645            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14646        } else if ((queue = isReceivingBroadcast(app)) != null) {
14647            // An app that is currently receiving a broadcast also
14648            // counts as being in the foreground for OOM killer purposes.
14649            // It's placed in a sched group based on the nature of the
14650            // broadcast as reflected by which queue it's active in.
14651            adj = ProcessList.FOREGROUND_APP_ADJ;
14652            schedGroup = (queue == mFgBroadcastQueue)
14653                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14654            app.adjType = "broadcast";
14655            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14656        } else if (app.executingServices.size() > 0) {
14657            // An app that is currently executing a service callback also
14658            // counts as being in the foreground.
14659            adj = ProcessList.FOREGROUND_APP_ADJ;
14660            schedGroup = app.execServicesFg ?
14661                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14662            app.adjType = "exec-service";
14663            procState = ActivityManager.PROCESS_STATE_SERVICE;
14664            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14665        } else {
14666            // As far as we know the process is empty.  We may change our mind later.
14667            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14668            // At this point we don't actually know the adjustment.  Use the cached adj
14669            // value that the caller wants us to.
14670            adj = cachedAdj;
14671            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14672            app.cached = true;
14673            app.empty = true;
14674            app.adjType = "cch-empty";
14675        }
14676
14677        // Examine all activities if not already foreground.
14678        if (!foregroundActivities && activitiesSize > 0) {
14679            for (int j = 0; j < activitiesSize; j++) {
14680                final ActivityRecord r = app.activities.get(j);
14681                if (r.app != app) {
14682                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14683                            + app + "?!?");
14684                    continue;
14685                }
14686                if (r.visible) {
14687                    // App has a visible activity; only upgrade adjustment.
14688                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14689                        adj = ProcessList.VISIBLE_APP_ADJ;
14690                        app.adjType = "visible";
14691                    }
14692                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14693                        procState = ActivityManager.PROCESS_STATE_TOP;
14694                    }
14695                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14696                    app.cached = false;
14697                    app.empty = false;
14698                    foregroundActivities = true;
14699                    break;
14700                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14701                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14702                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14703                        app.adjType = "pausing";
14704                    }
14705                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14706                        procState = ActivityManager.PROCESS_STATE_TOP;
14707                    }
14708                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14709                    app.cached = false;
14710                    app.empty = false;
14711                    foregroundActivities = true;
14712                } else if (r.state == ActivityState.STOPPING) {
14713                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14714                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14715                        app.adjType = "stopping";
14716                    }
14717                    // For the process state, we will at this point consider the
14718                    // process to be cached.  It will be cached either as an activity
14719                    // or empty depending on whether the activity is finishing.  We do
14720                    // this so that we can treat the process as cached for purposes of
14721                    // memory trimming (determing current memory level, trim command to
14722                    // send to process) since there can be an arbitrary number of stopping
14723                    // processes and they should soon all go into the cached state.
14724                    if (!r.finishing) {
14725                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14726                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14727                        }
14728                    }
14729                    app.cached = false;
14730                    app.empty = false;
14731                    foregroundActivities = true;
14732                } else {
14733                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14734                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14735                        app.adjType = "cch-act";
14736                    }
14737                }
14738            }
14739        }
14740
14741        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14742            if (app.foregroundServices) {
14743                // The user is aware of this app, so make it visible.
14744                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14745                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14746                app.cached = false;
14747                app.adjType = "fg-service";
14748                schedGroup = Process.THREAD_GROUP_DEFAULT;
14749            } else if (app.forcingToForeground != null) {
14750                // The user is aware of this app, so make it visible.
14751                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14752                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14753                app.cached = false;
14754                app.adjType = "force-fg";
14755                app.adjSource = app.forcingToForeground;
14756                schedGroup = Process.THREAD_GROUP_DEFAULT;
14757            }
14758        }
14759
14760        if (app.foregroundServices) {
14761            interesting = true;
14762        }
14763
14764        if (app == mHeavyWeightProcess) {
14765            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14766                // We don't want to kill the current heavy-weight process.
14767                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14768                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14769                app.cached = false;
14770                app.adjType = "heavy";
14771            }
14772            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14773                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14774            }
14775        }
14776
14777        if (app == mHomeProcess) {
14778            if (adj > ProcessList.HOME_APP_ADJ) {
14779                // This process is hosting what we currently consider to be the
14780                // home app, so we don't want to let it go into the background.
14781                adj = ProcessList.HOME_APP_ADJ;
14782                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14783                app.cached = false;
14784                app.adjType = "home";
14785            }
14786            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14787                procState = ActivityManager.PROCESS_STATE_HOME;
14788            }
14789        }
14790
14791        if (app == mPreviousProcess && app.activities.size() > 0) {
14792            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14793                // This was the previous process that showed UI to the user.
14794                // We want to try to keep it around more aggressively, to give
14795                // a good experience around switching between two apps.
14796                adj = ProcessList.PREVIOUS_APP_ADJ;
14797                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14798                app.cached = false;
14799                app.adjType = "previous";
14800            }
14801            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14802                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14803            }
14804        }
14805
14806        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14807                + " reason=" + app.adjType);
14808
14809        // By default, we use the computed adjustment.  It may be changed if
14810        // there are applications dependent on our services or providers, but
14811        // this gives us a baseline and makes sure we don't get into an
14812        // infinite recursion.
14813        app.adjSeq = mAdjSeq;
14814        app.curRawAdj = adj;
14815        app.hasStartedServices = false;
14816
14817        if (mBackupTarget != null && app == mBackupTarget.app) {
14818            // If possible we want to avoid killing apps while they're being backed up
14819            if (adj > ProcessList.BACKUP_APP_ADJ) {
14820                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14821                adj = ProcessList.BACKUP_APP_ADJ;
14822                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14823                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14824                }
14825                app.adjType = "backup";
14826                app.cached = false;
14827            }
14828            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14829                procState = ActivityManager.PROCESS_STATE_BACKUP;
14830            }
14831        }
14832
14833        boolean mayBeTop = false;
14834
14835        for (int is = app.services.size()-1;
14836                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14837                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14838                        || procState > ActivityManager.PROCESS_STATE_TOP);
14839                is--) {
14840            ServiceRecord s = app.services.valueAt(is);
14841            if (s.startRequested) {
14842                app.hasStartedServices = true;
14843                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14844                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14845                }
14846                if (app.hasShownUi && app != mHomeProcess) {
14847                    // If this process has shown some UI, let it immediately
14848                    // go to the LRU list because it may be pretty heavy with
14849                    // UI stuff.  We'll tag it with a label just to help
14850                    // debug and understand what is going on.
14851                    if (adj > ProcessList.SERVICE_ADJ) {
14852                        app.adjType = "cch-started-ui-services";
14853                    }
14854                } else {
14855                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14856                        // This service has seen some activity within
14857                        // recent memory, so we will keep its process ahead
14858                        // of the background processes.
14859                        if (adj > ProcessList.SERVICE_ADJ) {
14860                            adj = ProcessList.SERVICE_ADJ;
14861                            app.adjType = "started-services";
14862                            app.cached = false;
14863                        }
14864                    }
14865                    // If we have let the service slide into the background
14866                    // state, still have some text describing what it is doing
14867                    // even though the service no longer has an impact.
14868                    if (adj > ProcessList.SERVICE_ADJ) {
14869                        app.adjType = "cch-started-services";
14870                    }
14871                }
14872                // Don't kill this process because it is doing work; it
14873                // has said it is doing work.
14874                app.keeping = true;
14875            }
14876            for (int conni = s.connections.size()-1;
14877                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14878                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14879                            || procState > ActivityManager.PROCESS_STATE_TOP);
14880                    conni--) {
14881                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14882                for (int i = 0;
14883                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14884                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14885                                || procState > ActivityManager.PROCESS_STATE_TOP);
14886                        i++) {
14887                    // XXX should compute this based on the max of
14888                    // all connected clients.
14889                    ConnectionRecord cr = clist.get(i);
14890                    if (cr.binding.client == app) {
14891                        // Binding to ourself is not interesting.
14892                        continue;
14893                    }
14894                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14895                        ProcessRecord client = cr.binding.client;
14896                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14897                                TOP_APP, doingAll, now);
14898                        int clientProcState = client.curProcState;
14899                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14900                            // If the other app is cached for any reason, for purposes here
14901                            // we are going to consider it empty.  The specific cached state
14902                            // doesn't propagate except under certain conditions.
14903                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14904                        }
14905                        String adjType = null;
14906                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14907                            // Not doing bind OOM management, so treat
14908                            // this guy more like a started service.
14909                            if (app.hasShownUi && app != mHomeProcess) {
14910                                // If this process has shown some UI, let it immediately
14911                                // go to the LRU list because it may be pretty heavy with
14912                                // UI stuff.  We'll tag it with a label just to help
14913                                // debug and understand what is going on.
14914                                if (adj > clientAdj) {
14915                                    adjType = "cch-bound-ui-services";
14916                                }
14917                                app.cached = false;
14918                                clientAdj = adj;
14919                                clientProcState = procState;
14920                            } else {
14921                                if (now >= (s.lastActivity
14922                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14923                                    // This service has not seen activity within
14924                                    // recent memory, so allow it to drop to the
14925                                    // LRU list if there is no other reason to keep
14926                                    // it around.  We'll also tag it with a label just
14927                                    // to help debug and undertand what is going on.
14928                                    if (adj > clientAdj) {
14929                                        adjType = "cch-bound-services";
14930                                    }
14931                                    clientAdj = adj;
14932                                }
14933                            }
14934                        }
14935                        if (adj > clientAdj) {
14936                            // If this process has recently shown UI, and
14937                            // the process that is binding to it is less
14938                            // important than being visible, then we don't
14939                            // care about the binding as much as we care
14940                            // about letting this process get into the LRU
14941                            // list to be killed and restarted if needed for
14942                            // memory.
14943                            if (app.hasShownUi && app != mHomeProcess
14944                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14945                                adjType = "cch-bound-ui-services";
14946                            } else {
14947                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14948                                        |Context.BIND_IMPORTANT)) != 0) {
14949                                    adj = clientAdj;
14950                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14951                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14952                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14953                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14954                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14955                                    adj = clientAdj;
14956                                } else {
14957                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14958                                        adj = ProcessList.VISIBLE_APP_ADJ;
14959                                    }
14960                                }
14961                                if (!client.cached) {
14962                                    app.cached = false;
14963                                }
14964                                if (client.keeping) {
14965                                    app.keeping = true;
14966                                }
14967                                adjType = "service";
14968                            }
14969                        }
14970                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14971                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14972                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14973                            }
14974                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14975                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14976                                    // Special handling of clients who are in the top state.
14977                                    // We *may* want to consider this process to be in the
14978                                    // top state as well, but only if there is not another
14979                                    // reason for it to be running.  Being on the top is a
14980                                    // special state, meaning you are specifically running
14981                                    // for the current top app.  If the process is already
14982                                    // running in the background for some other reason, it
14983                                    // is more important to continue considering it to be
14984                                    // in the background state.
14985                                    mayBeTop = true;
14986                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14987                                } else {
14988                                    // Special handling for above-top states (persistent
14989                                    // processes).  These should not bring the current process
14990                                    // into the top state, since they are not on top.  Instead
14991                                    // give them the best state after that.
14992                                    clientProcState =
14993                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14994                                }
14995                            }
14996                        } else {
14997                            if (clientProcState <
14998                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14999                                clientProcState =
15000                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15001                            }
15002                        }
15003                        if (procState > clientProcState) {
15004                            procState = clientProcState;
15005                        }
15006                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15007                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15008                            app.pendingUiClean = true;
15009                        }
15010                        if (adjType != null) {
15011                            app.adjType = adjType;
15012                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15013                                    .REASON_SERVICE_IN_USE;
15014                            app.adjSource = cr.binding.client;
15015                            app.adjSourceOom = clientAdj;
15016                            app.adjTarget = s.name;
15017                        }
15018                    }
15019                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15020                        app.treatLikeActivity = true;
15021                    }
15022                    final ActivityRecord a = cr.activity;
15023                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15024                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15025                                (a.visible || a.state == ActivityState.RESUMED
15026                                 || a.state == ActivityState.PAUSING)) {
15027                            adj = ProcessList.FOREGROUND_APP_ADJ;
15028                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15029                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15030                            }
15031                            app.cached = false;
15032                            app.adjType = "service";
15033                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15034                                    .REASON_SERVICE_IN_USE;
15035                            app.adjSource = a;
15036                            app.adjSourceOom = adj;
15037                            app.adjTarget = s.name;
15038                        }
15039                    }
15040                }
15041            }
15042        }
15043
15044        for (int provi = app.pubProviders.size()-1;
15045                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15046                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15047                        || procState > ActivityManager.PROCESS_STATE_TOP);
15048                provi--) {
15049            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15050            for (int i = cpr.connections.size()-1;
15051                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15052                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15053                            || procState > ActivityManager.PROCESS_STATE_TOP);
15054                    i--) {
15055                ContentProviderConnection conn = cpr.connections.get(i);
15056                ProcessRecord client = conn.client;
15057                if (client == app) {
15058                    // Being our own client is not interesting.
15059                    continue;
15060                }
15061                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15062                int clientProcState = client.curProcState;
15063                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15064                    // If the other app is cached for any reason, for purposes here
15065                    // we are going to consider it empty.
15066                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15067                }
15068                if (adj > clientAdj) {
15069                    if (app.hasShownUi && app != mHomeProcess
15070                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15071                        app.adjType = "cch-ui-provider";
15072                    } else {
15073                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15074                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15075                        app.adjType = "provider";
15076                    }
15077                    app.cached &= client.cached;
15078                    app.keeping |= client.keeping;
15079                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15080                            .REASON_PROVIDER_IN_USE;
15081                    app.adjSource = client;
15082                    app.adjSourceOom = clientAdj;
15083                    app.adjTarget = cpr.name;
15084                }
15085                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15086                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15087                        // Special handling of clients who are in the top state.
15088                        // We *may* want to consider this process to be in the
15089                        // top state as well, but only if there is not another
15090                        // reason for it to be running.  Being on the top is a
15091                        // special state, meaning you are specifically running
15092                        // for the current top app.  If the process is already
15093                        // running in the background for some other reason, it
15094                        // is more important to continue considering it to be
15095                        // in the background state.
15096                        mayBeTop = true;
15097                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15098                    } else {
15099                        // Special handling for above-top states (persistent
15100                        // processes).  These should not bring the current process
15101                        // into the top state, since they are not on top.  Instead
15102                        // give them the best state after that.
15103                        clientProcState =
15104                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15105                    }
15106                }
15107                if (procState > clientProcState) {
15108                    procState = clientProcState;
15109                }
15110                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15111                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15112                }
15113            }
15114            // If the provider has external (non-framework) process
15115            // dependencies, ensure that its adjustment is at least
15116            // FOREGROUND_APP_ADJ.
15117            if (cpr.hasExternalProcessHandles()) {
15118                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15119                    adj = ProcessList.FOREGROUND_APP_ADJ;
15120                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15121                    app.cached = false;
15122                    app.keeping = true;
15123                    app.adjType = "provider";
15124                    app.adjTarget = cpr.name;
15125                }
15126                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15127                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15128                }
15129            }
15130        }
15131
15132        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15133            // A client of one of our services or providers is in the top state.  We
15134            // *may* want to be in the top state, but not if we are already running in
15135            // the background for some other reason.  For the decision here, we are going
15136            // to pick out a few specific states that we want to remain in when a client
15137            // is top (states that tend to be longer-term) and otherwise allow it to go
15138            // to the top state.
15139            switch (procState) {
15140                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15141                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15142                case ActivityManager.PROCESS_STATE_SERVICE:
15143                    // These all are longer-term states, so pull them up to the top
15144                    // of the background states, but not all the way to the top state.
15145                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15146                    break;
15147                default:
15148                    // Otherwise, top is a better choice, so take it.
15149                    procState = ActivityManager.PROCESS_STATE_TOP;
15150                    break;
15151            }
15152        }
15153
15154        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15155            if (app.hasClientActivities) {
15156                // This is a cached process, but with client activities.  Mark it so.
15157                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15158                app.adjType = "cch-client-act";
15159            } else if (app.treatLikeActivity) {
15160                // This is a cached process, but somebody wants us to treat it like it has
15161                // an activity, okay!
15162                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15163                app.adjType = "cch-as-act";
15164            }
15165        }
15166
15167        if (adj == ProcessList.SERVICE_ADJ) {
15168            if (doingAll) {
15169                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15170                mNewNumServiceProcs++;
15171                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15172                if (!app.serviceb) {
15173                    // This service isn't far enough down on the LRU list to
15174                    // normally be a B service, but if we are low on RAM and it
15175                    // is large we want to force it down since we would prefer to
15176                    // keep launcher over it.
15177                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15178                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15179                        app.serviceHighRam = true;
15180                        app.serviceb = true;
15181                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15182                    } else {
15183                        mNewNumAServiceProcs++;
15184                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15185                    }
15186                } else {
15187                    app.serviceHighRam = false;
15188                }
15189            }
15190            if (app.serviceb) {
15191                adj = ProcessList.SERVICE_B_ADJ;
15192            }
15193        }
15194
15195        app.curRawAdj = adj;
15196
15197        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15198        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15199        if (adj > app.maxAdj) {
15200            adj = app.maxAdj;
15201            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15202                schedGroup = Process.THREAD_GROUP_DEFAULT;
15203            }
15204        }
15205        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15206            app.keeping = true;
15207        }
15208
15209        // Do final modification to adj.  Everything we do between here and applying
15210        // the final setAdj must be done in this function, because we will also use
15211        // it when computing the final cached adj later.  Note that we don't need to
15212        // worry about this for max adj above, since max adj will always be used to
15213        // keep it out of the cached vaues.
15214        app.curAdj = app.modifyRawOomAdj(adj);
15215        app.curSchedGroup = schedGroup;
15216        app.curProcState = procState;
15217        app.foregroundActivities = foregroundActivities;
15218
15219        return app.curRawAdj;
15220    }
15221
15222    /**
15223     * Schedule PSS collection of a process.
15224     */
15225    void requestPssLocked(ProcessRecord proc, int procState) {
15226        if (mPendingPssProcesses.contains(proc)) {
15227            return;
15228        }
15229        if (mPendingPssProcesses.size() == 0) {
15230            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15231        }
15232        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15233        proc.pssProcState = procState;
15234        mPendingPssProcesses.add(proc);
15235    }
15236
15237    /**
15238     * Schedule PSS collection of all processes.
15239     */
15240    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15241        if (!always) {
15242            if (now < (mLastFullPssTime +
15243                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15244                return;
15245            }
15246        }
15247        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15248        mLastFullPssTime = now;
15249        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15250        mPendingPssProcesses.clear();
15251        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15252            ProcessRecord app = mLruProcesses.get(i);
15253            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15254                app.pssProcState = app.setProcState;
15255                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15256                        isSleeping(), now);
15257                mPendingPssProcesses.add(app);
15258            }
15259        }
15260        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15261    }
15262
15263    /**
15264     * Ask a given process to GC right now.
15265     */
15266    final void performAppGcLocked(ProcessRecord app) {
15267        try {
15268            app.lastRequestedGc = SystemClock.uptimeMillis();
15269            if (app.thread != null) {
15270                if (app.reportLowMemory) {
15271                    app.reportLowMemory = false;
15272                    app.thread.scheduleLowMemory();
15273                } else {
15274                    app.thread.processInBackground();
15275                }
15276            }
15277        } catch (Exception e) {
15278            // whatever.
15279        }
15280    }
15281
15282    /**
15283     * Returns true if things are idle enough to perform GCs.
15284     */
15285    private final boolean canGcNowLocked() {
15286        boolean processingBroadcasts = false;
15287        for (BroadcastQueue q : mBroadcastQueues) {
15288            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15289                processingBroadcasts = true;
15290            }
15291        }
15292        return !processingBroadcasts
15293                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15294    }
15295
15296    /**
15297     * Perform GCs on all processes that are waiting for it, but only
15298     * if things are idle.
15299     */
15300    final void performAppGcsLocked() {
15301        final int N = mProcessesToGc.size();
15302        if (N <= 0) {
15303            return;
15304        }
15305        if (canGcNowLocked()) {
15306            while (mProcessesToGc.size() > 0) {
15307                ProcessRecord proc = mProcessesToGc.remove(0);
15308                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15309                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15310                            <= SystemClock.uptimeMillis()) {
15311                        // To avoid spamming the system, we will GC processes one
15312                        // at a time, waiting a few seconds between each.
15313                        performAppGcLocked(proc);
15314                        scheduleAppGcsLocked();
15315                        return;
15316                    } else {
15317                        // It hasn't been long enough since we last GCed this
15318                        // process...  put it in the list to wait for its time.
15319                        addProcessToGcListLocked(proc);
15320                        break;
15321                    }
15322                }
15323            }
15324
15325            scheduleAppGcsLocked();
15326        }
15327    }
15328
15329    /**
15330     * If all looks good, perform GCs on all processes waiting for them.
15331     */
15332    final void performAppGcsIfAppropriateLocked() {
15333        if (canGcNowLocked()) {
15334            performAppGcsLocked();
15335            return;
15336        }
15337        // Still not idle, wait some more.
15338        scheduleAppGcsLocked();
15339    }
15340
15341    /**
15342     * Schedule the execution of all pending app GCs.
15343     */
15344    final void scheduleAppGcsLocked() {
15345        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15346
15347        if (mProcessesToGc.size() > 0) {
15348            // Schedule a GC for the time to the next process.
15349            ProcessRecord proc = mProcessesToGc.get(0);
15350            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15351
15352            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15353            long now = SystemClock.uptimeMillis();
15354            if (when < (now+GC_TIMEOUT)) {
15355                when = now + GC_TIMEOUT;
15356            }
15357            mHandler.sendMessageAtTime(msg, when);
15358        }
15359    }
15360
15361    /**
15362     * Add a process to the array of processes waiting to be GCed.  Keeps the
15363     * list in sorted order by the last GC time.  The process can't already be
15364     * on the list.
15365     */
15366    final void addProcessToGcListLocked(ProcessRecord proc) {
15367        boolean added = false;
15368        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15369            if (mProcessesToGc.get(i).lastRequestedGc <
15370                    proc.lastRequestedGc) {
15371                added = true;
15372                mProcessesToGc.add(i+1, proc);
15373                break;
15374            }
15375        }
15376        if (!added) {
15377            mProcessesToGc.add(0, proc);
15378        }
15379    }
15380
15381    /**
15382     * Set up to ask a process to GC itself.  This will either do it
15383     * immediately, or put it on the list of processes to gc the next
15384     * time things are idle.
15385     */
15386    final void scheduleAppGcLocked(ProcessRecord app) {
15387        long now = SystemClock.uptimeMillis();
15388        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15389            return;
15390        }
15391        if (!mProcessesToGc.contains(app)) {
15392            addProcessToGcListLocked(app);
15393            scheduleAppGcsLocked();
15394        }
15395    }
15396
15397    final void checkExcessivePowerUsageLocked(boolean doKills) {
15398        updateCpuStatsNow();
15399
15400        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15401        boolean doWakeKills = doKills;
15402        boolean doCpuKills = doKills;
15403        if (mLastPowerCheckRealtime == 0) {
15404            doWakeKills = false;
15405        }
15406        if (mLastPowerCheckUptime == 0) {
15407            doCpuKills = false;
15408        }
15409        if (stats.isScreenOn()) {
15410            doWakeKills = false;
15411        }
15412        final long curRealtime = SystemClock.elapsedRealtime();
15413        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15414        final long curUptime = SystemClock.uptimeMillis();
15415        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15416        mLastPowerCheckRealtime = curRealtime;
15417        mLastPowerCheckUptime = curUptime;
15418        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15419            doWakeKills = false;
15420        }
15421        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15422            doCpuKills = false;
15423        }
15424        int i = mLruProcesses.size();
15425        while (i > 0) {
15426            i--;
15427            ProcessRecord app = mLruProcesses.get(i);
15428            if (!app.keeping) {
15429                long wtime;
15430                synchronized (stats) {
15431                    wtime = stats.getProcessWakeTime(app.info.uid,
15432                            app.pid, curRealtime);
15433                }
15434                long wtimeUsed = wtime - app.lastWakeTime;
15435                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15436                if (DEBUG_POWER) {
15437                    StringBuilder sb = new StringBuilder(128);
15438                    sb.append("Wake for ");
15439                    app.toShortString(sb);
15440                    sb.append(": over ");
15441                    TimeUtils.formatDuration(realtimeSince, sb);
15442                    sb.append(" used ");
15443                    TimeUtils.formatDuration(wtimeUsed, sb);
15444                    sb.append(" (");
15445                    sb.append((wtimeUsed*100)/realtimeSince);
15446                    sb.append("%)");
15447                    Slog.i(TAG, sb.toString());
15448                    sb.setLength(0);
15449                    sb.append("CPU for ");
15450                    app.toShortString(sb);
15451                    sb.append(": over ");
15452                    TimeUtils.formatDuration(uptimeSince, sb);
15453                    sb.append(" used ");
15454                    TimeUtils.formatDuration(cputimeUsed, sb);
15455                    sb.append(" (");
15456                    sb.append((cputimeUsed*100)/uptimeSince);
15457                    sb.append("%)");
15458                    Slog.i(TAG, sb.toString());
15459                }
15460                // If a process has held a wake lock for more
15461                // than 50% of the time during this period,
15462                // that sounds bad.  Kill!
15463                if (doWakeKills && realtimeSince > 0
15464                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15465                    synchronized (stats) {
15466                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15467                                realtimeSince, wtimeUsed);
15468                    }
15469                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15470                            + " during " + realtimeSince);
15471                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15472                } else if (doCpuKills && uptimeSince > 0
15473                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15474                    synchronized (stats) {
15475                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15476                                uptimeSince, cputimeUsed);
15477                    }
15478                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15479                            + " during " + uptimeSince);
15480                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15481                } else {
15482                    app.lastWakeTime = wtime;
15483                    app.lastCpuTime = app.curCpuTime;
15484                }
15485            }
15486        }
15487    }
15488
15489    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15490            ProcessRecord TOP_APP, boolean doingAll, long now) {
15491        boolean success = true;
15492
15493        if (app.curRawAdj != app.setRawAdj) {
15494            if (wasKeeping && !app.keeping) {
15495                // This app is no longer something we want to keep.  Note
15496                // its current wake lock time to later know to kill it if
15497                // it is not behaving well.
15498                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15499                synchronized (stats) {
15500                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15501                            app.pid, SystemClock.elapsedRealtime());
15502                }
15503                app.lastCpuTime = app.curCpuTime;
15504            }
15505
15506            app.setRawAdj = app.curRawAdj;
15507        }
15508
15509        int changes = 0;
15510
15511        if (app.curAdj != app.setAdj) {
15512            ProcessList.setOomAdj(app.pid, app.curAdj);
15513            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15514                TAG, "Set " + app.pid + " " + app.processName +
15515                " adj " + app.curAdj + ": " + app.adjType);
15516            app.setAdj = app.curAdj;
15517        }
15518
15519        if (app.setSchedGroup != app.curSchedGroup) {
15520            app.setSchedGroup = app.curSchedGroup;
15521            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15522                    "Setting process group of " + app.processName
15523                    + " to " + app.curSchedGroup);
15524            if (app.waitingToKill != null &&
15525                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15526                killUnneededProcessLocked(app, app.waitingToKill);
15527                success = false;
15528            } else {
15529                if (true) {
15530                    long oldId = Binder.clearCallingIdentity();
15531                    try {
15532                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15533                    } catch (Exception e) {
15534                        Slog.w(TAG, "Failed setting process group of " + app.pid
15535                                + " to " + app.curSchedGroup);
15536                        e.printStackTrace();
15537                    } finally {
15538                        Binder.restoreCallingIdentity(oldId);
15539                    }
15540                } else {
15541                    if (app.thread != null) {
15542                        try {
15543                            app.thread.setSchedulingGroup(app.curSchedGroup);
15544                        } catch (RemoteException e) {
15545                        }
15546                    }
15547                }
15548                Process.setSwappiness(app.pid,
15549                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15550            }
15551        }
15552        if (app.repForegroundActivities != app.foregroundActivities) {
15553            app.repForegroundActivities = app.foregroundActivities;
15554            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15555        }
15556        if (app.repProcState != app.curProcState) {
15557            app.repProcState = app.curProcState;
15558            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15559            if (app.thread != null) {
15560                try {
15561                    if (false) {
15562                        //RuntimeException h = new RuntimeException("here");
15563                        Slog.i(TAG, "Sending new process state " + app.repProcState
15564                                + " to " + app /*, h*/);
15565                    }
15566                    app.thread.setProcessState(app.repProcState);
15567                } catch (RemoteException e) {
15568                }
15569            }
15570        }
15571        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15572                app.setProcState)) {
15573            app.lastStateTime = now;
15574            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15575                    isSleeping(), now);
15576            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15577                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15578                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15579                    + (app.nextPssTime-now) + ": " + app);
15580        } else {
15581            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15582                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15583                requestPssLocked(app, app.setProcState);
15584                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15585                        isSleeping(), now);
15586            } else if (false && DEBUG_PSS) {
15587                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15588            }
15589        }
15590        if (app.setProcState != app.curProcState) {
15591            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15592                    "Proc state change of " + app.processName
15593                    + " to " + app.curProcState);
15594            app.setProcState = app.curProcState;
15595            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15596                app.notCachedSinceIdle = false;
15597            }
15598            if (!doingAll) {
15599                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15600            } else {
15601                app.procStateChanged = true;
15602            }
15603        }
15604
15605        if (changes != 0) {
15606            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15607            int i = mPendingProcessChanges.size()-1;
15608            ProcessChangeItem item = null;
15609            while (i >= 0) {
15610                item = mPendingProcessChanges.get(i);
15611                if (item.pid == app.pid) {
15612                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15613                    break;
15614                }
15615                i--;
15616            }
15617            if (i < 0) {
15618                // No existing item in pending changes; need a new one.
15619                final int NA = mAvailProcessChanges.size();
15620                if (NA > 0) {
15621                    item = mAvailProcessChanges.remove(NA-1);
15622                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15623                } else {
15624                    item = new ProcessChangeItem();
15625                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15626                }
15627                item.changes = 0;
15628                item.pid = app.pid;
15629                item.uid = app.info.uid;
15630                if (mPendingProcessChanges.size() == 0) {
15631                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15632                            "*** Enqueueing dispatch processes changed!");
15633                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15634                }
15635                mPendingProcessChanges.add(item);
15636            }
15637            item.changes |= changes;
15638            item.processState = app.repProcState;
15639            item.foregroundActivities = app.repForegroundActivities;
15640            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15641                    + Integer.toHexString(System.identityHashCode(item))
15642                    + " " + app.toShortString() + ": changes=" + item.changes
15643                    + " procState=" + item.processState
15644                    + " foreground=" + item.foregroundActivities
15645                    + " type=" + app.adjType + " source=" + app.adjSource
15646                    + " target=" + app.adjTarget);
15647        }
15648
15649        return success;
15650    }
15651
15652    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15653        if (proc.thread != null && proc.baseProcessTracker != null) {
15654            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15655        }
15656    }
15657
15658    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15659            ProcessRecord TOP_APP, boolean doingAll, long now) {
15660        if (app.thread == null) {
15661            return false;
15662        }
15663
15664        final boolean wasKeeping = app.keeping;
15665
15666        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15667
15668        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15669    }
15670
15671    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15672            boolean oomAdj) {
15673        if (isForeground != proc.foregroundServices) {
15674            proc.foregroundServices = isForeground;
15675            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15676                    proc.info.uid);
15677            if (isForeground) {
15678                if (curProcs == null) {
15679                    curProcs = new ArrayList<ProcessRecord>();
15680                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15681                }
15682                if (!curProcs.contains(proc)) {
15683                    curProcs.add(proc);
15684                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15685                            proc.info.packageName, proc.info.uid);
15686                }
15687            } else {
15688                if (curProcs != null) {
15689                    if (curProcs.remove(proc)) {
15690                        mBatteryStatsService.noteEvent(
15691                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15692                                proc.info.packageName, proc.info.uid);
15693                        if (curProcs.size() <= 0) {
15694                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15695                        }
15696                    }
15697                }
15698            }
15699            if (oomAdj) {
15700                updateOomAdjLocked();
15701            }
15702        }
15703    }
15704
15705    private final ActivityRecord resumedAppLocked() {
15706        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15707        String pkg;
15708        int uid;
15709        if (act != null && !act.sleeping) {
15710            pkg = act.packageName;
15711            uid = act.info.applicationInfo.uid;
15712        } else {
15713            pkg = null;
15714            uid = -1;
15715        }
15716        // Has the UID or resumed package name changed?
15717        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15718                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15719            if (mCurResumedPackage != null) {
15720                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15721                        mCurResumedPackage, mCurResumedUid);
15722            }
15723            mCurResumedPackage = pkg;
15724            mCurResumedUid = uid;
15725            if (mCurResumedPackage != null) {
15726                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15727                        mCurResumedPackage, mCurResumedUid);
15728            }
15729        }
15730        return act;
15731    }
15732
15733    final boolean updateOomAdjLocked(ProcessRecord app) {
15734        final ActivityRecord TOP_ACT = resumedAppLocked();
15735        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15736        final boolean wasCached = app.cached;
15737
15738        mAdjSeq++;
15739
15740        // This is the desired cached adjusment we want to tell it to use.
15741        // If our app is currently cached, we know it, and that is it.  Otherwise,
15742        // we don't know it yet, and it needs to now be cached we will then
15743        // need to do a complete oom adj.
15744        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15745                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15746        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15747                SystemClock.uptimeMillis());
15748        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15749            // Changed to/from cached state, so apps after it in the LRU
15750            // list may also be changed.
15751            updateOomAdjLocked();
15752        }
15753        return success;
15754    }
15755
15756    final void updateOomAdjLocked() {
15757        final ActivityRecord TOP_ACT = resumedAppLocked();
15758        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15759        final long now = SystemClock.uptimeMillis();
15760        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15761        final int N = mLruProcesses.size();
15762
15763        if (false) {
15764            RuntimeException e = new RuntimeException();
15765            e.fillInStackTrace();
15766            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15767        }
15768
15769        mAdjSeq++;
15770        mNewNumServiceProcs = 0;
15771        mNewNumAServiceProcs = 0;
15772
15773        final int emptyProcessLimit;
15774        final int cachedProcessLimit;
15775        if (mProcessLimit <= 0) {
15776            emptyProcessLimit = cachedProcessLimit = 0;
15777        } else if (mProcessLimit == 1) {
15778            emptyProcessLimit = 1;
15779            cachedProcessLimit = 0;
15780        } else {
15781            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15782            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15783        }
15784
15785        // Let's determine how many processes we have running vs.
15786        // how many slots we have for background processes; we may want
15787        // to put multiple processes in a slot of there are enough of
15788        // them.
15789        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15790                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15791        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15792        if (numEmptyProcs > cachedProcessLimit) {
15793            // If there are more empty processes than our limit on cached
15794            // processes, then use the cached process limit for the factor.
15795            // This ensures that the really old empty processes get pushed
15796            // down to the bottom, so if we are running low on memory we will
15797            // have a better chance at keeping around more cached processes
15798            // instead of a gazillion empty processes.
15799            numEmptyProcs = cachedProcessLimit;
15800        }
15801        int emptyFactor = numEmptyProcs/numSlots;
15802        if (emptyFactor < 1) emptyFactor = 1;
15803        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15804        if (cachedFactor < 1) cachedFactor = 1;
15805        int stepCached = 0;
15806        int stepEmpty = 0;
15807        int numCached = 0;
15808        int numEmpty = 0;
15809        int numTrimming = 0;
15810
15811        mNumNonCachedProcs = 0;
15812        mNumCachedHiddenProcs = 0;
15813
15814        // First update the OOM adjustment for each of the
15815        // application processes based on their current state.
15816        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15817        int nextCachedAdj = curCachedAdj+1;
15818        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15819        int nextEmptyAdj = curEmptyAdj+2;
15820        for (int i=N-1; i>=0; i--) {
15821            ProcessRecord app = mLruProcesses.get(i);
15822            if (!app.killedByAm && app.thread != null) {
15823                app.procStateChanged = false;
15824                final boolean wasKeeping = app.keeping;
15825                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15826
15827                // If we haven't yet assigned the final cached adj
15828                // to the process, do that now.
15829                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15830                    switch (app.curProcState) {
15831                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15832                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15833                            // This process is a cached process holding activities...
15834                            // assign it the next cached value for that type, and then
15835                            // step that cached level.
15836                            app.curRawAdj = curCachedAdj;
15837                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15838                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15839                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15840                                    + ")");
15841                            if (curCachedAdj != nextCachedAdj) {
15842                                stepCached++;
15843                                if (stepCached >= cachedFactor) {
15844                                    stepCached = 0;
15845                                    curCachedAdj = nextCachedAdj;
15846                                    nextCachedAdj += 2;
15847                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15848                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15849                                    }
15850                                }
15851                            }
15852                            break;
15853                        default:
15854                            // For everything else, assign next empty cached process
15855                            // level and bump that up.  Note that this means that
15856                            // long-running services that have dropped down to the
15857                            // cached level will be treated as empty (since their process
15858                            // state is still as a service), which is what we want.
15859                            app.curRawAdj = curEmptyAdj;
15860                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15861                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15862                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15863                                    + ")");
15864                            if (curEmptyAdj != nextEmptyAdj) {
15865                                stepEmpty++;
15866                                if (stepEmpty >= emptyFactor) {
15867                                    stepEmpty = 0;
15868                                    curEmptyAdj = nextEmptyAdj;
15869                                    nextEmptyAdj += 2;
15870                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15871                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15872                                    }
15873                                }
15874                            }
15875                            break;
15876                    }
15877                }
15878
15879                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15880
15881                // Count the number of process types.
15882                switch (app.curProcState) {
15883                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15884                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15885                        mNumCachedHiddenProcs++;
15886                        numCached++;
15887                        if (numCached > cachedProcessLimit) {
15888                            killUnneededProcessLocked(app, "cached #" + numCached);
15889                        }
15890                        break;
15891                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15892                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15893                                && app.lastActivityTime < oldTime) {
15894                            killUnneededProcessLocked(app, "empty for "
15895                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15896                                    / 1000) + "s");
15897                        } else {
15898                            numEmpty++;
15899                            if (numEmpty > emptyProcessLimit) {
15900                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15901                            }
15902                        }
15903                        break;
15904                    default:
15905                        mNumNonCachedProcs++;
15906                        break;
15907                }
15908
15909                if (app.isolated && app.services.size() <= 0) {
15910                    // If this is an isolated process, and there are no
15911                    // services running in it, then the process is no longer
15912                    // needed.  We agressively kill these because we can by
15913                    // definition not re-use the same process again, and it is
15914                    // good to avoid having whatever code was running in them
15915                    // left sitting around after no longer needed.
15916                    killUnneededProcessLocked(app, "isolated not needed");
15917                }
15918
15919                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15920                        && !app.killedByAm) {
15921                    numTrimming++;
15922                }
15923            }
15924        }
15925
15926        mNumServiceProcs = mNewNumServiceProcs;
15927
15928        // Now determine the memory trimming level of background processes.
15929        // Unfortunately we need to start at the back of the list to do this
15930        // properly.  We only do this if the number of background apps we
15931        // are managing to keep around is less than half the maximum we desire;
15932        // if we are keeping a good number around, we'll let them use whatever
15933        // memory they want.
15934        final int numCachedAndEmpty = numCached + numEmpty;
15935        int memFactor;
15936        if (numCached <= ProcessList.TRIM_CACHED_APPS
15937                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15938            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15939                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15940            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15941                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15942            } else {
15943                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15944            }
15945        } else {
15946            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15947        }
15948        // We always allow the memory level to go up (better).  We only allow it to go
15949        // down if we are in a state where that is allowed, *and* the total number of processes
15950        // has gone down since last time.
15951        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15952                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15953                + " last=" + mLastNumProcesses);
15954        if (memFactor > mLastMemoryLevel) {
15955            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15956                memFactor = mLastMemoryLevel;
15957                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15958            }
15959        }
15960        mLastMemoryLevel = memFactor;
15961        mLastNumProcesses = mLruProcesses.size();
15962        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
15963        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15964        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15965            if (mLowRamStartTime == 0) {
15966                mLowRamStartTime = now;
15967            }
15968            int step = 0;
15969            int fgTrimLevel;
15970            switch (memFactor) {
15971                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15972                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15973                    break;
15974                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15975                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15976                    break;
15977                default:
15978                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15979                    break;
15980            }
15981            int factor = numTrimming/3;
15982            int minFactor = 2;
15983            if (mHomeProcess != null) minFactor++;
15984            if (mPreviousProcess != null) minFactor++;
15985            if (factor < minFactor) factor = minFactor;
15986            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15987            for (int i=N-1; i>=0; i--) {
15988                ProcessRecord app = mLruProcesses.get(i);
15989                if (allChanged || app.procStateChanged) {
15990                    setProcessTrackerState(app, trackerMemFactor, now);
15991                    app.procStateChanged = false;
15992                }
15993                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15994                        && !app.killedByAm) {
15995                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15996                        try {
15997                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15998                                    "Trimming memory of " + app.processName
15999                                    + " to " + curLevel);
16000                            app.thread.scheduleTrimMemory(curLevel);
16001                        } catch (RemoteException e) {
16002                        }
16003                        if (false) {
16004                            // For now we won't do this; our memory trimming seems
16005                            // to be good enough at this point that destroying
16006                            // activities causes more harm than good.
16007                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16008                                    && app != mHomeProcess && app != mPreviousProcess) {
16009                                // Need to do this on its own message because the stack may not
16010                                // be in a consistent state at this point.
16011                                // For these apps we will also finish their activities
16012                                // to help them free memory.
16013                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16014                            }
16015                        }
16016                    }
16017                    app.trimMemoryLevel = curLevel;
16018                    step++;
16019                    if (step >= factor) {
16020                        step = 0;
16021                        switch (curLevel) {
16022                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16023                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16024                                break;
16025                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16026                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16027                                break;
16028                        }
16029                    }
16030                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16031                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16032                            && app.thread != null) {
16033                        try {
16034                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16035                                    "Trimming memory of heavy-weight " + app.processName
16036                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16037                            app.thread.scheduleTrimMemory(
16038                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16039                        } catch (RemoteException e) {
16040                        }
16041                    }
16042                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16043                } else {
16044                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16045                            || app.systemNoUi) && app.pendingUiClean) {
16046                        // If this application is now in the background and it
16047                        // had done UI, then give it the special trim level to
16048                        // have it free UI resources.
16049                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16050                        if (app.trimMemoryLevel < level && app.thread != null) {
16051                            try {
16052                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16053                                        "Trimming memory of bg-ui " + app.processName
16054                                        + " to " + level);
16055                                app.thread.scheduleTrimMemory(level);
16056                            } catch (RemoteException e) {
16057                            }
16058                        }
16059                        app.pendingUiClean = false;
16060                    }
16061                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16062                        try {
16063                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16064                                    "Trimming memory of fg " + app.processName
16065                                    + " to " + fgTrimLevel);
16066                            app.thread.scheduleTrimMemory(fgTrimLevel);
16067                        } catch (RemoteException e) {
16068                        }
16069                    }
16070                    app.trimMemoryLevel = fgTrimLevel;
16071                }
16072            }
16073        } else {
16074            if (mLowRamStartTime != 0) {
16075                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16076                mLowRamStartTime = 0;
16077            }
16078            for (int i=N-1; i>=0; i--) {
16079                ProcessRecord app = mLruProcesses.get(i);
16080                if (allChanged || app.procStateChanged) {
16081                    setProcessTrackerState(app, trackerMemFactor, now);
16082                    app.procStateChanged = false;
16083                }
16084                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16085                        || app.systemNoUi) && app.pendingUiClean) {
16086                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16087                            && app.thread != null) {
16088                        try {
16089                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16090                                    "Trimming memory of ui hidden " + app.processName
16091                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16092                            app.thread.scheduleTrimMemory(
16093                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16094                        } catch (RemoteException e) {
16095                        }
16096                    }
16097                    app.pendingUiClean = false;
16098                }
16099                app.trimMemoryLevel = 0;
16100            }
16101        }
16102
16103        if (mAlwaysFinishActivities) {
16104            // Need to do this on its own message because the stack may not
16105            // be in a consistent state at this point.
16106            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16107        }
16108
16109        if (allChanged) {
16110            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16111        }
16112
16113        if (mProcessStats.shouldWriteNowLocked(now)) {
16114            mHandler.post(new Runnable() {
16115                @Override public void run() {
16116                    synchronized (ActivityManagerService.this) {
16117                        mProcessStats.writeStateAsyncLocked();
16118                    }
16119                }
16120            });
16121        }
16122
16123        if (DEBUG_OOM_ADJ) {
16124            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16125        }
16126    }
16127
16128    final void trimApplications() {
16129        synchronized (this) {
16130            int i;
16131
16132            // First remove any unused application processes whose package
16133            // has been removed.
16134            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16135                final ProcessRecord app = mRemovedProcesses.get(i);
16136                if (app.activities.size() == 0
16137                        && app.curReceiver == null && app.services.size() == 0) {
16138                    Slog.i(
16139                        TAG, "Exiting empty application process "
16140                        + app.processName + " ("
16141                        + (app.thread != null ? app.thread.asBinder() : null)
16142                        + ")\n");
16143                    if (app.pid > 0 && app.pid != MY_PID) {
16144                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16145                                app.processName, app.setAdj, "empty");
16146                        app.killedByAm = true;
16147                        Process.killProcessQuiet(app.pid);
16148                    } else {
16149                        try {
16150                            app.thread.scheduleExit();
16151                        } catch (Exception e) {
16152                            // Ignore exceptions.
16153                        }
16154                    }
16155                    cleanUpApplicationRecordLocked(app, false, true, -1);
16156                    mRemovedProcesses.remove(i);
16157
16158                    if (app.persistent) {
16159                        if (app.persistent) {
16160                            addAppLocked(app.info, false);
16161                        }
16162                    }
16163                }
16164            }
16165
16166            // Now update the oom adj for all processes.
16167            updateOomAdjLocked();
16168        }
16169    }
16170
16171    /** This method sends the specified signal to each of the persistent apps */
16172    public void signalPersistentProcesses(int sig) throws RemoteException {
16173        if (sig != Process.SIGNAL_USR1) {
16174            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16175        }
16176
16177        synchronized (this) {
16178            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16179                    != PackageManager.PERMISSION_GRANTED) {
16180                throw new SecurityException("Requires permission "
16181                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16182            }
16183
16184            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16185                ProcessRecord r = mLruProcesses.get(i);
16186                if (r.thread != null && r.persistent) {
16187                    Process.sendSignal(r.pid, sig);
16188                }
16189            }
16190        }
16191    }
16192
16193    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16194        if (proc == null || proc == mProfileProc) {
16195            proc = mProfileProc;
16196            path = mProfileFile;
16197            profileType = mProfileType;
16198            clearProfilerLocked();
16199        }
16200        if (proc == null) {
16201            return;
16202        }
16203        try {
16204            proc.thread.profilerControl(false, path, null, profileType);
16205        } catch (RemoteException e) {
16206            throw new IllegalStateException("Process disappeared");
16207        }
16208    }
16209
16210    private void clearProfilerLocked() {
16211        if (mProfileFd != null) {
16212            try {
16213                mProfileFd.close();
16214            } catch (IOException e) {
16215            }
16216        }
16217        mProfileApp = null;
16218        mProfileProc = null;
16219        mProfileFile = null;
16220        mProfileType = 0;
16221        mAutoStopProfiler = false;
16222    }
16223
16224    public boolean profileControl(String process, int userId, boolean start,
16225            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16226
16227        try {
16228            synchronized (this) {
16229                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16230                // its own permission.
16231                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16232                        != PackageManager.PERMISSION_GRANTED) {
16233                    throw new SecurityException("Requires permission "
16234                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16235                }
16236
16237                if (start && fd == null) {
16238                    throw new IllegalArgumentException("null fd");
16239                }
16240
16241                ProcessRecord proc = null;
16242                if (process != null) {
16243                    proc = findProcessLocked(process, userId, "profileControl");
16244                }
16245
16246                if (start && (proc == null || proc.thread == null)) {
16247                    throw new IllegalArgumentException("Unknown process: " + process);
16248                }
16249
16250                if (start) {
16251                    stopProfilerLocked(null, null, 0);
16252                    setProfileApp(proc.info, proc.processName, path, fd, false);
16253                    mProfileProc = proc;
16254                    mProfileType = profileType;
16255                    try {
16256                        fd = fd.dup();
16257                    } catch (IOException e) {
16258                        fd = null;
16259                    }
16260                    proc.thread.profilerControl(start, path, fd, profileType);
16261                    fd = null;
16262                    mProfileFd = null;
16263                } else {
16264                    stopProfilerLocked(proc, path, profileType);
16265                    if (fd != null) {
16266                        try {
16267                            fd.close();
16268                        } catch (IOException e) {
16269                        }
16270                    }
16271                }
16272
16273                return true;
16274            }
16275        } catch (RemoteException e) {
16276            throw new IllegalStateException("Process disappeared");
16277        } finally {
16278            if (fd != null) {
16279                try {
16280                    fd.close();
16281                } catch (IOException e) {
16282                }
16283            }
16284        }
16285    }
16286
16287    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16288        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16289                userId, true, true, callName, null);
16290        ProcessRecord proc = null;
16291        try {
16292            int pid = Integer.parseInt(process);
16293            synchronized (mPidsSelfLocked) {
16294                proc = mPidsSelfLocked.get(pid);
16295            }
16296        } catch (NumberFormatException e) {
16297        }
16298
16299        if (proc == null) {
16300            ArrayMap<String, SparseArray<ProcessRecord>> all
16301                    = mProcessNames.getMap();
16302            SparseArray<ProcessRecord> procs = all.get(process);
16303            if (procs != null && procs.size() > 0) {
16304                proc = procs.valueAt(0);
16305                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16306                    for (int i=1; i<procs.size(); i++) {
16307                        ProcessRecord thisProc = procs.valueAt(i);
16308                        if (thisProc.userId == userId) {
16309                            proc = thisProc;
16310                            break;
16311                        }
16312                    }
16313                }
16314            }
16315        }
16316
16317        return proc;
16318    }
16319
16320    public boolean dumpHeap(String process, int userId, boolean managed,
16321            String path, ParcelFileDescriptor fd) throws RemoteException {
16322
16323        try {
16324            synchronized (this) {
16325                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16326                // its own permission (same as profileControl).
16327                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16328                        != PackageManager.PERMISSION_GRANTED) {
16329                    throw new SecurityException("Requires permission "
16330                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16331                }
16332
16333                if (fd == null) {
16334                    throw new IllegalArgumentException("null fd");
16335                }
16336
16337                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16338                if (proc == null || proc.thread == null) {
16339                    throw new IllegalArgumentException("Unknown process: " + process);
16340                }
16341
16342                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16343                if (!isDebuggable) {
16344                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16345                        throw new SecurityException("Process not debuggable: " + proc);
16346                    }
16347                }
16348
16349                proc.thread.dumpHeap(managed, path, fd);
16350                fd = null;
16351                return true;
16352            }
16353        } catch (RemoteException e) {
16354            throw new IllegalStateException("Process disappeared");
16355        } finally {
16356            if (fd != null) {
16357                try {
16358                    fd.close();
16359                } catch (IOException e) {
16360                }
16361            }
16362        }
16363    }
16364
16365    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16366    public void monitor() {
16367        synchronized (this) { }
16368    }
16369
16370    void onCoreSettingsChange(Bundle settings) {
16371        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16372            ProcessRecord processRecord = mLruProcesses.get(i);
16373            try {
16374                if (processRecord.thread != null) {
16375                    processRecord.thread.setCoreSettings(settings);
16376                }
16377            } catch (RemoteException re) {
16378                /* ignore */
16379            }
16380        }
16381    }
16382
16383    // Multi-user methods
16384
16385    /**
16386     * Start user, if its not already running, but don't bring it to foreground.
16387     */
16388    @Override
16389    public boolean startUserInBackground(final int userId) {
16390        return startUser(userId, /* foreground */ false);
16391    }
16392
16393    /**
16394     * Refreshes the list of users related to the current user when either a
16395     * user switch happens or when a new related user is started in the
16396     * background.
16397     */
16398    private void updateCurrentProfileIdsLocked() {
16399        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16400                mCurrentUserId, false /* enabledOnly */);
16401        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16402        for (int i = 0; i < currentProfileIds.length; i++) {
16403            currentProfileIds[i] = profiles.get(i).id;
16404        }
16405        mCurrentProfileIds = currentProfileIds;
16406    }
16407
16408    private Set getProfileIdsLocked(int userId) {
16409        Set userIds = new HashSet<Integer>();
16410        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16411                userId, false /* enabledOnly */);
16412        for (UserInfo user : profiles) {
16413            userIds.add(Integer.valueOf(user.id));
16414        }
16415        return userIds;
16416    }
16417
16418    @Override
16419    public boolean switchUser(final int userId) {
16420        return startUser(userId, /* foregound */ true);
16421    }
16422
16423    private boolean startUser(final int userId, boolean foreground) {
16424        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16425                != PackageManager.PERMISSION_GRANTED) {
16426            String msg = "Permission Denial: switchUser() from pid="
16427                    + Binder.getCallingPid()
16428                    + ", uid=" + Binder.getCallingUid()
16429                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16430            Slog.w(TAG, msg);
16431            throw new SecurityException(msg);
16432        }
16433
16434        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16435
16436        final long ident = Binder.clearCallingIdentity();
16437        try {
16438            synchronized (this) {
16439                final int oldUserId = mCurrentUserId;
16440                if (oldUserId == userId) {
16441                    return true;
16442                }
16443
16444                mStackSupervisor.setLockTaskModeLocked(null);
16445
16446                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16447                if (userInfo == null) {
16448                    Slog.w(TAG, "No user info for user #" + userId);
16449                    return false;
16450                }
16451
16452                if (foreground) {
16453                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16454                            R.anim.screen_user_enter);
16455                }
16456
16457                boolean needStart = false;
16458
16459                // If the user we are switching to is not currently started, then
16460                // we need to start it now.
16461                if (mStartedUsers.get(userId) == null) {
16462                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16463                    updateStartedUserArrayLocked();
16464                    needStart = true;
16465                }
16466
16467                final Integer userIdInt = Integer.valueOf(userId);
16468                mUserLru.remove(userIdInt);
16469                mUserLru.add(userIdInt);
16470
16471                if (foreground) {
16472                    mCurrentUserId = userId;
16473                    updateCurrentProfileIdsLocked();
16474                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16475                    // Once the internal notion of the active user has switched, we lock the device
16476                    // with the option to show the user switcher on the keyguard.
16477                    mWindowManager.lockNow(null);
16478                } else {
16479                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16480                    updateCurrentProfileIdsLocked();
16481                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16482                    mUserLru.remove(currentUserIdInt);
16483                    mUserLru.add(currentUserIdInt);
16484                }
16485
16486                final UserStartedState uss = mStartedUsers.get(userId);
16487
16488                // Make sure user is in the started state.  If it is currently
16489                // stopping, we need to knock that off.
16490                if (uss.mState == UserStartedState.STATE_STOPPING) {
16491                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16492                    // so we can just fairly silently bring the user back from
16493                    // the almost-dead.
16494                    uss.mState = UserStartedState.STATE_RUNNING;
16495                    updateStartedUserArrayLocked();
16496                    needStart = true;
16497                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16498                    // This means ACTION_SHUTDOWN has been sent, so we will
16499                    // need to treat this as a new boot of the user.
16500                    uss.mState = UserStartedState.STATE_BOOTING;
16501                    updateStartedUserArrayLocked();
16502                    needStart = true;
16503                }
16504
16505                if (uss.mState == UserStartedState.STATE_BOOTING) {
16506                    // Booting up a new user, need to tell system services about it.
16507                    // Note that this is on the same handler as scheduling of broadcasts,
16508                    // which is important because it needs to go first.
16509                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16510                }
16511
16512                if (foreground) {
16513                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16514                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16515                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16516                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16517                            oldUserId, userId, uss));
16518                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16519                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16520                }
16521
16522                if (needStart) {
16523                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16524                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16525                            | Intent.FLAG_RECEIVER_FOREGROUND);
16526                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16527                    broadcastIntentLocked(null, null, intent,
16528                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16529                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16530                }
16531
16532                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16533                    if (userId != UserHandle.USER_OWNER) {
16534                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16535                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16536                        broadcastIntentLocked(null, null, intent, null,
16537                                new IIntentReceiver.Stub() {
16538                                    public void performReceive(Intent intent, int resultCode,
16539                                            String data, Bundle extras, boolean ordered,
16540                                            boolean sticky, int sendingUser) {
16541                                        userInitialized(uss, userId);
16542                                    }
16543                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16544                                true, false, MY_PID, Process.SYSTEM_UID,
16545                                userId);
16546                        uss.initializing = true;
16547                    } else {
16548                        getUserManagerLocked().makeInitialized(userInfo.id);
16549                    }
16550                }
16551
16552                if (foreground) {
16553                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16554                    if (homeInFront) {
16555                        startHomeActivityLocked(userId);
16556                    } else {
16557                        mStackSupervisor.resumeTopActivitiesLocked();
16558                    }
16559                    EventLogTags.writeAmSwitchUser(userId);
16560                    getUserManagerLocked().userForeground(userId);
16561                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16562                } else {
16563                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16564                }
16565
16566                if (needStart) {
16567                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16568                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16569                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16570                    broadcastIntentLocked(null, null, intent,
16571                            null, new IIntentReceiver.Stub() {
16572                                @Override
16573                                public void performReceive(Intent intent, int resultCode, String data,
16574                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16575                                        throws RemoteException {
16576                                }
16577                            }, 0, null, null,
16578                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16579                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16580                }
16581            }
16582        } finally {
16583            Binder.restoreCallingIdentity(ident);
16584        }
16585
16586        return true;
16587    }
16588
16589    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16590        long ident = Binder.clearCallingIdentity();
16591        try {
16592            Intent intent;
16593            if (oldUserId >= 0) {
16594                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16595                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16596                        | Intent.FLAG_RECEIVER_FOREGROUND);
16597                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16598                broadcastIntentLocked(null, null, intent,
16599                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16600                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16601            }
16602            if (newUserId >= 0) {
16603                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16604                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16605                        | Intent.FLAG_RECEIVER_FOREGROUND);
16606                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16607                broadcastIntentLocked(null, null, intent,
16608                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16609                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16610                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16611                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16612                        | Intent.FLAG_RECEIVER_FOREGROUND);
16613                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16614                broadcastIntentLocked(null, null, intent,
16615                        null, null, 0, null, null,
16616                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16617                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16618            }
16619        } finally {
16620            Binder.restoreCallingIdentity(ident);
16621        }
16622    }
16623
16624    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16625            final int newUserId) {
16626        final int N = mUserSwitchObservers.beginBroadcast();
16627        if (N > 0) {
16628            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16629                int mCount = 0;
16630                @Override
16631                public void sendResult(Bundle data) throws RemoteException {
16632                    synchronized (ActivityManagerService.this) {
16633                        if (mCurUserSwitchCallback == this) {
16634                            mCount++;
16635                            if (mCount == N) {
16636                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16637                            }
16638                        }
16639                    }
16640                }
16641            };
16642            synchronized (this) {
16643                uss.switching = true;
16644                mCurUserSwitchCallback = callback;
16645            }
16646            for (int i=0; i<N; i++) {
16647                try {
16648                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16649                            newUserId, callback);
16650                } catch (RemoteException e) {
16651                }
16652            }
16653        } else {
16654            synchronized (this) {
16655                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16656            }
16657        }
16658        mUserSwitchObservers.finishBroadcast();
16659    }
16660
16661    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16662        synchronized (this) {
16663            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16664            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16665        }
16666    }
16667
16668    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16669        mCurUserSwitchCallback = null;
16670        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16671        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16672                oldUserId, newUserId, uss));
16673    }
16674
16675    void userInitialized(UserStartedState uss, int newUserId) {
16676        completeSwitchAndInitalize(uss, newUserId, true, false);
16677    }
16678
16679    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16680        completeSwitchAndInitalize(uss, newUserId, false, true);
16681    }
16682
16683    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16684            boolean clearInitializing, boolean clearSwitching) {
16685        boolean unfrozen = false;
16686        synchronized (this) {
16687            if (clearInitializing) {
16688                uss.initializing = false;
16689                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16690            }
16691            if (clearSwitching) {
16692                uss.switching = false;
16693            }
16694            if (!uss.switching && !uss.initializing) {
16695                mWindowManager.stopFreezingScreen();
16696                unfrozen = true;
16697            }
16698        }
16699        if (unfrozen) {
16700            final int N = mUserSwitchObservers.beginBroadcast();
16701            for (int i=0; i<N; i++) {
16702                try {
16703                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16704                } catch (RemoteException e) {
16705                }
16706            }
16707            mUserSwitchObservers.finishBroadcast();
16708        }
16709    }
16710
16711    void scheduleStartProfilesLocked() {
16712        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16713            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16714                    DateUtils.SECOND_IN_MILLIS);
16715        }
16716    }
16717
16718    void startProfilesLocked() {
16719        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16720        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16721                mCurrentUserId, false /* enabledOnly */);
16722        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16723        for (UserInfo user : profiles) {
16724            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16725                    && user.id != mCurrentUserId) {
16726                toStart.add(user);
16727            }
16728        }
16729        final int n = toStart.size();
16730        int i = 0;
16731        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16732            startUserInBackground(toStart.get(i).id);
16733        }
16734        if (i < n) {
16735            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16736        }
16737    }
16738
16739    void finishUserBoot(UserStartedState uss) {
16740        synchronized (this) {
16741            if (uss.mState == UserStartedState.STATE_BOOTING
16742                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16743                uss.mState = UserStartedState.STATE_RUNNING;
16744                final int userId = uss.mHandle.getIdentifier();
16745                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16746                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16747                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16748                broadcastIntentLocked(null, null, intent,
16749                        null, null, 0, null, null,
16750                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16751                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16752            }
16753        }
16754    }
16755
16756    void finishUserSwitch(UserStartedState uss) {
16757        synchronized (this) {
16758            finishUserBoot(uss);
16759
16760            startProfilesLocked();
16761
16762            int num = mUserLru.size();
16763            int i = 0;
16764            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16765                Integer oldUserId = mUserLru.get(i);
16766                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16767                if (oldUss == null) {
16768                    // Shouldn't happen, but be sane if it does.
16769                    mUserLru.remove(i);
16770                    num--;
16771                    continue;
16772                }
16773                if (oldUss.mState == UserStartedState.STATE_STOPPING
16774                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16775                    // This user is already stopping, doesn't count.
16776                    num--;
16777                    i++;
16778                    continue;
16779                }
16780                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16781                    // Owner and current can't be stopped, but count as running.
16782                    i++;
16783                    continue;
16784                }
16785                // This is a user to be stopped.
16786                stopUserLocked(oldUserId, null);
16787                num--;
16788                i++;
16789            }
16790        }
16791    }
16792
16793    @Override
16794    public int stopUser(final int userId, final IStopUserCallback callback) {
16795        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16796                != PackageManager.PERMISSION_GRANTED) {
16797            String msg = "Permission Denial: switchUser() from pid="
16798                    + Binder.getCallingPid()
16799                    + ", uid=" + Binder.getCallingUid()
16800                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16801            Slog.w(TAG, msg);
16802            throw new SecurityException(msg);
16803        }
16804        if (userId <= 0) {
16805            throw new IllegalArgumentException("Can't stop primary user " + userId);
16806        }
16807        synchronized (this) {
16808            return stopUserLocked(userId, callback);
16809        }
16810    }
16811
16812    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16813        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16814        if (mCurrentUserId == userId) {
16815            return ActivityManager.USER_OP_IS_CURRENT;
16816        }
16817
16818        final UserStartedState uss = mStartedUsers.get(userId);
16819        if (uss == null) {
16820            // User is not started, nothing to do...  but we do need to
16821            // callback if requested.
16822            if (callback != null) {
16823                mHandler.post(new Runnable() {
16824                    @Override
16825                    public void run() {
16826                        try {
16827                            callback.userStopped(userId);
16828                        } catch (RemoteException e) {
16829                        }
16830                    }
16831                });
16832            }
16833            return ActivityManager.USER_OP_SUCCESS;
16834        }
16835
16836        if (callback != null) {
16837            uss.mStopCallbacks.add(callback);
16838        }
16839
16840        if (uss.mState != UserStartedState.STATE_STOPPING
16841                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16842            uss.mState = UserStartedState.STATE_STOPPING;
16843            updateStartedUserArrayLocked();
16844
16845            long ident = Binder.clearCallingIdentity();
16846            try {
16847                // We are going to broadcast ACTION_USER_STOPPING and then
16848                // once that is done send a final ACTION_SHUTDOWN and then
16849                // stop the user.
16850                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16851                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16852                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16853                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16854                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16855                // This is the result receiver for the final shutdown broadcast.
16856                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16857                    @Override
16858                    public void performReceive(Intent intent, int resultCode, String data,
16859                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16860                        finishUserStop(uss);
16861                    }
16862                };
16863                // This is the result receiver for the initial stopping broadcast.
16864                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16865                    @Override
16866                    public void performReceive(Intent intent, int resultCode, String data,
16867                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16868                        // On to the next.
16869                        synchronized (ActivityManagerService.this) {
16870                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16871                                // Whoops, we are being started back up.  Abort, abort!
16872                                return;
16873                            }
16874                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16875                        }
16876                        mSystemServiceManager.stopUser(userId);
16877                        broadcastIntentLocked(null, null, shutdownIntent,
16878                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16879                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16880                    }
16881                };
16882                // Kick things off.
16883                broadcastIntentLocked(null, null, stoppingIntent,
16884                        null, stoppingReceiver, 0, null, null,
16885                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16886                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16887            } finally {
16888                Binder.restoreCallingIdentity(ident);
16889            }
16890        }
16891
16892        return ActivityManager.USER_OP_SUCCESS;
16893    }
16894
16895    void finishUserStop(UserStartedState uss) {
16896        final int userId = uss.mHandle.getIdentifier();
16897        boolean stopped;
16898        ArrayList<IStopUserCallback> callbacks;
16899        synchronized (this) {
16900            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16901            if (mStartedUsers.get(userId) != uss) {
16902                stopped = false;
16903            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16904                stopped = false;
16905            } else {
16906                stopped = true;
16907                // User can no longer run.
16908                mStartedUsers.remove(userId);
16909                mUserLru.remove(Integer.valueOf(userId));
16910                updateStartedUserArrayLocked();
16911
16912                // Clean up all state and processes associated with the user.
16913                // Kill all the processes for the user.
16914                forceStopUserLocked(userId, "finish user");
16915            }
16916        }
16917
16918        for (int i=0; i<callbacks.size(); i++) {
16919            try {
16920                if (stopped) callbacks.get(i).userStopped(userId);
16921                else callbacks.get(i).userStopAborted(userId);
16922            } catch (RemoteException e) {
16923            }
16924        }
16925
16926        if (stopped) {
16927            mSystemServiceManager.cleanupUser(userId);
16928            synchronized (this) {
16929                mStackSupervisor.removeUserLocked(userId);
16930            }
16931        }
16932    }
16933
16934    @Override
16935    public UserInfo getCurrentUser() {
16936        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16937                != PackageManager.PERMISSION_GRANTED) && (
16938                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16939                != PackageManager.PERMISSION_GRANTED)) {
16940            String msg = "Permission Denial: getCurrentUser() from pid="
16941                    + Binder.getCallingPid()
16942                    + ", uid=" + Binder.getCallingUid()
16943                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16944            Slog.w(TAG, msg);
16945            throw new SecurityException(msg);
16946        }
16947        synchronized (this) {
16948            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16949        }
16950    }
16951
16952    int getCurrentUserIdLocked() {
16953        return mCurrentUserId;
16954    }
16955
16956    @Override
16957    public boolean isUserRunning(int userId, boolean orStopped) {
16958        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16959                != PackageManager.PERMISSION_GRANTED) {
16960            String msg = "Permission Denial: isUserRunning() from pid="
16961                    + Binder.getCallingPid()
16962                    + ", uid=" + Binder.getCallingUid()
16963                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16964            Slog.w(TAG, msg);
16965            throw new SecurityException(msg);
16966        }
16967        synchronized (this) {
16968            return isUserRunningLocked(userId, orStopped);
16969        }
16970    }
16971
16972    boolean isUserRunningLocked(int userId, boolean orStopped) {
16973        UserStartedState state = mStartedUsers.get(userId);
16974        if (state == null) {
16975            return false;
16976        }
16977        if (orStopped) {
16978            return true;
16979        }
16980        return state.mState != UserStartedState.STATE_STOPPING
16981                && state.mState != UserStartedState.STATE_SHUTDOWN;
16982    }
16983
16984    @Override
16985    public int[] getRunningUserIds() {
16986        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16987                != PackageManager.PERMISSION_GRANTED) {
16988            String msg = "Permission Denial: isUserRunning() from pid="
16989                    + Binder.getCallingPid()
16990                    + ", uid=" + Binder.getCallingUid()
16991                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16992            Slog.w(TAG, msg);
16993            throw new SecurityException(msg);
16994        }
16995        synchronized (this) {
16996            return mStartedUserArray;
16997        }
16998    }
16999
17000    private void updateStartedUserArrayLocked() {
17001        int num = 0;
17002        for (int i=0; i<mStartedUsers.size();  i++) {
17003            UserStartedState uss = mStartedUsers.valueAt(i);
17004            // This list does not include stopping users.
17005            if (uss.mState != UserStartedState.STATE_STOPPING
17006                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17007                num++;
17008            }
17009        }
17010        mStartedUserArray = new int[num];
17011        num = 0;
17012        for (int i=0; i<mStartedUsers.size();  i++) {
17013            UserStartedState uss = mStartedUsers.valueAt(i);
17014            if (uss.mState != UserStartedState.STATE_STOPPING
17015                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17016                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17017                num++;
17018            }
17019        }
17020    }
17021
17022    @Override
17023    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17024        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17025                != PackageManager.PERMISSION_GRANTED) {
17026            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17027                    + Binder.getCallingPid()
17028                    + ", uid=" + Binder.getCallingUid()
17029                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17030            Slog.w(TAG, msg);
17031            throw new SecurityException(msg);
17032        }
17033
17034        mUserSwitchObservers.register(observer);
17035    }
17036
17037    @Override
17038    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17039        mUserSwitchObservers.unregister(observer);
17040    }
17041
17042    private boolean userExists(int userId) {
17043        if (userId == 0) {
17044            return true;
17045        }
17046        UserManagerService ums = getUserManagerLocked();
17047        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17048    }
17049
17050    int[] getUsersLocked() {
17051        UserManagerService ums = getUserManagerLocked();
17052        return ums != null ? ums.getUserIds() : new int[] { 0 };
17053    }
17054
17055    UserManagerService getUserManagerLocked() {
17056        if (mUserManager == null) {
17057            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17058            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17059        }
17060        return mUserManager;
17061    }
17062
17063    private int applyUserId(int uid, int userId) {
17064        return UserHandle.getUid(userId, uid);
17065    }
17066
17067    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17068        if (info == null) return null;
17069        ApplicationInfo newInfo = new ApplicationInfo(info);
17070        newInfo.uid = applyUserId(info.uid, userId);
17071        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17072                + info.packageName;
17073        return newInfo;
17074    }
17075
17076    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17077        if (aInfo == null
17078                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17079            return aInfo;
17080        }
17081
17082        ActivityInfo info = new ActivityInfo(aInfo);
17083        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17084        return info;
17085    }
17086
17087    private final class LocalService extends ActivityManagerInternal {
17088        @Override
17089        public void goingToSleep() {
17090            ActivityManagerService.this.goingToSleep();
17091        }
17092
17093        @Override
17094        public void wakingUp() {
17095            ActivityManagerService.this.wakingUp();
17096        }
17097    }
17098}
17099