ActivityManagerService.java revision 91097de49b0f683b00e26a75dbc0ac6082344137
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.os.BackgroundThread;
48import com.android.internal.os.BatteryStatsImpl;
49import com.android.internal.os.ProcessCpuTracker;
50import com.android.internal.os.TransferPipe;
51import com.android.internal.os.Zygote;
52import com.android.internal.util.FastPrintWriter;
53import com.android.internal.util.FastXmlSerializer;
54import com.android.internal.util.MemInfoReader;
55import com.android.internal.util.Preconditions;
56import com.android.server.AppOpsService;
57import com.android.server.AttributeCache;
58import com.android.server.IntentResolver;
59import com.android.server.LocalServices;
60import com.android.server.ServiceThread;
61import com.android.server.SystemService;
62import com.android.server.SystemServiceManager;
63import com.android.server.Watchdog;
64import com.android.server.am.ActivityStack.ActivityState;
65import com.android.server.firewall.IntentFirewall;
66import com.android.server.pm.UserManagerService;
67import com.android.server.wm.AppTransition;
68import com.android.server.wm.WindowManagerService;
69import com.google.android.collect.Lists;
70import com.google.android.collect.Maps;
71
72import libcore.io.IoUtils;
73
74import org.xmlpull.v1.XmlPullParser;
75import org.xmlpull.v1.XmlPullParserException;
76import org.xmlpull.v1.XmlSerializer;
77
78import android.app.Activity;
79import android.app.ActivityManager;
80import android.app.ActivityManager.RunningTaskInfo;
81import android.app.ActivityManager.StackInfo;
82import android.app.ActivityManagerInternal;
83import android.app.ActivityManagerNative;
84import android.app.ActivityOptions;
85import android.app.ActivityThread;
86import android.app.AlertDialog;
87import android.app.AppGlobals;
88import android.app.ApplicationErrorReport;
89import android.app.Dialog;
90import android.app.IActivityController;
91import android.app.IApplicationThread;
92import android.app.IInstrumentationWatcher;
93import android.app.INotificationManager;
94import android.app.IProcessObserver;
95import android.app.IServiceConnection;
96import android.app.IStopUserCallback;
97import android.app.IThumbnailReceiver;
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.ProxyProperties;
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    /**
706     * List of PendingThumbnailsRecord objects of clients who are still
707     * waiting to receive all of the thumbnails for a task.
708     */
709    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
710            new ArrayList<PendingThumbnailsRecord>();
711
712    final ProviderMap mProviderMap;
713
714    /**
715     * List of content providers who have clients waiting for them.  The
716     * application is currently being launched and the provider will be
717     * removed from this list once it is published.
718     */
719    final ArrayList<ContentProviderRecord> mLaunchingProviders
720            = new ArrayList<ContentProviderRecord>();
721
722    /**
723     * File storing persisted {@link #mGrantedUriPermissions}.
724     */
725    private final AtomicFile mGrantFile;
726
727    /** XML constants used in {@link #mGrantFile} */
728    private static final String TAG_URI_GRANTS = "uri-grants";
729    private static final String TAG_URI_GRANT = "uri-grant";
730    private static final String ATTR_USER_HANDLE = "userHandle";
731    private static final String ATTR_SOURCE_PKG = "sourcePkg";
732    private static final String ATTR_TARGET_PKG = "targetPkg";
733    private static final String ATTR_URI = "uri";
734    private static final String ATTR_MODE_FLAGS = "modeFlags";
735    private static final String ATTR_CREATED_TIME = "createdTime";
736    private static final String ATTR_PREFIX = "prefix";
737
738    /**
739     * Global set of specific {@link Uri} permissions that have been granted.
740     * This optimized lookup structure maps from {@link UriPermission#targetUid}
741     * to {@link UriPermission#uri} to {@link UriPermission}.
742     */
743    @GuardedBy("this")
744    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
745            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
746
747    public static class GrantUri {
748        public final Uri uri;
749        public final boolean prefix;
750
751        public GrantUri(Uri uri, boolean prefix) {
752            this.uri = uri;
753            this.prefix = prefix;
754        }
755
756        @Override
757        public int hashCode() {
758            return toString().hashCode();
759        }
760
761        @Override
762        public boolean equals(Object o) {
763            if (o instanceof GrantUri) {
764                GrantUri other = (GrantUri) o;
765                return uri.equals(other.uri) && prefix == other.prefix;
766            }
767            return false;
768        }
769
770        @Override
771        public String toString() {
772            if (prefix) {
773                return uri.toString() + " [prefix]";
774            } else {
775                return uri.toString();
776            }
777        }
778    }
779
780    CoreSettingsObserver mCoreSettingsObserver;
781
782    /**
783     * Thread-local storage used to carry caller permissions over through
784     * indirect content-provider access.
785     */
786    private class Identity {
787        public int pid;
788        public int uid;
789
790        Identity(int _pid, int _uid) {
791            pid = _pid;
792            uid = _uid;
793        }
794    }
795
796    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
797
798    /**
799     * All information we have collected about the runtime performance of
800     * any user id that can impact battery performance.
801     */
802    final BatteryStatsService mBatteryStatsService;
803
804    /**
805     * Information about component usage
806     */
807    final UsageStatsService mUsageStatsService;
808
809    /**
810     * Information about and control over application operations
811     */
812    final AppOpsService mAppOpsService;
813
814    /**
815     * Current configuration information.  HistoryRecord objects are given
816     * a reference to this object to indicate which configuration they are
817     * currently running in, so this object must be kept immutable.
818     */
819    Configuration mConfiguration = new Configuration();
820
821    /**
822     * Current sequencing integer of the configuration, for skipping old
823     * configurations.
824     */
825    int mConfigurationSeq = 0;
826
827    /**
828     * Hardware-reported OpenGLES version.
829     */
830    final int GL_ES_VERSION;
831
832    /**
833     * List of initialization arguments to pass to all processes when binding applications to them.
834     * For example, references to the commonly used services.
835     */
836    HashMap<String, IBinder> mAppBindArgs;
837
838    /**
839     * Temporary to avoid allocations.  Protected by main lock.
840     */
841    final StringBuilder mStringBuilder = new StringBuilder(256);
842
843    /**
844     * Used to control how we initialize the service.
845     */
846    ComponentName mTopComponent;
847    String mTopAction = Intent.ACTION_MAIN;
848    String mTopData;
849    boolean mProcessesReady = false;
850    boolean mSystemReady = false;
851    boolean mBooting = false;
852    boolean mWaitingUpdate = false;
853    boolean mDidUpdate = false;
854    boolean mOnBattery = false;
855    boolean mLaunchWarningShown = false;
856
857    Context mContext;
858
859    int mFactoryTest;
860
861    boolean mCheckedForSetup;
862
863    /**
864     * The time at which we will allow normal application switches again,
865     * after a call to {@link #stopAppSwitches()}.
866     */
867    long mAppSwitchesAllowedTime;
868
869    /**
870     * This is set to true after the first switch after mAppSwitchesAllowedTime
871     * is set; any switches after that will clear the time.
872     */
873    boolean mDidAppSwitch;
874
875    /**
876     * Last time (in realtime) at which we checked for power usage.
877     */
878    long mLastPowerCheckRealtime;
879
880    /**
881     * Last time (in uptime) at which we checked for power usage.
882     */
883    long mLastPowerCheckUptime;
884
885    /**
886     * Set while we are wanting to sleep, to prevent any
887     * activities from being started/resumed.
888     */
889    private boolean mSleeping = false;
890
891    /**
892     * Set while we are running a voice interaction.  This overrides
893     * sleeping while it is active.
894     */
895    private boolean mRunningVoice = false;
896
897    /**
898     * State of external calls telling us if the device is asleep.
899     */
900    private boolean mWentToSleep = false;
901
902    /**
903     * State of external call telling us if the lock screen is shown.
904     */
905    private boolean mLockScreenShown = false;
906
907    /**
908     * Set if we are shutting down the system, similar to sleeping.
909     */
910    boolean mShuttingDown = false;
911
912    /**
913     * Current sequence id for oom_adj computation traversal.
914     */
915    int mAdjSeq = 0;
916
917    /**
918     * Current sequence id for process LRU updating.
919     */
920    int mLruSeq = 0;
921
922    /**
923     * Keep track of the non-cached/empty process we last found, to help
924     * determine how to distribute cached/empty processes next time.
925     */
926    int mNumNonCachedProcs = 0;
927
928    /**
929     * Keep track of the number of cached hidden procs, to balance oom adj
930     * distribution between those and empty procs.
931     */
932    int mNumCachedHiddenProcs = 0;
933
934    /**
935     * Keep track of the number of service processes we last found, to
936     * determine on the next iteration which should be B services.
937     */
938    int mNumServiceProcs = 0;
939    int mNewNumAServiceProcs = 0;
940    int mNewNumServiceProcs = 0;
941
942    /**
943     * Allow the current computed overall memory level of the system to go down?
944     * This is set to false when we are killing processes for reasons other than
945     * memory management, so that the now smaller process list will not be taken as
946     * an indication that memory is tighter.
947     */
948    boolean mAllowLowerMemLevel = false;
949
950    /**
951     * The last computed memory level, for holding when we are in a state that
952     * processes are going away for other reasons.
953     */
954    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
955
956    /**
957     * The last total number of process we have, to determine if changes actually look
958     * like a shrinking number of process due to lower RAM.
959     */
960    int mLastNumProcesses;
961
962    /**
963     * The uptime of the last time we performed idle maintenance.
964     */
965    long mLastIdleTime = SystemClock.uptimeMillis();
966
967    /**
968     * Total time spent with RAM that has been added in the past since the last idle time.
969     */
970    long mLowRamTimeSinceLastIdle = 0;
971
972    /**
973     * If RAM is currently low, when that horrible situation started.
974     */
975    long mLowRamStartTime = 0;
976
977    /**
978     * For reporting to battery stats the current top application.
979     */
980    private String mCurResumedPackage = null;
981    private int mCurResumedUid = -1;
982
983    /**
984     * For reporting to battery stats the apps currently running foreground
985     * service.  The ProcessMap is package/uid tuples; each of these contain
986     * an array of the currently foreground processes.
987     */
988    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
989            = new ProcessMap<ArrayList<ProcessRecord>>();
990
991    /**
992     * This is set if we had to do a delayed dexopt of an app before launching
993     * it, to increasing the ANR timeouts in that case.
994     */
995    boolean mDidDexOpt;
996
997    /**
998     * Set if the systemServer made a call to enterSafeMode.
999     */
1000    boolean mSafeMode;
1001
1002    String mDebugApp = null;
1003    boolean mWaitForDebugger = false;
1004    boolean mDebugTransient = false;
1005    String mOrigDebugApp = null;
1006    boolean mOrigWaitForDebugger = false;
1007    boolean mAlwaysFinishActivities = false;
1008    IActivityController mController = null;
1009    String mProfileApp = null;
1010    ProcessRecord mProfileProc = null;
1011    String mProfileFile;
1012    ParcelFileDescriptor mProfileFd;
1013    int mProfileType = 0;
1014    boolean mAutoStopProfiler = false;
1015    String mOpenGlTraceApp = null;
1016
1017    static class ProcessChangeItem {
1018        static final int CHANGE_ACTIVITIES = 1<<0;
1019        static final int CHANGE_IMPORTANCE= 1<<1;
1020        int changes;
1021        int uid;
1022        int pid;
1023        int importance;
1024        boolean foregroundActivities;
1025    }
1026
1027    final RemoteCallbackList<IProcessObserver> mProcessObservers
1028            = new RemoteCallbackList<IProcessObserver>();
1029    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1030
1031    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1032            = new ArrayList<ProcessChangeItem>();
1033    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1034            = new ArrayList<ProcessChangeItem>();
1035
1036    /**
1037     * Runtime CPU use collection thread.  This object's lock is used to
1038     * protect all related state.
1039     */
1040    final Thread mProcessCpuThread;
1041
1042    /**
1043     * Used to collect process stats when showing not responding dialog.
1044     * Protected by mProcessCpuThread.
1045     */
1046    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1047            MONITOR_THREAD_CPU_USAGE);
1048    final AtomicLong mLastCpuTime = new AtomicLong(0);
1049    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1050
1051    long mLastWriteTime = 0;
1052
1053    /**
1054     * Used to retain an update lock when the foreground activity is in
1055     * immersive mode.
1056     */
1057    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1058
1059    /**
1060     * Set to true after the system has finished booting.
1061     */
1062    boolean mBooted = false;
1063
1064    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1065    int mProcessLimitOverride = -1;
1066
1067    WindowManagerService mWindowManager;
1068
1069    final ActivityThread mSystemThread;
1070
1071    int mCurrentUserId = 0;
1072    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1073    private UserManagerService mUserManager;
1074
1075    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1076        final ProcessRecord mApp;
1077        final int mPid;
1078        final IApplicationThread mAppThread;
1079
1080        AppDeathRecipient(ProcessRecord app, int pid,
1081                IApplicationThread thread) {
1082            if (localLOGV) Slog.v(
1083                TAG, "New death recipient " + this
1084                + " for thread " + thread.asBinder());
1085            mApp = app;
1086            mPid = pid;
1087            mAppThread = thread;
1088        }
1089
1090        @Override
1091        public void binderDied() {
1092            if (localLOGV) Slog.v(
1093                TAG, "Death received in " + this
1094                + " for thread " + mAppThread.asBinder());
1095            synchronized(ActivityManagerService.this) {
1096                appDiedLocked(mApp, mPid, mAppThread);
1097            }
1098        }
1099    }
1100
1101    static final int SHOW_ERROR_MSG = 1;
1102    static final int SHOW_NOT_RESPONDING_MSG = 2;
1103    static final int SHOW_FACTORY_ERROR_MSG = 3;
1104    static final int UPDATE_CONFIGURATION_MSG = 4;
1105    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1106    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1107    static final int SERVICE_TIMEOUT_MSG = 12;
1108    static final int UPDATE_TIME_ZONE = 13;
1109    static final int SHOW_UID_ERROR_MSG = 14;
1110    static final int IM_FEELING_LUCKY_MSG = 15;
1111    static final int PROC_START_TIMEOUT_MSG = 20;
1112    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1113    static final int KILL_APPLICATION_MSG = 22;
1114    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1115    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1116    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1117    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1118    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1119    static final int CLEAR_DNS_CACHE_MSG = 28;
1120    static final int UPDATE_HTTP_PROXY_MSG = 29;
1121    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1122    static final int DISPATCH_PROCESSES_CHANGED = 31;
1123    static final int DISPATCH_PROCESS_DIED = 32;
1124    static final int REPORT_MEM_USAGE_MSG = 33;
1125    static final int REPORT_USER_SWITCH_MSG = 34;
1126    static final int CONTINUE_USER_SWITCH_MSG = 35;
1127    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1128    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1129    static final int PERSIST_URI_GRANTS_MSG = 38;
1130    static final int REQUEST_ALL_PSS_MSG = 39;
1131    static final int START_PROFILES_MSG = 40;
1132    static final int UPDATE_TIME = 41;
1133    static final int SYSTEM_USER_START_MSG = 42;
1134    static final int SYSTEM_USER_CURRENT_MSG = 43;
1135
1136    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1137    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1138    static final int FIRST_COMPAT_MODE_MSG = 300;
1139    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1140
1141    AlertDialog mUidAlert;
1142    CompatModeDialog mCompatModeDialog;
1143    long mLastMemUsageReportTime = 0;
1144
1145    /**
1146     * Flag whether the current user is a "monkey", i.e. whether
1147     * the UI is driven by a UI automation tool.
1148     */
1149    private boolean mUserIsMonkey;
1150
1151    final ServiceThread mHandlerThread;
1152    final MainHandler mHandler;
1153
1154    final class MainHandler extends Handler {
1155        public MainHandler(Looper looper) {
1156            super(looper, null, true);
1157        }
1158
1159        @Override
1160        public void handleMessage(Message msg) {
1161            switch (msg.what) {
1162            case SHOW_ERROR_MSG: {
1163                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1164                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1165                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1166                synchronized (ActivityManagerService.this) {
1167                    ProcessRecord proc = (ProcessRecord)data.get("app");
1168                    AppErrorResult res = (AppErrorResult) data.get("result");
1169                    if (proc != null && proc.crashDialog != null) {
1170                        Slog.e(TAG, "App already has crash dialog: " + proc);
1171                        if (res != null) {
1172                            res.set(0);
1173                        }
1174                        return;
1175                    }
1176                    if (!showBackground && UserHandle.getAppId(proc.uid)
1177                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1178                            && proc.pid != MY_PID) {
1179                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1180                        if (res != null) {
1181                            res.set(0);
1182                        }
1183                        return;
1184                    }
1185                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1186                        Dialog d = new AppErrorDialog(mContext,
1187                                ActivityManagerService.this, res, proc);
1188                        d.show();
1189                        proc.crashDialog = d;
1190                    } else {
1191                        // The device is asleep, so just pretend that the user
1192                        // saw a crash dialog and hit "force quit".
1193                        if (res != null) {
1194                            res.set(0);
1195                        }
1196                    }
1197                }
1198
1199                ensureBootCompleted();
1200            } break;
1201            case SHOW_NOT_RESPONDING_MSG: {
1202                synchronized (ActivityManagerService.this) {
1203                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1204                    ProcessRecord proc = (ProcessRecord)data.get("app");
1205                    if (proc != null && proc.anrDialog != null) {
1206                        Slog.e(TAG, "App already has anr dialog: " + proc);
1207                        return;
1208                    }
1209
1210                    Intent intent = new Intent("android.intent.action.ANR");
1211                    if (!mProcessesReady) {
1212                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1213                                | Intent.FLAG_RECEIVER_FOREGROUND);
1214                    }
1215                    broadcastIntentLocked(null, null, intent,
1216                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1217                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1218
1219                    if (mShowDialogs) {
1220                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1221                                mContext, proc, (ActivityRecord)data.get("activity"),
1222                                msg.arg1 != 0);
1223                        d.show();
1224                        proc.anrDialog = d;
1225                    } else {
1226                        // Just kill the app if there is no dialog to be shown.
1227                        killAppAtUsersRequest(proc, null);
1228                    }
1229                }
1230
1231                ensureBootCompleted();
1232            } break;
1233            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1234                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1235                synchronized (ActivityManagerService.this) {
1236                    ProcessRecord proc = (ProcessRecord) data.get("app");
1237                    if (proc == null) {
1238                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1239                        break;
1240                    }
1241                    if (proc.crashDialog != null) {
1242                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1243                        return;
1244                    }
1245                    AppErrorResult res = (AppErrorResult) data.get("result");
1246                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1247                        Dialog d = new StrictModeViolationDialog(mContext,
1248                                ActivityManagerService.this, res, proc);
1249                        d.show();
1250                        proc.crashDialog = d;
1251                    } else {
1252                        // The device is asleep, so just pretend that the user
1253                        // saw a crash dialog and hit "force quit".
1254                        res.set(0);
1255                    }
1256                }
1257                ensureBootCompleted();
1258            } break;
1259            case SHOW_FACTORY_ERROR_MSG: {
1260                Dialog d = new FactoryErrorDialog(
1261                    mContext, msg.getData().getCharSequence("msg"));
1262                d.show();
1263                ensureBootCompleted();
1264            } break;
1265            case UPDATE_CONFIGURATION_MSG: {
1266                final ContentResolver resolver = mContext.getContentResolver();
1267                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1268            } break;
1269            case GC_BACKGROUND_PROCESSES_MSG: {
1270                synchronized (ActivityManagerService.this) {
1271                    performAppGcsIfAppropriateLocked();
1272                }
1273            } break;
1274            case WAIT_FOR_DEBUGGER_MSG: {
1275                synchronized (ActivityManagerService.this) {
1276                    ProcessRecord app = (ProcessRecord)msg.obj;
1277                    if (msg.arg1 != 0) {
1278                        if (!app.waitedForDebugger) {
1279                            Dialog d = new AppWaitingForDebuggerDialog(
1280                                    ActivityManagerService.this,
1281                                    mContext, app);
1282                            app.waitDialog = d;
1283                            app.waitedForDebugger = true;
1284                            d.show();
1285                        }
1286                    } else {
1287                        if (app.waitDialog != null) {
1288                            app.waitDialog.dismiss();
1289                            app.waitDialog = null;
1290                        }
1291                    }
1292                }
1293            } break;
1294            case SERVICE_TIMEOUT_MSG: {
1295                if (mDidDexOpt) {
1296                    mDidDexOpt = false;
1297                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1298                    nmsg.obj = msg.obj;
1299                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1300                    return;
1301                }
1302                mServices.serviceTimeout((ProcessRecord)msg.obj);
1303            } break;
1304            case UPDATE_TIME_ZONE: {
1305                synchronized (ActivityManagerService.this) {
1306                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1307                        ProcessRecord r = mLruProcesses.get(i);
1308                        if (r.thread != null) {
1309                            try {
1310                                r.thread.updateTimeZone();
1311                            } catch (RemoteException ex) {
1312                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1313                            }
1314                        }
1315                    }
1316                }
1317            } break;
1318            case CLEAR_DNS_CACHE_MSG: {
1319                synchronized (ActivityManagerService.this) {
1320                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1321                        ProcessRecord r = mLruProcesses.get(i);
1322                        if (r.thread != null) {
1323                            try {
1324                                r.thread.clearDnsCache();
1325                            } catch (RemoteException ex) {
1326                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1327                            }
1328                        }
1329                    }
1330                }
1331            } break;
1332            case UPDATE_HTTP_PROXY_MSG: {
1333                ProxyProperties proxy = (ProxyProperties)msg.obj;
1334                String host = "";
1335                String port = "";
1336                String exclList = "";
1337                String pacFileUrl = null;
1338                if (proxy != null) {
1339                    host = proxy.getHost();
1340                    port = Integer.toString(proxy.getPort());
1341                    exclList = proxy.getExclusionList();
1342                    pacFileUrl = proxy.getPacFileUrl();
1343                }
1344                synchronized (ActivityManagerService.this) {
1345                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1346                        ProcessRecord r = mLruProcesses.get(i);
1347                        if (r.thread != null) {
1348                            try {
1349                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1350                            } catch (RemoteException ex) {
1351                                Slog.w(TAG, "Failed to update http proxy for: " +
1352                                        r.info.processName);
1353                            }
1354                        }
1355                    }
1356                }
1357            } break;
1358            case SHOW_UID_ERROR_MSG: {
1359                String title = "System UIDs Inconsistent";
1360                String text = "UIDs on the system are inconsistent, you need to wipe your"
1361                        + " data partition or your device will be unstable.";
1362                Log.e(TAG, title + ": " + text);
1363                if (mShowDialogs) {
1364                    // XXX This is a temporary dialog, no need to localize.
1365                    AlertDialog d = new BaseErrorDialog(mContext);
1366                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1367                    d.setCancelable(false);
1368                    d.setTitle(title);
1369                    d.setMessage(text);
1370                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1371                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1372                    mUidAlert = d;
1373                    d.show();
1374                }
1375            } break;
1376            case IM_FEELING_LUCKY_MSG: {
1377                if (mUidAlert != null) {
1378                    mUidAlert.dismiss();
1379                    mUidAlert = null;
1380                }
1381            } break;
1382            case PROC_START_TIMEOUT_MSG: {
1383                if (mDidDexOpt) {
1384                    mDidDexOpt = false;
1385                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1386                    nmsg.obj = msg.obj;
1387                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1388                    return;
1389                }
1390                ProcessRecord app = (ProcessRecord)msg.obj;
1391                synchronized (ActivityManagerService.this) {
1392                    processStartTimedOutLocked(app);
1393                }
1394            } break;
1395            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1396                synchronized (ActivityManagerService.this) {
1397                    doPendingActivityLaunchesLocked(true);
1398                }
1399            } break;
1400            case KILL_APPLICATION_MSG: {
1401                synchronized (ActivityManagerService.this) {
1402                    int appid = msg.arg1;
1403                    boolean restart = (msg.arg2 == 1);
1404                    Bundle bundle = (Bundle)msg.obj;
1405                    String pkg = bundle.getString("pkg");
1406                    String reason = bundle.getString("reason");
1407                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1408                            false, UserHandle.USER_ALL, reason);
1409                }
1410            } break;
1411            case FINALIZE_PENDING_INTENT_MSG: {
1412                ((PendingIntentRecord)msg.obj).completeFinalize();
1413            } break;
1414            case POST_HEAVY_NOTIFICATION_MSG: {
1415                INotificationManager inm = NotificationManager.getService();
1416                if (inm == null) {
1417                    return;
1418                }
1419
1420                ActivityRecord root = (ActivityRecord)msg.obj;
1421                ProcessRecord process = root.app;
1422                if (process == null) {
1423                    return;
1424                }
1425
1426                try {
1427                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1428                    String text = mContext.getString(R.string.heavy_weight_notification,
1429                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1430                    Notification notification = new Notification();
1431                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1432                    notification.when = 0;
1433                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1434                    notification.tickerText = text;
1435                    notification.defaults = 0; // please be quiet
1436                    notification.sound = null;
1437                    notification.vibrate = null;
1438                    notification.setLatestEventInfo(context, text,
1439                            mContext.getText(R.string.heavy_weight_notification_detail),
1440                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1441                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1442                                    new UserHandle(root.userId)));
1443
1444                    try {
1445                        int[] outId = new int[1];
1446                        inm.enqueueNotificationWithTag("android", "android", null,
1447                                R.string.heavy_weight_notification,
1448                                notification, outId, root.userId);
1449                    } catch (RuntimeException e) {
1450                        Slog.w(ActivityManagerService.TAG,
1451                                "Error showing notification for heavy-weight app", e);
1452                    } catch (RemoteException e) {
1453                    }
1454                } catch (NameNotFoundException e) {
1455                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1456                }
1457            } break;
1458            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1459                INotificationManager inm = NotificationManager.getService();
1460                if (inm == null) {
1461                    return;
1462                }
1463                try {
1464                    inm.cancelNotificationWithTag("android", null,
1465                            R.string.heavy_weight_notification,  msg.arg1);
1466                } catch (RuntimeException e) {
1467                    Slog.w(ActivityManagerService.TAG,
1468                            "Error canceling notification for service", e);
1469                } catch (RemoteException e) {
1470                }
1471            } break;
1472            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1473                synchronized (ActivityManagerService.this) {
1474                    checkExcessivePowerUsageLocked(true);
1475                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1476                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1477                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1478                }
1479            } break;
1480            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1481                synchronized (ActivityManagerService.this) {
1482                    ActivityRecord ar = (ActivityRecord)msg.obj;
1483                    if (mCompatModeDialog != null) {
1484                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1485                                ar.info.applicationInfo.packageName)) {
1486                            return;
1487                        }
1488                        mCompatModeDialog.dismiss();
1489                        mCompatModeDialog = null;
1490                    }
1491                    if (ar != null && false) {
1492                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1493                                ar.packageName)) {
1494                            int mode = mCompatModePackages.computeCompatModeLocked(
1495                                    ar.info.applicationInfo);
1496                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1497                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1498                                mCompatModeDialog = new CompatModeDialog(
1499                                        ActivityManagerService.this, mContext,
1500                                        ar.info.applicationInfo);
1501                                mCompatModeDialog.show();
1502                            }
1503                        }
1504                    }
1505                }
1506                break;
1507            }
1508            case DISPATCH_PROCESSES_CHANGED: {
1509                dispatchProcessesChanged();
1510                break;
1511            }
1512            case DISPATCH_PROCESS_DIED: {
1513                final int pid = msg.arg1;
1514                final int uid = msg.arg2;
1515                dispatchProcessDied(pid, uid);
1516                break;
1517            }
1518            case REPORT_MEM_USAGE_MSG: {
1519                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1520                Thread thread = new Thread() {
1521                    @Override public void run() {
1522                        final SparseArray<ProcessMemInfo> infoMap
1523                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1524                        for (int i=0, N=memInfos.size(); i<N; i++) {
1525                            ProcessMemInfo mi = memInfos.get(i);
1526                            infoMap.put(mi.pid, mi);
1527                        }
1528                        updateCpuStatsNow();
1529                        synchronized (mProcessCpuThread) {
1530                            final int N = mProcessCpuTracker.countStats();
1531                            for (int i=0; i<N; i++) {
1532                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1533                                if (st.vsize > 0) {
1534                                    long pss = Debug.getPss(st.pid, null);
1535                                    if (pss > 0) {
1536                                        if (infoMap.indexOfKey(st.pid) < 0) {
1537                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1538                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1539                                            mi.pss = pss;
1540                                            memInfos.add(mi);
1541                                        }
1542                                    }
1543                                }
1544                            }
1545                        }
1546
1547                        long totalPss = 0;
1548                        for (int i=0, N=memInfos.size(); i<N; i++) {
1549                            ProcessMemInfo mi = memInfos.get(i);
1550                            if (mi.pss == 0) {
1551                                mi.pss = Debug.getPss(mi.pid, null);
1552                            }
1553                            totalPss += mi.pss;
1554                        }
1555                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1556                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1557                                if (lhs.oomAdj != rhs.oomAdj) {
1558                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1559                                }
1560                                if (lhs.pss != rhs.pss) {
1561                                    return lhs.pss < rhs.pss ? 1 : -1;
1562                                }
1563                                return 0;
1564                            }
1565                        });
1566
1567                        StringBuilder tag = new StringBuilder(128);
1568                        StringBuilder stack = new StringBuilder(128);
1569                        tag.append("Low on memory -- ");
1570                        appendMemBucket(tag, totalPss, "total", false);
1571                        appendMemBucket(stack, totalPss, "total", true);
1572
1573                        StringBuilder logBuilder = new StringBuilder(1024);
1574                        logBuilder.append("Low on memory:\n");
1575
1576                        boolean firstLine = true;
1577                        int lastOomAdj = Integer.MIN_VALUE;
1578                        for (int i=0, N=memInfos.size(); i<N; i++) {
1579                            ProcessMemInfo mi = memInfos.get(i);
1580
1581                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1582                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1583                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1584                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1585                                if (lastOomAdj != mi.oomAdj) {
1586                                    lastOomAdj = mi.oomAdj;
1587                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1588                                        tag.append(" / ");
1589                                    }
1590                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1591                                        if (firstLine) {
1592                                            stack.append(":");
1593                                            firstLine = false;
1594                                        }
1595                                        stack.append("\n\t at ");
1596                                    } else {
1597                                        stack.append("$");
1598                                    }
1599                                } else {
1600                                    tag.append(" ");
1601                                    stack.append("$");
1602                                }
1603                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1604                                    appendMemBucket(tag, mi.pss, mi.name, false);
1605                                }
1606                                appendMemBucket(stack, mi.pss, mi.name, true);
1607                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1608                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1609                                    stack.append("(");
1610                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1611                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1612                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1613                                            stack.append(":");
1614                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1615                                        }
1616                                    }
1617                                    stack.append(")");
1618                                }
1619                            }
1620
1621                            logBuilder.append("  ");
1622                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1623                            logBuilder.append(' ');
1624                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1625                            logBuilder.append(' ');
1626                            ProcessList.appendRamKb(logBuilder, mi.pss);
1627                            logBuilder.append(" kB: ");
1628                            logBuilder.append(mi.name);
1629                            logBuilder.append(" (");
1630                            logBuilder.append(mi.pid);
1631                            logBuilder.append(") ");
1632                            logBuilder.append(mi.adjType);
1633                            logBuilder.append('\n');
1634                            if (mi.adjReason != null) {
1635                                logBuilder.append("                      ");
1636                                logBuilder.append(mi.adjReason);
1637                                logBuilder.append('\n');
1638                            }
1639                        }
1640
1641                        logBuilder.append("           ");
1642                        ProcessList.appendRamKb(logBuilder, totalPss);
1643                        logBuilder.append(" kB: TOTAL\n");
1644
1645                        long[] infos = new long[Debug.MEMINFO_COUNT];
1646                        Debug.getMemInfo(infos);
1647                        logBuilder.append("  MemInfo: ");
1648                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1649                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1650                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1651                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1652                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1653                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1654                            logBuilder.append("  ZRAM: ");
1655                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1656                            logBuilder.append(" kB RAM, ");
1657                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1658                            logBuilder.append(" kB swap total, ");
1659                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1660                            logBuilder.append(" kB swap free\n");
1661                        }
1662                        Slog.i(TAG, logBuilder.toString());
1663
1664                        StringBuilder dropBuilder = new StringBuilder(1024);
1665                        /*
1666                        StringWriter oomSw = new StringWriter();
1667                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1668                        StringWriter catSw = new StringWriter();
1669                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1670                        String[] emptyArgs = new String[] { };
1671                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1672                        oomPw.flush();
1673                        String oomString = oomSw.toString();
1674                        */
1675                        dropBuilder.append(stack);
1676                        dropBuilder.append('\n');
1677                        dropBuilder.append('\n');
1678                        dropBuilder.append(logBuilder);
1679                        dropBuilder.append('\n');
1680                        /*
1681                        dropBuilder.append(oomString);
1682                        dropBuilder.append('\n');
1683                        */
1684                        StringWriter catSw = new StringWriter();
1685                        synchronized (ActivityManagerService.this) {
1686                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1687                            String[] emptyArgs = new String[] { };
1688                            catPw.println();
1689                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1690                            catPw.println();
1691                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1692                                    false, false, null);
1693                            catPw.println();
1694                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1695                            catPw.flush();
1696                        }
1697                        dropBuilder.append(catSw.toString());
1698                        addErrorToDropBox("lowmem", null, "system_server", null,
1699                                null, tag.toString(), dropBuilder.toString(), null, null);
1700                        //Slog.i(TAG, "Sent to dropbox:");
1701                        //Slog.i(TAG, dropBuilder.toString());
1702                        synchronized (ActivityManagerService.this) {
1703                            long now = SystemClock.uptimeMillis();
1704                            if (mLastMemUsageReportTime < now) {
1705                                mLastMemUsageReportTime = now;
1706                            }
1707                        }
1708                    }
1709                };
1710                thread.start();
1711                break;
1712            }
1713            case REPORT_USER_SWITCH_MSG: {
1714                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1715                break;
1716            }
1717            case CONTINUE_USER_SWITCH_MSG: {
1718                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1719                break;
1720            }
1721            case USER_SWITCH_TIMEOUT_MSG: {
1722                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1723                break;
1724            }
1725            case IMMERSIVE_MODE_LOCK_MSG: {
1726                final boolean nextState = (msg.arg1 != 0);
1727                if (mUpdateLock.isHeld() != nextState) {
1728                    if (DEBUG_IMMERSIVE) {
1729                        final ActivityRecord r = (ActivityRecord) msg.obj;
1730                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1731                    }
1732                    if (nextState) {
1733                        mUpdateLock.acquire();
1734                    } else {
1735                        mUpdateLock.release();
1736                    }
1737                }
1738                break;
1739            }
1740            case PERSIST_URI_GRANTS_MSG: {
1741                writeGrantedUriPermissions();
1742                break;
1743            }
1744            case REQUEST_ALL_PSS_MSG: {
1745                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1746                break;
1747            }
1748            case START_PROFILES_MSG: {
1749                synchronized (ActivityManagerService.this) {
1750                    startProfilesLocked();
1751                }
1752                break;
1753            }
1754            case UPDATE_TIME: {
1755                synchronized (ActivityManagerService.this) {
1756                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1757                        ProcessRecord r = mLruProcesses.get(i);
1758                        if (r.thread != null) {
1759                            try {
1760                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1761                            } catch (RemoteException ex) {
1762                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1763                            }
1764                        }
1765                    }
1766                }
1767                break;
1768            }
1769            case SYSTEM_USER_START_MSG: {
1770                mSystemServiceManager.startUser(msg.arg1);
1771                break;
1772            }
1773            case SYSTEM_USER_CURRENT_MSG: {
1774                mSystemServiceManager.switchUser(msg.arg1);
1775                break;
1776            }
1777            }
1778        }
1779    };
1780
1781    static final int COLLECT_PSS_BG_MSG = 1;
1782
1783    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1784        @Override
1785        public void handleMessage(Message msg) {
1786            switch (msg.what) {
1787            case COLLECT_PSS_BG_MSG: {
1788                int i=0, num=0;
1789                long start = SystemClock.uptimeMillis();
1790                long[] tmp = new long[1];
1791                do {
1792                    ProcessRecord proc;
1793                    int procState;
1794                    int pid;
1795                    synchronized (ActivityManagerService.this) {
1796                        if (i >= mPendingPssProcesses.size()) {
1797                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1798                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1799                            mPendingPssProcesses.clear();
1800                            return;
1801                        }
1802                        proc = mPendingPssProcesses.get(i);
1803                        procState = proc.pssProcState;
1804                        if (proc.thread != null && procState == proc.setProcState) {
1805                            pid = proc.pid;
1806                        } else {
1807                            proc = null;
1808                            pid = 0;
1809                        }
1810                        i++;
1811                    }
1812                    if (proc != null) {
1813                        long pss = Debug.getPss(pid, tmp);
1814                        synchronized (ActivityManagerService.this) {
1815                            if (proc.thread != null && proc.setProcState == procState
1816                                    && proc.pid == pid) {
1817                                num++;
1818                                proc.lastPssTime = SystemClock.uptimeMillis();
1819                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1820                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1821                                        + ": " + pss + " lastPss=" + proc.lastPss
1822                                        + " state=" + ProcessList.makeProcStateString(procState));
1823                                if (proc.initialIdlePss == 0) {
1824                                    proc.initialIdlePss = pss;
1825                                }
1826                                proc.lastPss = pss;
1827                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1828                                    proc.lastCachedPss = pss;
1829                                }
1830                            }
1831                        }
1832                    }
1833                } while (true);
1834            }
1835            }
1836        }
1837    };
1838
1839    public void setSystemProcess() {
1840        try {
1841            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1842            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1843            ServiceManager.addService("meminfo", new MemBinder(this));
1844            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1845            ServiceManager.addService("dbinfo", new DbBinder(this));
1846            if (MONITOR_CPU_USAGE) {
1847                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1848            }
1849            ServiceManager.addService("permission", new PermissionController(this));
1850
1851            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1852                    "android", STOCK_PM_FLAGS);
1853            mSystemThread.installSystemApplicationInfo(info);
1854
1855            synchronized (this) {
1856                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1857                app.persistent = true;
1858                app.pid = MY_PID;
1859                app.maxAdj = ProcessList.SYSTEM_ADJ;
1860                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1861                mProcessNames.put(app.processName, app.uid, app);
1862                synchronized (mPidsSelfLocked) {
1863                    mPidsSelfLocked.put(app.pid, app);
1864                }
1865                updateLruProcessLocked(app, false, null);
1866                updateOomAdjLocked();
1867            }
1868        } catch (PackageManager.NameNotFoundException e) {
1869            throw new RuntimeException(
1870                    "Unable to find android system package", e);
1871        }
1872    }
1873
1874    public void setWindowManager(WindowManagerService wm) {
1875        mWindowManager = wm;
1876        mStackSupervisor.setWindowManager(wm);
1877    }
1878
1879    public void startObservingNativeCrashes() {
1880        final NativeCrashListener ncl = new NativeCrashListener(this);
1881        ncl.start();
1882    }
1883
1884    public IAppOpsService getAppOpsService() {
1885        return mAppOpsService;
1886    }
1887
1888    static class MemBinder extends Binder {
1889        ActivityManagerService mActivityManagerService;
1890        MemBinder(ActivityManagerService activityManagerService) {
1891            mActivityManagerService = activityManagerService;
1892        }
1893
1894        @Override
1895        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1896            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1897                    != PackageManager.PERMISSION_GRANTED) {
1898                pw.println("Permission Denial: can't dump meminfo from from pid="
1899                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1900                        + " without permission " + android.Manifest.permission.DUMP);
1901                return;
1902            }
1903
1904            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1905        }
1906    }
1907
1908    static class GraphicsBinder extends Binder {
1909        ActivityManagerService mActivityManagerService;
1910        GraphicsBinder(ActivityManagerService activityManagerService) {
1911            mActivityManagerService = activityManagerService;
1912        }
1913
1914        @Override
1915        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1916            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1917                    != PackageManager.PERMISSION_GRANTED) {
1918                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1919                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1920                        + " without permission " + android.Manifest.permission.DUMP);
1921                return;
1922            }
1923
1924            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1925        }
1926    }
1927
1928    static class DbBinder extends Binder {
1929        ActivityManagerService mActivityManagerService;
1930        DbBinder(ActivityManagerService activityManagerService) {
1931            mActivityManagerService = activityManagerService;
1932        }
1933
1934        @Override
1935        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1936            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1937                    != PackageManager.PERMISSION_GRANTED) {
1938                pw.println("Permission Denial: can't dump dbinfo from from pid="
1939                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1940                        + " without permission " + android.Manifest.permission.DUMP);
1941                return;
1942            }
1943
1944            mActivityManagerService.dumpDbInfo(fd, pw, args);
1945        }
1946    }
1947
1948    static class CpuBinder extends Binder {
1949        ActivityManagerService mActivityManagerService;
1950        CpuBinder(ActivityManagerService activityManagerService) {
1951            mActivityManagerService = activityManagerService;
1952        }
1953
1954        @Override
1955        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1956            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1957                    != PackageManager.PERMISSION_GRANTED) {
1958                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1959                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1960                        + " without permission " + android.Manifest.permission.DUMP);
1961                return;
1962            }
1963
1964            synchronized (mActivityManagerService.mProcessCpuThread) {
1965                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1966                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1967                        SystemClock.uptimeMillis()));
1968            }
1969        }
1970    }
1971
1972    public static final class Lifecycle extends SystemService {
1973        private final ActivityManagerService mService;
1974
1975        public Lifecycle(Context context) {
1976            super(context);
1977            mService = new ActivityManagerService(context);
1978        }
1979
1980        @Override
1981        public void onStart() {
1982            mService.start();
1983        }
1984
1985        public ActivityManagerService getService() {
1986            return mService;
1987        }
1988    }
1989
1990    // Note: This method is invoked on the main thread but may need to attach various
1991    // handlers to other threads.  So take care to be explicit about the looper.
1992    public ActivityManagerService(Context systemContext) {
1993        mContext = systemContext;
1994        mFactoryTest = FactoryTest.getMode();
1995        mSystemThread = ActivityThread.currentActivityThread();
1996
1997        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1998
1999        mHandlerThread = new ServiceThread(TAG,
2000                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2001        mHandlerThread.start();
2002        mHandler = new MainHandler(mHandlerThread.getLooper());
2003
2004        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2005                "foreground", BROADCAST_FG_TIMEOUT, false);
2006        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2007                "background", BROADCAST_BG_TIMEOUT, true);
2008        mBroadcastQueues[0] = mFgBroadcastQueue;
2009        mBroadcastQueues[1] = mBgBroadcastQueue;
2010
2011        mServices = new ActiveServices(this);
2012        mProviderMap = new ProviderMap(this);
2013
2014        // TODO: Move creation of battery stats service outside of activity manager service.
2015        File dataDir = Environment.getDataDirectory();
2016        File systemDir = new File(dataDir, "system");
2017        systemDir.mkdirs();
2018        mBatteryStatsService = new BatteryStatsService(new File(
2019                systemDir, "batterystats.bin").toString(), mHandler);
2020        mBatteryStatsService.getActiveStatistics().readLocked();
2021        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2022        mOnBattery = DEBUG_POWER ? true
2023                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2024        mBatteryStatsService.getActiveStatistics().setCallback(this);
2025
2026        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2027
2028        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2029        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2030
2031        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2032
2033        // User 0 is the first and only user that runs at boot.
2034        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2035        mUserLru.add(Integer.valueOf(0));
2036        updateStartedUserArrayLocked();
2037
2038        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2039            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2040
2041        mConfiguration.setToDefaults();
2042        mConfiguration.setLocale(Locale.getDefault());
2043
2044        mConfigurationSeq = mConfiguration.seq = 1;
2045        mProcessCpuTracker.init();
2046
2047        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2048        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2049        mStackSupervisor = new ActivityStackSupervisor(this);
2050
2051        mProcessCpuThread = new Thread("CpuTracker") {
2052            @Override
2053            public void run() {
2054                while (true) {
2055                    try {
2056                        try {
2057                            synchronized(this) {
2058                                final long now = SystemClock.uptimeMillis();
2059                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2060                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2061                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2062                                //        + ", write delay=" + nextWriteDelay);
2063                                if (nextWriteDelay < nextCpuDelay) {
2064                                    nextCpuDelay = nextWriteDelay;
2065                                }
2066                                if (nextCpuDelay > 0) {
2067                                    mProcessCpuMutexFree.set(true);
2068                                    this.wait(nextCpuDelay);
2069                                }
2070                            }
2071                        } catch (InterruptedException e) {
2072                        }
2073                        updateCpuStatsNow();
2074                    } catch (Exception e) {
2075                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2076                    }
2077                }
2078            }
2079        };
2080
2081        Watchdog.getInstance().addMonitor(this);
2082        Watchdog.getInstance().addThread(mHandler);
2083    }
2084
2085    public void setSystemServiceManager(SystemServiceManager mgr) {
2086        mSystemServiceManager = mgr;
2087    }
2088
2089    private void start() {
2090        mProcessCpuThread.start();
2091
2092        mBatteryStatsService.publish(mContext);
2093        mUsageStatsService.publish(mContext);
2094        mAppOpsService.publish(mContext);
2095
2096        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2097    }
2098
2099    @Override
2100    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2101            throws RemoteException {
2102        if (code == SYSPROPS_TRANSACTION) {
2103            // We need to tell all apps about the system property change.
2104            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2105            synchronized(this) {
2106                final int NP = mProcessNames.getMap().size();
2107                for (int ip=0; ip<NP; ip++) {
2108                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2109                    final int NA = apps.size();
2110                    for (int ia=0; ia<NA; ia++) {
2111                        ProcessRecord app = apps.valueAt(ia);
2112                        if (app.thread != null) {
2113                            procs.add(app.thread.asBinder());
2114                        }
2115                    }
2116                }
2117            }
2118
2119            int N = procs.size();
2120            for (int i=0; i<N; i++) {
2121                Parcel data2 = Parcel.obtain();
2122                try {
2123                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2124                } catch (RemoteException e) {
2125                }
2126                data2.recycle();
2127            }
2128        }
2129        try {
2130            return super.onTransact(code, data, reply, flags);
2131        } catch (RuntimeException e) {
2132            // The activity manager only throws security exceptions, so let's
2133            // log all others.
2134            if (!(e instanceof SecurityException)) {
2135                Slog.wtf(TAG, "Activity Manager Crash", e);
2136            }
2137            throw e;
2138        }
2139    }
2140
2141    void updateCpuStats() {
2142        final long now = SystemClock.uptimeMillis();
2143        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2144            return;
2145        }
2146        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2147            synchronized (mProcessCpuThread) {
2148                mProcessCpuThread.notify();
2149            }
2150        }
2151    }
2152
2153    void updateCpuStatsNow() {
2154        synchronized (mProcessCpuThread) {
2155            mProcessCpuMutexFree.set(false);
2156            final long now = SystemClock.uptimeMillis();
2157            boolean haveNewCpuStats = false;
2158
2159            if (MONITOR_CPU_USAGE &&
2160                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2161                mLastCpuTime.set(now);
2162                haveNewCpuStats = true;
2163                mProcessCpuTracker.update();
2164                //Slog.i(TAG, mProcessCpu.printCurrentState());
2165                //Slog.i(TAG, "Total CPU usage: "
2166                //        + mProcessCpu.getTotalCpuPercent() + "%");
2167
2168                // Slog the cpu usage if the property is set.
2169                if ("true".equals(SystemProperties.get("events.cpu"))) {
2170                    int user = mProcessCpuTracker.getLastUserTime();
2171                    int system = mProcessCpuTracker.getLastSystemTime();
2172                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2173                    int irq = mProcessCpuTracker.getLastIrqTime();
2174                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2175                    int idle = mProcessCpuTracker.getLastIdleTime();
2176
2177                    int total = user + system + iowait + irq + softIrq + idle;
2178                    if (total == 0) total = 1;
2179
2180                    EventLog.writeEvent(EventLogTags.CPU,
2181                            ((user+system+iowait+irq+softIrq) * 100) / total,
2182                            (user * 100) / total,
2183                            (system * 100) / total,
2184                            (iowait * 100) / total,
2185                            (irq * 100) / total,
2186                            (softIrq * 100) / total);
2187                }
2188            }
2189
2190            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2191            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2192            synchronized(bstats) {
2193                synchronized(mPidsSelfLocked) {
2194                    if (haveNewCpuStats) {
2195                        if (mOnBattery) {
2196                            int perc = bstats.startAddingCpuLocked();
2197                            int totalUTime = 0;
2198                            int totalSTime = 0;
2199                            final int N = mProcessCpuTracker.countStats();
2200                            for (int i=0; i<N; i++) {
2201                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2202                                if (!st.working) {
2203                                    continue;
2204                                }
2205                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2206                                int otherUTime = (st.rel_utime*perc)/100;
2207                                int otherSTime = (st.rel_stime*perc)/100;
2208                                totalUTime += otherUTime;
2209                                totalSTime += otherSTime;
2210                                if (pr != null) {
2211                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2212                                    if (ps == null || !ps.isActive()) {
2213                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2214                                                pr.info.uid, pr.processName);
2215                                    }
2216                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2217                                            st.rel_stime-otherSTime);
2218                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2219                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2220                                } else {
2221                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2222                                    if (ps == null || !ps.isActive()) {
2223                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2224                                                bstats.mapUid(st.uid), st.name);
2225                                    }
2226                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2227                                            st.rel_stime-otherSTime);
2228                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2229                                }
2230                            }
2231                            bstats.finishAddingCpuLocked(perc, totalUTime,
2232                                    totalSTime, cpuSpeedTimes);
2233                        }
2234                    }
2235                }
2236
2237                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2238                    mLastWriteTime = now;
2239                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2240                }
2241            }
2242        }
2243    }
2244
2245    @Override
2246    public void batteryNeedsCpuUpdate() {
2247        updateCpuStatsNow();
2248    }
2249
2250    @Override
2251    public void batteryPowerChanged(boolean onBattery) {
2252        // When plugging in, update the CPU stats first before changing
2253        // the plug state.
2254        updateCpuStatsNow();
2255        synchronized (this) {
2256            synchronized(mPidsSelfLocked) {
2257                mOnBattery = DEBUG_POWER ? true : onBattery;
2258            }
2259        }
2260    }
2261
2262    /**
2263     * Initialize the application bind args. These are passed to each
2264     * process when the bindApplication() IPC is sent to the process. They're
2265     * lazily setup to make sure the services are running when they're asked for.
2266     */
2267    private HashMap<String, IBinder> getCommonServicesLocked() {
2268        if (mAppBindArgs == null) {
2269            mAppBindArgs = new HashMap<String, IBinder>();
2270
2271            // Setup the application init args
2272            mAppBindArgs.put("package", ServiceManager.getService("package"));
2273            mAppBindArgs.put("window", ServiceManager.getService("window"));
2274            mAppBindArgs.put(Context.ALARM_SERVICE,
2275                    ServiceManager.getService(Context.ALARM_SERVICE));
2276        }
2277        return mAppBindArgs;
2278    }
2279
2280    final void setFocusedActivityLocked(ActivityRecord r) {
2281        if (mFocusedActivity != r) {
2282            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2283            mFocusedActivity = r;
2284            if (r.task != null && r.task.voiceInteractor != null) {
2285                startRunningVoiceLocked();
2286            } else {
2287                finishRunningVoiceLocked();
2288            }
2289            mStackSupervisor.setFocusedStack(r);
2290            if (r != null) {
2291                mWindowManager.setFocusedApp(r.appToken, true);
2292            }
2293            applyUpdateLockStateLocked(r);
2294        }
2295    }
2296
2297    final void clearFocusedActivity(ActivityRecord r) {
2298        if (mFocusedActivity == r) {
2299            mFocusedActivity = null;
2300        }
2301    }
2302
2303    @Override
2304    public void setFocusedStack(int stackId) {
2305        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2306        synchronized (ActivityManagerService.this) {
2307            ActivityStack stack = mStackSupervisor.getStack(stackId);
2308            if (stack != null) {
2309                ActivityRecord r = stack.topRunningActivityLocked(null);
2310                if (r != null) {
2311                    setFocusedActivityLocked(r);
2312                }
2313            }
2314        }
2315    }
2316
2317    @Override
2318    public void notifyActivityDrawn(IBinder token) {
2319        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2320        synchronized (this) {
2321            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2322            if (r != null) {
2323                r.task.stack.notifyActivityDrawnLocked(r);
2324            }
2325        }
2326    }
2327
2328    final void applyUpdateLockStateLocked(ActivityRecord r) {
2329        // Modifications to the UpdateLock state are done on our handler, outside
2330        // the activity manager's locks.  The new state is determined based on the
2331        // state *now* of the relevant activity record.  The object is passed to
2332        // the handler solely for logging detail, not to be consulted/modified.
2333        final boolean nextState = r != null && r.immersive;
2334        mHandler.sendMessage(
2335                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2336    }
2337
2338    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2339        Message msg = Message.obtain();
2340        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2341        msg.obj = r.task.askedCompatMode ? null : r;
2342        mHandler.sendMessage(msg);
2343    }
2344
2345    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2346            String what, Object obj, ProcessRecord srcApp) {
2347        app.lastActivityTime = now;
2348
2349        if (app.activities.size() > 0) {
2350            // Don't want to touch dependent processes that are hosting activities.
2351            return index;
2352        }
2353
2354        int lrui = mLruProcesses.lastIndexOf(app);
2355        if (lrui < 0) {
2356            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2357                    + what + " " + obj + " from " + srcApp);
2358            return index;
2359        }
2360
2361        if (lrui >= index) {
2362            // Don't want to cause this to move dependent processes *back* in the
2363            // list as if they were less frequently used.
2364            return index;
2365        }
2366
2367        if (lrui >= mLruProcessActivityStart) {
2368            // Don't want to touch dependent processes that are hosting activities.
2369            return index;
2370        }
2371
2372        mLruProcesses.remove(lrui);
2373        if (index > 0) {
2374            index--;
2375        }
2376        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2377                + " in LRU list: " + app);
2378        mLruProcesses.add(index, app);
2379        return index;
2380    }
2381
2382    final void removeLruProcessLocked(ProcessRecord app) {
2383        int lrui = mLruProcesses.lastIndexOf(app);
2384        if (lrui >= 0) {
2385            if (lrui <= mLruProcessActivityStart) {
2386                mLruProcessActivityStart--;
2387            }
2388            if (lrui <= mLruProcessServiceStart) {
2389                mLruProcessServiceStart--;
2390            }
2391            mLruProcesses.remove(lrui);
2392        }
2393    }
2394
2395    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2396            ProcessRecord client) {
2397        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2398                || app.treatLikeActivity;
2399        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2400        if (!activityChange && hasActivity) {
2401            // The process has activities, so we are only allowing activity-based adjustments
2402            // to move it.  It should be kept in the front of the list with other
2403            // processes that have activities, and we don't want those to change their
2404            // order except due to activity operations.
2405            return;
2406        }
2407
2408        mLruSeq++;
2409        final long now = SystemClock.uptimeMillis();
2410        app.lastActivityTime = now;
2411
2412        // First a quick reject: if the app is already at the position we will
2413        // put it, then there is nothing to do.
2414        if (hasActivity) {
2415            final int N = mLruProcesses.size();
2416            if (N > 0 && mLruProcesses.get(N-1) == app) {
2417                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2418                return;
2419            }
2420        } else {
2421            if (mLruProcessServiceStart > 0
2422                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2423                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2424                return;
2425            }
2426        }
2427
2428        int lrui = mLruProcesses.lastIndexOf(app);
2429
2430        if (app.persistent && lrui >= 0) {
2431            // We don't care about the position of persistent processes, as long as
2432            // they are in the list.
2433            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2434            return;
2435        }
2436
2437        /* In progress: compute new position first, so we can avoid doing work
2438           if the process is not actually going to move.  Not yet working.
2439        int addIndex;
2440        int nextIndex;
2441        boolean inActivity = false, inService = false;
2442        if (hasActivity) {
2443            // Process has activities, put it at the very tipsy-top.
2444            addIndex = mLruProcesses.size();
2445            nextIndex = mLruProcessServiceStart;
2446            inActivity = true;
2447        } else if (hasService) {
2448            // Process has services, put it at the top of the service list.
2449            addIndex = mLruProcessActivityStart;
2450            nextIndex = mLruProcessServiceStart;
2451            inActivity = true;
2452            inService = true;
2453        } else  {
2454            // Process not otherwise of interest, it goes to the top of the non-service area.
2455            addIndex = mLruProcessServiceStart;
2456            if (client != null) {
2457                int clientIndex = mLruProcesses.lastIndexOf(client);
2458                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2459                        + app);
2460                if (clientIndex >= 0 && addIndex > clientIndex) {
2461                    addIndex = clientIndex;
2462                }
2463            }
2464            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2465        }
2466
2467        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2468                + mLruProcessActivityStart + "): " + app);
2469        */
2470
2471        if (lrui >= 0) {
2472            if (lrui < mLruProcessActivityStart) {
2473                mLruProcessActivityStart--;
2474            }
2475            if (lrui < mLruProcessServiceStart) {
2476                mLruProcessServiceStart--;
2477            }
2478            /*
2479            if (addIndex > lrui) {
2480                addIndex--;
2481            }
2482            if (nextIndex > lrui) {
2483                nextIndex--;
2484            }
2485            */
2486            mLruProcesses.remove(lrui);
2487        }
2488
2489        /*
2490        mLruProcesses.add(addIndex, app);
2491        if (inActivity) {
2492            mLruProcessActivityStart++;
2493        }
2494        if (inService) {
2495            mLruProcessActivityStart++;
2496        }
2497        */
2498
2499        int nextIndex;
2500        if (hasActivity) {
2501            final int N = mLruProcesses.size();
2502            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2503                // Process doesn't have activities, but has clients with
2504                // activities...  move it up, but one below the top (the top
2505                // should always have a real activity).
2506                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2507                mLruProcesses.add(N-1, app);
2508                // To keep it from spamming the LRU list (by making a bunch of clients),
2509                // we will push down any other entries owned by the app.
2510                final int uid = app.info.uid;
2511                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2512                    ProcessRecord subProc = mLruProcesses.get(i);
2513                    if (subProc.info.uid == uid) {
2514                        // We want to push this one down the list.  If the process after
2515                        // it is for the same uid, however, don't do so, because we don't
2516                        // want them internally to be re-ordered.
2517                        if (mLruProcesses.get(i-1).info.uid != uid) {
2518                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2519                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2520                            ProcessRecord tmp = mLruProcesses.get(i);
2521                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2522                            mLruProcesses.set(i-1, tmp);
2523                            i--;
2524                        }
2525                    } else {
2526                        // A gap, we can stop here.
2527                        break;
2528                    }
2529                }
2530            } else {
2531                // Process has activities, put it at the very tipsy-top.
2532                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2533                mLruProcesses.add(app);
2534            }
2535            nextIndex = mLruProcessServiceStart;
2536        } else if (hasService) {
2537            // Process has services, put it at the top of the service list.
2538            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2539            mLruProcesses.add(mLruProcessActivityStart, app);
2540            nextIndex = mLruProcessServiceStart;
2541            mLruProcessActivityStart++;
2542        } else  {
2543            // Process not otherwise of interest, it goes to the top of the non-service area.
2544            int index = mLruProcessServiceStart;
2545            if (client != null) {
2546                // If there is a client, don't allow the process to be moved up higher
2547                // in the list than that client.
2548                int clientIndex = mLruProcesses.lastIndexOf(client);
2549                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2550                        + " when updating " + app);
2551                if (clientIndex <= lrui) {
2552                    // Don't allow the client index restriction to push it down farther in the
2553                    // list than it already is.
2554                    clientIndex = lrui;
2555                }
2556                if (clientIndex >= 0 && index > clientIndex) {
2557                    index = clientIndex;
2558                }
2559            }
2560            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2561            mLruProcesses.add(index, app);
2562            nextIndex = index-1;
2563            mLruProcessActivityStart++;
2564            mLruProcessServiceStart++;
2565        }
2566
2567        // If the app is currently using a content provider or service,
2568        // bump those processes as well.
2569        for (int j=app.connections.size()-1; j>=0; j--) {
2570            ConnectionRecord cr = app.connections.valueAt(j);
2571            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2572                    && cr.binding.service.app != null
2573                    && cr.binding.service.app.lruSeq != mLruSeq
2574                    && !cr.binding.service.app.persistent) {
2575                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2576                        "service connection", cr, app);
2577            }
2578        }
2579        for (int j=app.conProviders.size()-1; j>=0; j--) {
2580            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2581            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2582                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2583                        "provider reference", cpr, app);
2584            }
2585        }
2586    }
2587
2588    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2589        if (uid == Process.SYSTEM_UID) {
2590            // The system gets to run in any process.  If there are multiple
2591            // processes with the same uid, just pick the first (this
2592            // should never happen).
2593            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2594            if (procs == null) return null;
2595            final int N = procs.size();
2596            for (int i = 0; i < N; i++) {
2597                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2598            }
2599        }
2600        ProcessRecord proc = mProcessNames.get(processName, uid);
2601        if (false && proc != null && !keepIfLarge
2602                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2603                && proc.lastCachedPss >= 4000) {
2604            // Turn this condition on to cause killing to happen regularly, for testing.
2605            if (proc.baseProcessTracker != null) {
2606                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2607            }
2608            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2609                    + "k from cached");
2610        } else if (proc != null && !keepIfLarge
2611                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2612                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2613            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2614            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2615                if (proc.baseProcessTracker != null) {
2616                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2617                }
2618                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2619                        + "k from cached");
2620            }
2621        }
2622        return proc;
2623    }
2624
2625    void ensurePackageDexOpt(String packageName) {
2626        IPackageManager pm = AppGlobals.getPackageManager();
2627        try {
2628            if (pm.performDexOpt(packageName)) {
2629                mDidDexOpt = true;
2630            }
2631        } catch (RemoteException e) {
2632        }
2633    }
2634
2635    boolean isNextTransitionForward() {
2636        int transit = mWindowManager.getPendingAppTransition();
2637        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2638                || transit == AppTransition.TRANSIT_TASK_OPEN
2639                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2640    }
2641
2642    final ProcessRecord startProcessLocked(String processName,
2643            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2644            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2645            boolean isolated, boolean keepIfLarge) {
2646        ProcessRecord app;
2647        if (!isolated) {
2648            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2649        } else {
2650            // If this is an isolated process, it can't re-use an existing process.
2651            app = null;
2652        }
2653        // We don't have to do anything more if:
2654        // (1) There is an existing application record; and
2655        // (2) The caller doesn't think it is dead, OR there is no thread
2656        //     object attached to it so we know it couldn't have crashed; and
2657        // (3) There is a pid assigned to it, so it is either starting or
2658        //     already running.
2659        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2660                + " app=" + app + " knownToBeDead=" + knownToBeDead
2661                + " thread=" + (app != null ? app.thread : null)
2662                + " pid=" + (app != null ? app.pid : -1));
2663        if (app != null && app.pid > 0) {
2664            if (!knownToBeDead || app.thread == null) {
2665                // We already have the app running, or are waiting for it to
2666                // come up (we have a pid but not yet its thread), so keep it.
2667                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2668                // If this is a new package in the process, add the package to the list
2669                app.addPackage(info.packageName, mProcessStats);
2670                return app;
2671            }
2672
2673            // An application record is attached to a previous process,
2674            // clean it up now.
2675            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2676            handleAppDiedLocked(app, true, true);
2677        }
2678
2679        String hostingNameStr = hostingName != null
2680                ? hostingName.flattenToShortString() : null;
2681
2682        if (!isolated) {
2683            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2684                // If we are in the background, then check to see if this process
2685                // is bad.  If so, we will just silently fail.
2686                if (mBadProcesses.get(info.processName, info.uid) != null) {
2687                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2688                            + "/" + info.processName);
2689                    return null;
2690                }
2691            } else {
2692                // When the user is explicitly starting a process, then clear its
2693                // crash count so that we won't make it bad until they see at
2694                // least one crash dialog again, and make the process good again
2695                // if it had been bad.
2696                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2697                        + "/" + info.processName);
2698                mProcessCrashTimes.remove(info.processName, info.uid);
2699                if (mBadProcesses.get(info.processName, info.uid) != null) {
2700                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2701                            UserHandle.getUserId(info.uid), info.uid,
2702                            info.processName);
2703                    mBadProcesses.remove(info.processName, info.uid);
2704                    if (app != null) {
2705                        app.bad = false;
2706                    }
2707                }
2708            }
2709        }
2710
2711        if (app == null) {
2712            app = newProcessRecordLocked(info, processName, isolated);
2713            if (app == null) {
2714                Slog.w(TAG, "Failed making new process record for "
2715                        + processName + "/" + info.uid + " isolated=" + isolated);
2716                return null;
2717            }
2718            mProcessNames.put(processName, app.uid, app);
2719            if (isolated) {
2720                mIsolatedProcesses.put(app.uid, app);
2721            }
2722        } else {
2723            // If this is a new package in the process, add the package to the list
2724            app.addPackage(info.packageName, mProcessStats);
2725        }
2726
2727        // If the system is not ready yet, then hold off on starting this
2728        // process until it is.
2729        if (!mProcessesReady
2730                && !isAllowedWhileBooting(info)
2731                && !allowWhileBooting) {
2732            if (!mProcessesOnHold.contains(app)) {
2733                mProcessesOnHold.add(app);
2734            }
2735            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2736            return app;
2737        }
2738
2739        startProcessLocked(app, hostingType, hostingNameStr);
2740        return (app.pid != 0) ? app : null;
2741    }
2742
2743    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2744        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2745    }
2746
2747    private final void startProcessLocked(ProcessRecord app,
2748            String hostingType, String hostingNameStr) {
2749        if (app.pid > 0 && app.pid != MY_PID) {
2750            synchronized (mPidsSelfLocked) {
2751                mPidsSelfLocked.remove(app.pid);
2752                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2753            }
2754            app.setPid(0);
2755        }
2756
2757        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2758                "startProcessLocked removing on hold: " + app);
2759        mProcessesOnHold.remove(app);
2760
2761        updateCpuStats();
2762
2763        try {
2764            int uid = app.uid;
2765
2766            int[] gids = null;
2767            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2768            if (!app.isolated) {
2769                int[] permGids = null;
2770                try {
2771                    final PackageManager pm = mContext.getPackageManager();
2772                    permGids = pm.getPackageGids(app.info.packageName);
2773
2774                    if (Environment.isExternalStorageEmulated()) {
2775                        if (pm.checkPermission(
2776                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2777                                app.info.packageName) == PERMISSION_GRANTED) {
2778                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2779                        } else {
2780                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2781                        }
2782                    }
2783                } catch (PackageManager.NameNotFoundException e) {
2784                    Slog.w(TAG, "Unable to retrieve gids", e);
2785                }
2786
2787                /*
2788                 * Add shared application GID so applications can share some
2789                 * resources like shared libraries
2790                 */
2791                if (permGids == null) {
2792                    gids = new int[1];
2793                } else {
2794                    gids = new int[permGids.length + 1];
2795                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2796                }
2797                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2798            }
2799            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2800                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2801                        && mTopComponent != null
2802                        && app.processName.equals(mTopComponent.getPackageName())) {
2803                    uid = 0;
2804                }
2805                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2806                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2807                    uid = 0;
2808                }
2809            }
2810            int debugFlags = 0;
2811            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2812                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2813                // Also turn on CheckJNI for debuggable apps. It's quite
2814                // awkward to turn on otherwise.
2815                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2816            }
2817            // Run the app in safe mode if its manifest requests so or the
2818            // system is booted in safe mode.
2819            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2820                mSafeMode == true) {
2821                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2822            }
2823            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2824                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2825            }
2826            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2827                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2828            }
2829            if ("1".equals(SystemProperties.get("debug.assert"))) {
2830                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2831            }
2832
2833            String requiredAbi = app.info.requiredCpuAbi;
2834            if (requiredAbi == null) {
2835                requiredAbi = Build.SUPPORTED_ABIS[0];
2836            }
2837
2838            // Start the process.  It will either succeed and return a result containing
2839            // the PID of the new process, or else throw a RuntimeException.
2840            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2841                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2842                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2843
2844            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2845            synchronized (bs) {
2846                if (bs.isOnBattery()) {
2847                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2848                }
2849            }
2850
2851            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2852                    UserHandle.getUserId(uid), startResult.pid, uid,
2853                    app.processName, hostingType,
2854                    hostingNameStr != null ? hostingNameStr : "");
2855
2856            if (app.persistent) {
2857                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2858            }
2859
2860            StringBuilder buf = mStringBuilder;
2861            buf.setLength(0);
2862            buf.append("Start proc ");
2863            buf.append(app.processName);
2864            buf.append(" for ");
2865            buf.append(hostingType);
2866            if (hostingNameStr != null) {
2867                buf.append(" ");
2868                buf.append(hostingNameStr);
2869            }
2870            buf.append(": pid=");
2871            buf.append(startResult.pid);
2872            buf.append(" uid=");
2873            buf.append(uid);
2874            buf.append(" gids={");
2875            if (gids != null) {
2876                for (int gi=0; gi<gids.length; gi++) {
2877                    if (gi != 0) buf.append(", ");
2878                    buf.append(gids[gi]);
2879
2880                }
2881            }
2882            buf.append("}");
2883            Slog.i(TAG, buf.toString());
2884            app.setPid(startResult.pid);
2885            app.usingWrapper = startResult.usingWrapper;
2886            app.removed = false;
2887            synchronized (mPidsSelfLocked) {
2888                this.mPidsSelfLocked.put(startResult.pid, app);
2889                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2890                msg.obj = app;
2891                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2892                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2893            }
2894            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2895                    app.processName, app.info.uid);
2896            if (app.isolated) {
2897                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2898            }
2899        } catch (RuntimeException e) {
2900            // XXX do better error recovery.
2901            app.setPid(0);
2902            Slog.e(TAG, "Failure starting process " + app.processName, e);
2903        }
2904    }
2905
2906    void updateUsageStats(ActivityRecord component, boolean resumed) {
2907        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2908        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2909        if (resumed) {
2910            mUsageStatsService.noteResumeComponent(component.realActivity);
2911            synchronized (stats) {
2912                stats.noteActivityResumedLocked(component.app.uid);
2913            }
2914        } else {
2915            mUsageStatsService.notePauseComponent(component.realActivity);
2916            synchronized (stats) {
2917                stats.noteActivityPausedLocked(component.app.uid);
2918            }
2919        }
2920    }
2921
2922    Intent getHomeIntent() {
2923        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2924        intent.setComponent(mTopComponent);
2925        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2926            intent.addCategory(Intent.CATEGORY_HOME);
2927        }
2928        return intent;
2929    }
2930
2931    boolean startHomeActivityLocked(int userId) {
2932        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2933                && mTopAction == null) {
2934            // We are running in factory test mode, but unable to find
2935            // the factory test app, so just sit around displaying the
2936            // error message and don't try to start anything.
2937            return false;
2938        }
2939        Intent intent = getHomeIntent();
2940        ActivityInfo aInfo =
2941            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2942        if (aInfo != null) {
2943            intent.setComponent(new ComponentName(
2944                    aInfo.applicationInfo.packageName, aInfo.name));
2945            // Don't do this if the home app is currently being
2946            // instrumented.
2947            aInfo = new ActivityInfo(aInfo);
2948            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2949            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2950                    aInfo.applicationInfo.uid, true);
2951            if (app == null || app.instrumentationClass == null) {
2952                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2953                mStackSupervisor.startHomeActivity(intent, aInfo);
2954            }
2955        }
2956
2957        return true;
2958    }
2959
2960    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2961        ActivityInfo ai = null;
2962        ComponentName comp = intent.getComponent();
2963        try {
2964            if (comp != null) {
2965                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2966            } else {
2967                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2968                        intent,
2969                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2970                            flags, userId);
2971
2972                if (info != null) {
2973                    ai = info.activityInfo;
2974                }
2975            }
2976        } catch (RemoteException e) {
2977            // ignore
2978        }
2979
2980        return ai;
2981    }
2982
2983    /**
2984     * Starts the "new version setup screen" if appropriate.
2985     */
2986    void startSetupActivityLocked() {
2987        // Only do this once per boot.
2988        if (mCheckedForSetup) {
2989            return;
2990        }
2991
2992        // We will show this screen if the current one is a different
2993        // version than the last one shown, and we are not running in
2994        // low-level factory test mode.
2995        final ContentResolver resolver = mContext.getContentResolver();
2996        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2997                Settings.Global.getInt(resolver,
2998                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2999            mCheckedForSetup = true;
3000
3001            // See if we should be showing the platform update setup UI.
3002            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3003            List<ResolveInfo> ris = mContext.getPackageManager()
3004                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3005
3006            // We don't allow third party apps to replace this.
3007            ResolveInfo ri = null;
3008            for (int i=0; ris != null && i<ris.size(); i++) {
3009                if ((ris.get(i).activityInfo.applicationInfo.flags
3010                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3011                    ri = ris.get(i);
3012                    break;
3013                }
3014            }
3015
3016            if (ri != null) {
3017                String vers = ri.activityInfo.metaData != null
3018                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3019                        : null;
3020                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3021                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3022                            Intent.METADATA_SETUP_VERSION);
3023                }
3024                String lastVers = Settings.Secure.getString(
3025                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3026                if (vers != null && !vers.equals(lastVers)) {
3027                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3028                    intent.setComponent(new ComponentName(
3029                            ri.activityInfo.packageName, ri.activityInfo.name));
3030                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3031                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3032                }
3033            }
3034        }
3035    }
3036
3037    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3038        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3039    }
3040
3041    void enforceNotIsolatedCaller(String caller) {
3042        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3043            throw new SecurityException("Isolated process not allowed to call " + caller);
3044        }
3045    }
3046
3047    @Override
3048    public int getFrontActivityScreenCompatMode() {
3049        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3050        synchronized (this) {
3051            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3052        }
3053    }
3054
3055    @Override
3056    public void setFrontActivityScreenCompatMode(int mode) {
3057        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3058                "setFrontActivityScreenCompatMode");
3059        synchronized (this) {
3060            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3061        }
3062    }
3063
3064    @Override
3065    public int getPackageScreenCompatMode(String packageName) {
3066        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3067        synchronized (this) {
3068            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3069        }
3070    }
3071
3072    @Override
3073    public void setPackageScreenCompatMode(String packageName, int mode) {
3074        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3075                "setPackageScreenCompatMode");
3076        synchronized (this) {
3077            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3078        }
3079    }
3080
3081    @Override
3082    public boolean getPackageAskScreenCompat(String packageName) {
3083        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3084        synchronized (this) {
3085            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3086        }
3087    }
3088
3089    @Override
3090    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3091        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3092                "setPackageAskScreenCompat");
3093        synchronized (this) {
3094            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3095        }
3096    }
3097
3098    private void dispatchProcessesChanged() {
3099        int N;
3100        synchronized (this) {
3101            N = mPendingProcessChanges.size();
3102            if (mActiveProcessChanges.length < N) {
3103                mActiveProcessChanges = new ProcessChangeItem[N];
3104            }
3105            mPendingProcessChanges.toArray(mActiveProcessChanges);
3106            mAvailProcessChanges.addAll(mPendingProcessChanges);
3107            mPendingProcessChanges.clear();
3108            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3109        }
3110
3111        int i = mProcessObservers.beginBroadcast();
3112        while (i > 0) {
3113            i--;
3114            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3115            if (observer != null) {
3116                try {
3117                    for (int j=0; j<N; j++) {
3118                        ProcessChangeItem item = mActiveProcessChanges[j];
3119                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3120                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3121                                    + item.pid + " uid=" + item.uid + ": "
3122                                    + item.foregroundActivities);
3123                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3124                                    item.foregroundActivities);
3125                        }
3126                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3127                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3128                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3129                            observer.onImportanceChanged(item.pid, item.uid,
3130                                    item.importance);
3131                        }
3132                    }
3133                } catch (RemoteException e) {
3134                }
3135            }
3136        }
3137        mProcessObservers.finishBroadcast();
3138    }
3139
3140    private void dispatchProcessDied(int pid, int uid) {
3141        int i = mProcessObservers.beginBroadcast();
3142        while (i > 0) {
3143            i--;
3144            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3145            if (observer != null) {
3146                try {
3147                    observer.onProcessDied(pid, uid);
3148                } catch (RemoteException e) {
3149                }
3150            }
3151        }
3152        mProcessObservers.finishBroadcast();
3153    }
3154
3155    final void doPendingActivityLaunchesLocked(boolean doResume) {
3156        final int N = mPendingActivityLaunches.size();
3157        if (N <= 0) {
3158            return;
3159        }
3160        for (int i=0; i<N; i++) {
3161            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3162            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3163                    doResume && i == (N-1), null);
3164        }
3165        mPendingActivityLaunches.clear();
3166    }
3167
3168    @Override
3169    public final int startActivity(IApplicationThread caller, String callingPackage,
3170            Intent intent, String resolvedType, IBinder resultTo,
3171            String resultWho, int requestCode, int startFlags,
3172            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3173        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3174                resultWho, requestCode,
3175                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3176    }
3177
3178    @Override
3179    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3180            Intent intent, String resolvedType, IBinder resultTo,
3181            String resultWho, int requestCode, int startFlags,
3182            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3183        enforceNotIsolatedCaller("startActivity");
3184        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3185                false, true, "startActivity", null);
3186        // TODO: Switch to user app stacks here.
3187        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3188                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3189                null, null, options, userId, null);
3190    }
3191
3192    @Override
3193    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3194            Intent intent, String resolvedType, IBinder resultTo,
3195            String resultWho, int requestCode, int startFlags, String profileFile,
3196            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3197        enforceNotIsolatedCaller("startActivityAndWait");
3198        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3199                false, true, "startActivityAndWait", null);
3200        WaitResult res = new WaitResult();
3201        // TODO: Switch to user app stacks here.
3202        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3203                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3204                res, null, options, UserHandle.getCallingUserId(), null);
3205        return res;
3206    }
3207
3208    @Override
3209    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3210            Intent intent, String resolvedType, IBinder resultTo,
3211            String resultWho, int requestCode, int startFlags, Configuration config,
3212            Bundle options, int userId) {
3213        enforceNotIsolatedCaller("startActivityWithConfig");
3214        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3215                false, true, "startActivityWithConfig", null);
3216        // TODO: Switch to user app stacks here.
3217        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3218                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3219                null, null, null, config, options, userId, null);
3220        return ret;
3221    }
3222
3223    @Override
3224    public int startActivityIntentSender(IApplicationThread caller,
3225            IntentSender intent, Intent fillInIntent, String resolvedType,
3226            IBinder resultTo, String resultWho, int requestCode,
3227            int flagsMask, int flagsValues, Bundle options) {
3228        enforceNotIsolatedCaller("startActivityIntentSender");
3229        // Refuse possible leaked file descriptors
3230        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3231            throw new IllegalArgumentException("File descriptors passed in Intent");
3232        }
3233
3234        IIntentSender sender = intent.getTarget();
3235        if (!(sender instanceof PendingIntentRecord)) {
3236            throw new IllegalArgumentException("Bad PendingIntent object");
3237        }
3238
3239        PendingIntentRecord pir = (PendingIntentRecord)sender;
3240
3241        synchronized (this) {
3242            // If this is coming from the currently resumed activity, it is
3243            // effectively saying that app switches are allowed at this point.
3244            final ActivityStack stack = getFocusedStack();
3245            if (stack.mResumedActivity != null &&
3246                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3247                mAppSwitchesAllowedTime = 0;
3248            }
3249        }
3250        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3251                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3252        return ret;
3253    }
3254
3255    @Override
3256    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3257            Intent intent, String resolvedType, IVoiceInteractionSession session,
3258            IVoiceInteractor interactor, int startFlags, String profileFile,
3259            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3260        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3261                != PackageManager.PERMISSION_GRANTED) {
3262            String msg = "Permission Denial: startVoiceActivity() from pid="
3263                    + Binder.getCallingPid()
3264                    + ", uid=" + Binder.getCallingUid()
3265                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3266            Slog.w(TAG, msg);
3267            throw new SecurityException(msg);
3268        }
3269        if (session == null || interactor == null) {
3270            throw new NullPointerException("null session or interactor");
3271        }
3272        userId = handleIncomingUser(callingPid, callingUid, userId,
3273                false, true, "startVoiceActivity", null);
3274        // TODO: Switch to user app stacks here.
3275        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3276                resolvedType, session, interactor, null, null, 0, startFlags,
3277                profileFile, profileFd, null, null, options, userId, null);
3278    }
3279
3280    @Override
3281    public boolean startNextMatchingActivity(IBinder callingActivity,
3282            Intent intent, Bundle options) {
3283        // Refuse possible leaked file descriptors
3284        if (intent != null && intent.hasFileDescriptors() == true) {
3285            throw new IllegalArgumentException("File descriptors passed in Intent");
3286        }
3287
3288        synchronized (this) {
3289            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3290            if (r == null) {
3291                ActivityOptions.abort(options);
3292                return false;
3293            }
3294            if (r.app == null || r.app.thread == null) {
3295                // The caller is not running...  d'oh!
3296                ActivityOptions.abort(options);
3297                return false;
3298            }
3299            intent = new Intent(intent);
3300            // The caller is not allowed to change the data.
3301            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3302            // And we are resetting to find the next component...
3303            intent.setComponent(null);
3304
3305            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3306
3307            ActivityInfo aInfo = null;
3308            try {
3309                List<ResolveInfo> resolves =
3310                    AppGlobals.getPackageManager().queryIntentActivities(
3311                            intent, r.resolvedType,
3312                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3313                            UserHandle.getCallingUserId());
3314
3315                // Look for the original activity in the list...
3316                final int N = resolves != null ? resolves.size() : 0;
3317                for (int i=0; i<N; i++) {
3318                    ResolveInfo rInfo = resolves.get(i);
3319                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3320                            && rInfo.activityInfo.name.equals(r.info.name)) {
3321                        // We found the current one...  the next matching is
3322                        // after it.
3323                        i++;
3324                        if (i<N) {
3325                            aInfo = resolves.get(i).activityInfo;
3326                        }
3327                        if (debug) {
3328                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3329                                    + "/" + r.info.name);
3330                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3331                                    + "/" + aInfo.name);
3332                        }
3333                        break;
3334                    }
3335                }
3336            } catch (RemoteException e) {
3337            }
3338
3339            if (aInfo == null) {
3340                // Nobody who is next!
3341                ActivityOptions.abort(options);
3342                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3343                return false;
3344            }
3345
3346            intent.setComponent(new ComponentName(
3347                    aInfo.applicationInfo.packageName, aInfo.name));
3348            intent.setFlags(intent.getFlags()&~(
3349                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3350                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3351                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3352                    Intent.FLAG_ACTIVITY_NEW_TASK));
3353
3354            // Okay now we need to start the new activity, replacing the
3355            // currently running activity.  This is a little tricky because
3356            // we want to start the new one as if the current one is finished,
3357            // but not finish the current one first so that there is no flicker.
3358            // And thus...
3359            final boolean wasFinishing = r.finishing;
3360            r.finishing = true;
3361
3362            // Propagate reply information over to the new activity.
3363            final ActivityRecord resultTo = r.resultTo;
3364            final String resultWho = r.resultWho;
3365            final int requestCode = r.requestCode;
3366            r.resultTo = null;
3367            if (resultTo != null) {
3368                resultTo.removeResultsLocked(r, resultWho, requestCode);
3369            }
3370
3371            final long origId = Binder.clearCallingIdentity();
3372            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3373                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3374                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3375                    options, false, null, null);
3376            Binder.restoreCallingIdentity(origId);
3377
3378            r.finishing = wasFinishing;
3379            if (res != ActivityManager.START_SUCCESS) {
3380                return false;
3381            }
3382            return true;
3383        }
3384    }
3385
3386    final int startActivityInPackage(int uid, String callingPackage,
3387            Intent intent, String resolvedType, IBinder resultTo,
3388            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3389                    IActivityContainer container) {
3390
3391        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3392                false, true, "startActivityInPackage", null);
3393
3394        // TODO: Switch to user app stacks here.
3395        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3396                null, null, resultTo, resultWho, requestCode, startFlags,
3397                null, null, null, null, options, userId, container);
3398        return ret;
3399    }
3400
3401    @Override
3402    public final int startActivities(IApplicationThread caller, String callingPackage,
3403            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3404            int userId) {
3405        enforceNotIsolatedCaller("startActivities");
3406        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3407                false, true, "startActivity", null);
3408        // TODO: Switch to user app stacks here.
3409        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3410                resolvedTypes, resultTo, options, userId);
3411        return ret;
3412    }
3413
3414    final int startActivitiesInPackage(int uid, String callingPackage,
3415            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3416            Bundle options, int userId) {
3417
3418        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3419                false, true, "startActivityInPackage", null);
3420        // TODO: Switch to user app stacks here.
3421        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3422                resultTo, options, userId);
3423        return ret;
3424    }
3425
3426    final void addRecentTaskLocked(TaskRecord task) {
3427        int N = mRecentTasks.size();
3428        // Quick case: check if the top-most recent task is the same.
3429        if (N > 0 && mRecentTasks.get(0) == task) {
3430            return;
3431        }
3432        // Another quick case: never add voice sessions.
3433        if (task.voiceSession != null) {
3434            return;
3435        }
3436        // Remove any existing entries that are the same kind of task.
3437        final Intent intent = task.intent;
3438        final boolean document = intent != null && intent.isDocument();
3439        for (int i=0; i<N; i++) {
3440            TaskRecord tr = mRecentTasks.get(i);
3441            if (task != tr) {
3442                if (task.userId != tr.userId) {
3443                    continue;
3444                }
3445                final Intent trIntent = tr.intent;
3446                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3447                    (intent == null || !intent.filterEquals(trIntent))) {
3448                    continue;
3449                }
3450                if (document || trIntent != null && trIntent.isDocument()) {
3451                    // Document tasks do not match other tasks.
3452                    continue;
3453                }
3454            }
3455
3456            // Either task and tr are the same or, their affinities match or their intents match
3457            // and neither of them is a document.
3458            tr.disposeThumbnail();
3459            mRecentTasks.remove(i);
3460            i--;
3461            N--;
3462            if (task.intent == null) {
3463                // If the new recent task we are adding is not fully
3464                // specified, then replace it with the existing recent task.
3465                task = tr;
3466            }
3467        }
3468        if (N >= MAX_RECENT_TASKS) {
3469            mRecentTasks.remove(N-1).disposeThumbnail();
3470        }
3471        mRecentTasks.add(0, task);
3472    }
3473
3474    @Override
3475    public void reportActivityFullyDrawn(IBinder token) {
3476        synchronized (this) {
3477            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3478            if (r == null) {
3479                return;
3480            }
3481            r.reportFullyDrawnLocked();
3482        }
3483    }
3484
3485    @Override
3486    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3487        synchronized (this) {
3488            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3489            if (r == null) {
3490                return;
3491            }
3492            final long origId = Binder.clearCallingIdentity();
3493            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3494            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3495                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3496            if (config != null) {
3497                r.frozenBeforeDestroy = true;
3498                if (!updateConfigurationLocked(config, r, false, false)) {
3499                    mStackSupervisor.resumeTopActivitiesLocked();
3500                }
3501            }
3502            Binder.restoreCallingIdentity(origId);
3503        }
3504    }
3505
3506    @Override
3507    public int getRequestedOrientation(IBinder token) {
3508        synchronized (this) {
3509            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3510            if (r == null) {
3511                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3512            }
3513            return mWindowManager.getAppOrientation(r.appToken);
3514        }
3515    }
3516
3517    /**
3518     * This is the internal entry point for handling Activity.finish().
3519     *
3520     * @param token The Binder token referencing the Activity we want to finish.
3521     * @param resultCode Result code, if any, from this Activity.
3522     * @param resultData Result data (Intent), if any, from this Activity.
3523     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3524     *            the root Activity in the task.
3525     *
3526     * @return Returns true if the activity successfully finished, or false if it is still running.
3527     */
3528    @Override
3529    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3530            boolean finishTask) {
3531        // Refuse possible leaked file descriptors
3532        if (resultData != null && resultData.hasFileDescriptors() == true) {
3533            throw new IllegalArgumentException("File descriptors passed in Intent");
3534        }
3535
3536        synchronized(this) {
3537            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3538            if (r == null) {
3539                return true;
3540            }
3541            // Keep track of the root activity of the task before we finish it
3542            TaskRecord tr = r.task;
3543            ActivityRecord rootR = tr.getRootActivity();
3544            if (mController != null) {
3545                // Find the first activity that is not finishing.
3546                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3547                if (next != null) {
3548                    // ask watcher if this is allowed
3549                    boolean resumeOK = true;
3550                    try {
3551                        resumeOK = mController.activityResuming(next.packageName);
3552                    } catch (RemoteException e) {
3553                        mController = null;
3554                        Watchdog.getInstance().setActivityController(null);
3555                    }
3556
3557                    if (!resumeOK) {
3558                        return false;
3559                    }
3560                }
3561            }
3562            final long origId = Binder.clearCallingIdentity();
3563            try {
3564                boolean res;
3565                if (finishTask && r == rootR) {
3566                    // If requested, remove the task that is associated to this activity only if it
3567                    // was the root activity in the task.  The result code and data is ignored because
3568                    // we don't support returning them across task boundaries.
3569                    res = removeTaskByIdLocked(tr.taskId, 0);
3570                } else {
3571                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3572                            resultData, "app-request", true);
3573                }
3574                return res;
3575            } finally {
3576                Binder.restoreCallingIdentity(origId);
3577            }
3578        }
3579    }
3580
3581    @Override
3582    public final void finishHeavyWeightApp() {
3583        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3584                != PackageManager.PERMISSION_GRANTED) {
3585            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3586                    + Binder.getCallingPid()
3587                    + ", uid=" + Binder.getCallingUid()
3588                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3589            Slog.w(TAG, msg);
3590            throw new SecurityException(msg);
3591        }
3592
3593        synchronized(this) {
3594            if (mHeavyWeightProcess == null) {
3595                return;
3596            }
3597
3598            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3599                    mHeavyWeightProcess.activities);
3600            for (int i=0; i<activities.size(); i++) {
3601                ActivityRecord r = activities.get(i);
3602                if (!r.finishing) {
3603                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3604                            null, "finish-heavy", true);
3605                }
3606            }
3607
3608            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3609                    mHeavyWeightProcess.userId, 0));
3610            mHeavyWeightProcess = null;
3611        }
3612    }
3613
3614    @Override
3615    public void crashApplication(int uid, int initialPid, String packageName,
3616            String message) {
3617        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3618                != PackageManager.PERMISSION_GRANTED) {
3619            String msg = "Permission Denial: crashApplication() from pid="
3620                    + Binder.getCallingPid()
3621                    + ", uid=" + Binder.getCallingUid()
3622                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3623            Slog.w(TAG, msg);
3624            throw new SecurityException(msg);
3625        }
3626
3627        synchronized(this) {
3628            ProcessRecord proc = null;
3629
3630            // Figure out which process to kill.  We don't trust that initialPid
3631            // still has any relation to current pids, so must scan through the
3632            // list.
3633            synchronized (mPidsSelfLocked) {
3634                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3635                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3636                    if (p.uid != uid) {
3637                        continue;
3638                    }
3639                    if (p.pid == initialPid) {
3640                        proc = p;
3641                        break;
3642                    }
3643                    if (p.pkgList.containsKey(packageName)) {
3644                        proc = p;
3645                    }
3646                }
3647            }
3648
3649            if (proc == null) {
3650                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3651                        + " initialPid=" + initialPid
3652                        + " packageName=" + packageName);
3653                return;
3654            }
3655
3656            if (proc.thread != null) {
3657                if (proc.pid == Process.myPid()) {
3658                    Log.w(TAG, "crashApplication: trying to crash self!");
3659                    return;
3660                }
3661                long ident = Binder.clearCallingIdentity();
3662                try {
3663                    proc.thread.scheduleCrash(message);
3664                } catch (RemoteException e) {
3665                }
3666                Binder.restoreCallingIdentity(ident);
3667            }
3668        }
3669    }
3670
3671    @Override
3672    public final void finishSubActivity(IBinder token, String resultWho,
3673            int requestCode) {
3674        synchronized(this) {
3675            final long origId = Binder.clearCallingIdentity();
3676            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3677            if (r != null) {
3678                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3679            }
3680            Binder.restoreCallingIdentity(origId);
3681        }
3682    }
3683
3684    @Override
3685    public boolean finishActivityAffinity(IBinder token) {
3686        synchronized(this) {
3687            final long origId = Binder.clearCallingIdentity();
3688            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3689            boolean res = false;
3690            if (r != null) {
3691                res = r.task.stack.finishActivityAffinityLocked(r);
3692            }
3693            Binder.restoreCallingIdentity(origId);
3694            return res;
3695        }
3696    }
3697
3698    @Override
3699    public boolean willActivityBeVisible(IBinder token) {
3700        synchronized(this) {
3701            ActivityStack stack = ActivityRecord.getStackLocked(token);
3702            if (stack != null) {
3703                return stack.willActivityBeVisibleLocked(token);
3704            }
3705            return false;
3706        }
3707    }
3708
3709    @Override
3710    public void overridePendingTransition(IBinder token, String packageName,
3711            int enterAnim, int exitAnim) {
3712        synchronized(this) {
3713            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3714            if (self == null) {
3715                return;
3716            }
3717
3718            final long origId = Binder.clearCallingIdentity();
3719
3720            if (self.state == ActivityState.RESUMED
3721                    || self.state == ActivityState.PAUSING) {
3722                mWindowManager.overridePendingAppTransition(packageName,
3723                        enterAnim, exitAnim, null);
3724            }
3725
3726            Binder.restoreCallingIdentity(origId);
3727        }
3728    }
3729
3730    /**
3731     * Main function for removing an existing process from the activity manager
3732     * as a result of that process going away.  Clears out all connections
3733     * to the process.
3734     */
3735    private final void handleAppDiedLocked(ProcessRecord app,
3736            boolean restarting, boolean allowRestart) {
3737        int pid = app.pid;
3738        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3739        if (!restarting) {
3740            removeLruProcessLocked(app);
3741            if (pid > 0) {
3742                ProcessList.remove(pid);
3743            }
3744        }
3745
3746        if (mProfileProc == app) {
3747            clearProfilerLocked();
3748        }
3749
3750        // Remove this application's activities from active lists.
3751        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3752
3753        app.activities.clear();
3754
3755        if (app.instrumentationClass != null) {
3756            Slog.w(TAG, "Crash of app " + app.processName
3757                  + " running instrumentation " + app.instrumentationClass);
3758            Bundle info = new Bundle();
3759            info.putString("shortMsg", "Process crashed.");
3760            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3761        }
3762
3763        if (!restarting) {
3764            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3765                // If there was nothing to resume, and we are not already
3766                // restarting this process, but there is a visible activity that
3767                // is hosted by the process...  then make sure all visible
3768                // activities are running, taking care of restarting this
3769                // process.
3770                if (hasVisibleActivities) {
3771                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3772                }
3773            }
3774        }
3775    }
3776
3777    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3778        IBinder threadBinder = thread.asBinder();
3779        // Find the application record.
3780        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3781            ProcessRecord rec = mLruProcesses.get(i);
3782            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3783                return i;
3784            }
3785        }
3786        return -1;
3787    }
3788
3789    final ProcessRecord getRecordForAppLocked(
3790            IApplicationThread thread) {
3791        if (thread == null) {
3792            return null;
3793        }
3794
3795        int appIndex = getLRURecordIndexForAppLocked(thread);
3796        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3797    }
3798
3799    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3800        // If there are no longer any background processes running,
3801        // and the app that died was not running instrumentation,
3802        // then tell everyone we are now low on memory.
3803        boolean haveBg = false;
3804        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3805            ProcessRecord rec = mLruProcesses.get(i);
3806            if (rec.thread != null
3807                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3808                haveBg = true;
3809                break;
3810            }
3811        }
3812
3813        if (!haveBg) {
3814            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3815            if (doReport) {
3816                long now = SystemClock.uptimeMillis();
3817                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3818                    doReport = false;
3819                } else {
3820                    mLastMemUsageReportTime = now;
3821                }
3822            }
3823            final ArrayList<ProcessMemInfo> memInfos
3824                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3825            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3826            long now = SystemClock.uptimeMillis();
3827            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3828                ProcessRecord rec = mLruProcesses.get(i);
3829                if (rec == dyingProc || rec.thread == null) {
3830                    continue;
3831                }
3832                if (doReport) {
3833                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3834                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3835                }
3836                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3837                    // The low memory report is overriding any current
3838                    // state for a GC request.  Make sure to do
3839                    // heavy/important/visible/foreground processes first.
3840                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3841                        rec.lastRequestedGc = 0;
3842                    } else {
3843                        rec.lastRequestedGc = rec.lastLowMemory;
3844                    }
3845                    rec.reportLowMemory = true;
3846                    rec.lastLowMemory = now;
3847                    mProcessesToGc.remove(rec);
3848                    addProcessToGcListLocked(rec);
3849                }
3850            }
3851            if (doReport) {
3852                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3853                mHandler.sendMessage(msg);
3854            }
3855            scheduleAppGcsLocked();
3856        }
3857    }
3858
3859    final void appDiedLocked(ProcessRecord app, int pid,
3860            IApplicationThread thread) {
3861
3862        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3863        synchronized (stats) {
3864            stats.noteProcessDiedLocked(app.info.uid, pid);
3865        }
3866
3867        // Clean up already done if the process has been re-started.
3868        if (app.pid == pid && app.thread != null &&
3869                app.thread.asBinder() == thread.asBinder()) {
3870            boolean doLowMem = app.instrumentationClass == null;
3871            boolean doOomAdj = doLowMem;
3872            if (!app.killedByAm) {
3873                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3874                        + ") has died.");
3875                mAllowLowerMemLevel = true;
3876            } else {
3877                // Note that we always want to do oom adj to update our state with the
3878                // new number of procs.
3879                mAllowLowerMemLevel = false;
3880                doLowMem = false;
3881            }
3882            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3883            if (DEBUG_CLEANUP) Slog.v(
3884                TAG, "Dying app: " + app + ", pid: " + pid
3885                + ", thread: " + thread.asBinder());
3886            handleAppDiedLocked(app, false, true);
3887
3888            if (doOomAdj) {
3889                updateOomAdjLocked();
3890            }
3891            if (doLowMem) {
3892                doLowMemReportIfNeededLocked(app);
3893            }
3894        } else if (app.pid != pid) {
3895            // A new process has already been started.
3896            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3897                    + ") has died and restarted (pid " + app.pid + ").");
3898            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3899        } else if (DEBUG_PROCESSES) {
3900            Slog.d(TAG, "Received spurious death notification for thread "
3901                    + thread.asBinder());
3902        }
3903    }
3904
3905    /**
3906     * If a stack trace dump file is configured, dump process stack traces.
3907     * @param clearTraces causes the dump file to be erased prior to the new
3908     *    traces being written, if true; when false, the new traces will be
3909     *    appended to any existing file content.
3910     * @param firstPids of dalvik VM processes to dump stack traces for first
3911     * @param lastPids of dalvik VM processes to dump stack traces for last
3912     * @param nativeProcs optional list of native process names to dump stack crawls
3913     * @return file containing stack traces, or null if no dump file is configured
3914     */
3915    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3916            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3917        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3918        if (tracesPath == null || tracesPath.length() == 0) {
3919            return null;
3920        }
3921
3922        File tracesFile = new File(tracesPath);
3923        try {
3924            File tracesDir = tracesFile.getParentFile();
3925            if (!tracesDir.exists()) {
3926                tracesFile.mkdirs();
3927                if (!SELinux.restorecon(tracesDir)) {
3928                    return null;
3929                }
3930            }
3931            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3932
3933            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3934            tracesFile.createNewFile();
3935            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3936        } catch (IOException e) {
3937            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3938            return null;
3939        }
3940
3941        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3942        return tracesFile;
3943    }
3944
3945    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3946            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3947        // Use a FileObserver to detect when traces finish writing.
3948        // The order of traces is considered important to maintain for legibility.
3949        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3950            @Override
3951            public synchronized void onEvent(int event, String path) { notify(); }
3952        };
3953
3954        try {
3955            observer.startWatching();
3956
3957            // First collect all of the stacks of the most important pids.
3958            if (firstPids != null) {
3959                try {
3960                    int num = firstPids.size();
3961                    for (int i = 0; i < num; i++) {
3962                        synchronized (observer) {
3963                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3964                            observer.wait(200);  // Wait for write-close, give up after 200msec
3965                        }
3966                    }
3967                } catch (InterruptedException e) {
3968                    Log.wtf(TAG, e);
3969                }
3970            }
3971
3972            // Next collect the stacks of the native pids
3973            if (nativeProcs != null) {
3974                int[] pids = Process.getPidsForCommands(nativeProcs);
3975                if (pids != null) {
3976                    for (int pid : pids) {
3977                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3978                    }
3979                }
3980            }
3981
3982            // Lastly, measure CPU usage.
3983            if (processCpuTracker != null) {
3984                processCpuTracker.init();
3985                System.gc();
3986                processCpuTracker.update();
3987                try {
3988                    synchronized (processCpuTracker) {
3989                        processCpuTracker.wait(500); // measure over 1/2 second.
3990                    }
3991                } catch (InterruptedException e) {
3992                }
3993                processCpuTracker.update();
3994
3995                // We'll take the stack crawls of just the top apps using CPU.
3996                final int N = processCpuTracker.countWorkingStats();
3997                int numProcs = 0;
3998                for (int i=0; i<N && numProcs<5; i++) {
3999                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4000                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4001                        numProcs++;
4002                        try {
4003                            synchronized (observer) {
4004                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4005                                observer.wait(200);  // Wait for write-close, give up after 200msec
4006                            }
4007                        } catch (InterruptedException e) {
4008                            Log.wtf(TAG, e);
4009                        }
4010
4011                    }
4012                }
4013            }
4014        } finally {
4015            observer.stopWatching();
4016        }
4017    }
4018
4019    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4020        if (true || IS_USER_BUILD) {
4021            return;
4022        }
4023        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4024        if (tracesPath == null || tracesPath.length() == 0) {
4025            return;
4026        }
4027
4028        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4029        StrictMode.allowThreadDiskWrites();
4030        try {
4031            final File tracesFile = new File(tracesPath);
4032            final File tracesDir = tracesFile.getParentFile();
4033            final File tracesTmp = new File(tracesDir, "__tmp__");
4034            try {
4035                if (!tracesDir.exists()) {
4036                    tracesFile.mkdirs();
4037                    if (!SELinux.restorecon(tracesDir.getPath())) {
4038                        return;
4039                    }
4040                }
4041                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4042
4043                if (tracesFile.exists()) {
4044                    tracesTmp.delete();
4045                    tracesFile.renameTo(tracesTmp);
4046                }
4047                StringBuilder sb = new StringBuilder();
4048                Time tobj = new Time();
4049                tobj.set(System.currentTimeMillis());
4050                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4051                sb.append(": ");
4052                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4053                sb.append(" since ");
4054                sb.append(msg);
4055                FileOutputStream fos = new FileOutputStream(tracesFile);
4056                fos.write(sb.toString().getBytes());
4057                if (app == null) {
4058                    fos.write("\n*** No application process!".getBytes());
4059                }
4060                fos.close();
4061                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4062            } catch (IOException e) {
4063                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4064                return;
4065            }
4066
4067            if (app != null) {
4068                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4069                firstPids.add(app.pid);
4070                dumpStackTraces(tracesPath, firstPids, null, null, null);
4071            }
4072
4073            File lastTracesFile = null;
4074            File curTracesFile = null;
4075            for (int i=9; i>=0; i--) {
4076                String name = String.format(Locale.US, "slow%02d.txt", i);
4077                curTracesFile = new File(tracesDir, name);
4078                if (curTracesFile.exists()) {
4079                    if (lastTracesFile != null) {
4080                        curTracesFile.renameTo(lastTracesFile);
4081                    } else {
4082                        curTracesFile.delete();
4083                    }
4084                }
4085                lastTracesFile = curTracesFile;
4086            }
4087            tracesFile.renameTo(curTracesFile);
4088            if (tracesTmp.exists()) {
4089                tracesTmp.renameTo(tracesFile);
4090            }
4091        } finally {
4092            StrictMode.setThreadPolicy(oldPolicy);
4093        }
4094    }
4095
4096    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4097            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4098        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4099        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4100
4101        if (mController != null) {
4102            try {
4103                // 0 == continue, -1 = kill process immediately
4104                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4105                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4106            } catch (RemoteException e) {
4107                mController = null;
4108                Watchdog.getInstance().setActivityController(null);
4109            }
4110        }
4111
4112        long anrTime = SystemClock.uptimeMillis();
4113        if (MONITOR_CPU_USAGE) {
4114            updateCpuStatsNow();
4115        }
4116
4117        synchronized (this) {
4118            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4119            if (mShuttingDown) {
4120                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4121                return;
4122            } else if (app.notResponding) {
4123                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4124                return;
4125            } else if (app.crashing) {
4126                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4127                return;
4128            }
4129
4130            // In case we come through here for the same app before completing
4131            // this one, mark as anring now so we will bail out.
4132            app.notResponding = true;
4133
4134            // Log the ANR to the event log.
4135            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4136                    app.processName, app.info.flags, annotation);
4137
4138            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4139            firstPids.add(app.pid);
4140
4141            int parentPid = app.pid;
4142            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4143            if (parentPid != app.pid) firstPids.add(parentPid);
4144
4145            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4146
4147            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4148                ProcessRecord r = mLruProcesses.get(i);
4149                if (r != null && r.thread != null) {
4150                    int pid = r.pid;
4151                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4152                        if (r.persistent) {
4153                            firstPids.add(pid);
4154                        } else {
4155                            lastPids.put(pid, Boolean.TRUE);
4156                        }
4157                    }
4158                }
4159            }
4160        }
4161
4162        // Log the ANR to the main log.
4163        StringBuilder info = new StringBuilder();
4164        info.setLength(0);
4165        info.append("ANR in ").append(app.processName);
4166        if (activity != null && activity.shortComponentName != null) {
4167            info.append(" (").append(activity.shortComponentName).append(")");
4168        }
4169        info.append("\n");
4170        info.append("PID: ").append(app.pid).append("\n");
4171        if (annotation != null) {
4172            info.append("Reason: ").append(annotation).append("\n");
4173        }
4174        if (parent != null && parent != activity) {
4175            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4176        }
4177
4178        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4179
4180        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4181                NATIVE_STACKS_OF_INTEREST);
4182
4183        String cpuInfo = null;
4184        if (MONITOR_CPU_USAGE) {
4185            updateCpuStatsNow();
4186            synchronized (mProcessCpuThread) {
4187                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4188            }
4189            info.append(processCpuTracker.printCurrentLoad());
4190            info.append(cpuInfo);
4191        }
4192
4193        info.append(processCpuTracker.printCurrentState(anrTime));
4194
4195        Slog.e(TAG, info.toString());
4196        if (tracesFile == null) {
4197            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4198            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4199        }
4200
4201        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4202                cpuInfo, tracesFile, null);
4203
4204        if (mController != null) {
4205            try {
4206                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4207                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4208                if (res != 0) {
4209                    if (res < 0 && app.pid != MY_PID) {
4210                        Process.killProcess(app.pid);
4211                    } else {
4212                        synchronized (this) {
4213                            mServices.scheduleServiceTimeoutLocked(app);
4214                        }
4215                    }
4216                    return;
4217                }
4218            } catch (RemoteException e) {
4219                mController = null;
4220                Watchdog.getInstance().setActivityController(null);
4221            }
4222        }
4223
4224        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4225        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4226                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4227
4228        synchronized (this) {
4229            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4230                killUnneededProcessLocked(app, "background ANR");
4231                return;
4232            }
4233
4234            // Set the app's notResponding state, and look up the errorReportReceiver
4235            makeAppNotRespondingLocked(app,
4236                    activity != null ? activity.shortComponentName : null,
4237                    annotation != null ? "ANR " + annotation : "ANR",
4238                    info.toString());
4239
4240            // Bring up the infamous App Not Responding dialog
4241            Message msg = Message.obtain();
4242            HashMap<String, Object> map = new HashMap<String, Object>();
4243            msg.what = SHOW_NOT_RESPONDING_MSG;
4244            msg.obj = map;
4245            msg.arg1 = aboveSystem ? 1 : 0;
4246            map.put("app", app);
4247            if (activity != null) {
4248                map.put("activity", activity);
4249            }
4250
4251            mHandler.sendMessage(msg);
4252        }
4253    }
4254
4255    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4256        if (!mLaunchWarningShown) {
4257            mLaunchWarningShown = true;
4258            mHandler.post(new Runnable() {
4259                @Override
4260                public void run() {
4261                    synchronized (ActivityManagerService.this) {
4262                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4263                        d.show();
4264                        mHandler.postDelayed(new Runnable() {
4265                            @Override
4266                            public void run() {
4267                                synchronized (ActivityManagerService.this) {
4268                                    d.dismiss();
4269                                    mLaunchWarningShown = false;
4270                                }
4271                            }
4272                        }, 4000);
4273                    }
4274                }
4275            });
4276        }
4277    }
4278
4279    @Override
4280    public boolean clearApplicationUserData(final String packageName,
4281            final IPackageDataObserver observer, int userId) {
4282        enforceNotIsolatedCaller("clearApplicationUserData");
4283        int uid = Binder.getCallingUid();
4284        int pid = Binder.getCallingPid();
4285        userId = handleIncomingUser(pid, uid,
4286                userId, false, true, "clearApplicationUserData", null);
4287        long callingId = Binder.clearCallingIdentity();
4288        try {
4289            IPackageManager pm = AppGlobals.getPackageManager();
4290            int pkgUid = -1;
4291            synchronized(this) {
4292                try {
4293                    pkgUid = pm.getPackageUid(packageName, userId);
4294                } catch (RemoteException e) {
4295                }
4296                if (pkgUid == -1) {
4297                    Slog.w(TAG, "Invalid packageName: " + packageName);
4298                    if (observer != null) {
4299                        try {
4300                            observer.onRemoveCompleted(packageName, false);
4301                        } catch (RemoteException e) {
4302                            Slog.i(TAG, "Observer no longer exists.");
4303                        }
4304                    }
4305                    return false;
4306                }
4307                if (uid == pkgUid || checkComponentPermission(
4308                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4309                        pid, uid, -1, true)
4310                        == PackageManager.PERMISSION_GRANTED) {
4311                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4312                } else {
4313                    throw new SecurityException("PID " + pid + " does not have permission "
4314                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4315                                    + " of package " + packageName);
4316                }
4317            }
4318
4319            try {
4320                // Clear application user data
4321                pm.clearApplicationUserData(packageName, observer, userId);
4322
4323                // Remove all permissions granted from/to this package
4324                removeUriPermissionsForPackageLocked(packageName, userId, true);
4325
4326                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4327                        Uri.fromParts("package", packageName, null));
4328                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4329                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4330                        null, null, 0, null, null, null, false, false, userId);
4331            } catch (RemoteException e) {
4332            }
4333        } finally {
4334            Binder.restoreCallingIdentity(callingId);
4335        }
4336        return true;
4337    }
4338
4339    @Override
4340    public void killBackgroundProcesses(final String packageName, int userId) {
4341        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4342                != PackageManager.PERMISSION_GRANTED &&
4343                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4344                        != PackageManager.PERMISSION_GRANTED) {
4345            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4346                    + Binder.getCallingPid()
4347                    + ", uid=" + Binder.getCallingUid()
4348                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4349            Slog.w(TAG, msg);
4350            throw new SecurityException(msg);
4351        }
4352
4353        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4354                userId, true, true, "killBackgroundProcesses", null);
4355        long callingId = Binder.clearCallingIdentity();
4356        try {
4357            IPackageManager pm = AppGlobals.getPackageManager();
4358            synchronized(this) {
4359                int appId = -1;
4360                try {
4361                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4362                } catch (RemoteException e) {
4363                }
4364                if (appId == -1) {
4365                    Slog.w(TAG, "Invalid packageName: " + packageName);
4366                    return;
4367                }
4368                killPackageProcessesLocked(packageName, appId, userId,
4369                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4370            }
4371        } finally {
4372            Binder.restoreCallingIdentity(callingId);
4373        }
4374    }
4375
4376    @Override
4377    public void killAllBackgroundProcesses() {
4378        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4379                != PackageManager.PERMISSION_GRANTED) {
4380            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4381                    + Binder.getCallingPid()
4382                    + ", uid=" + Binder.getCallingUid()
4383                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4384            Slog.w(TAG, msg);
4385            throw new SecurityException(msg);
4386        }
4387
4388        long callingId = Binder.clearCallingIdentity();
4389        try {
4390            synchronized(this) {
4391                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4392                final int NP = mProcessNames.getMap().size();
4393                for (int ip=0; ip<NP; ip++) {
4394                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4395                    final int NA = apps.size();
4396                    for (int ia=0; ia<NA; ia++) {
4397                        ProcessRecord app = apps.valueAt(ia);
4398                        if (app.persistent) {
4399                            // we don't kill persistent processes
4400                            continue;
4401                        }
4402                        if (app.removed) {
4403                            procs.add(app);
4404                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4405                            app.removed = true;
4406                            procs.add(app);
4407                        }
4408                    }
4409                }
4410
4411                int N = procs.size();
4412                for (int i=0; i<N; i++) {
4413                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4414                }
4415                mAllowLowerMemLevel = true;
4416                updateOomAdjLocked();
4417                doLowMemReportIfNeededLocked(null);
4418            }
4419        } finally {
4420            Binder.restoreCallingIdentity(callingId);
4421        }
4422    }
4423
4424    @Override
4425    public void forceStopPackage(final String packageName, int userId) {
4426        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4427                != PackageManager.PERMISSION_GRANTED) {
4428            String msg = "Permission Denial: forceStopPackage() from pid="
4429                    + Binder.getCallingPid()
4430                    + ", uid=" + Binder.getCallingUid()
4431                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4432            Slog.w(TAG, msg);
4433            throw new SecurityException(msg);
4434        }
4435        final int callingPid = Binder.getCallingPid();
4436        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4437                userId, true, true, "forceStopPackage", null);
4438        long callingId = Binder.clearCallingIdentity();
4439        try {
4440            IPackageManager pm = AppGlobals.getPackageManager();
4441            synchronized(this) {
4442                int[] users = userId == UserHandle.USER_ALL
4443                        ? getUsersLocked() : new int[] { userId };
4444                for (int user : users) {
4445                    int pkgUid = -1;
4446                    try {
4447                        pkgUid = pm.getPackageUid(packageName, user);
4448                    } catch (RemoteException e) {
4449                    }
4450                    if (pkgUid == -1) {
4451                        Slog.w(TAG, "Invalid packageName: " + packageName);
4452                        continue;
4453                    }
4454                    try {
4455                        pm.setPackageStoppedState(packageName, true, user);
4456                    } catch (RemoteException e) {
4457                    } catch (IllegalArgumentException e) {
4458                        Slog.w(TAG, "Failed trying to unstop package "
4459                                + packageName + ": " + e);
4460                    }
4461                    if (isUserRunningLocked(user, false)) {
4462                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4463                    }
4464                }
4465            }
4466        } finally {
4467            Binder.restoreCallingIdentity(callingId);
4468        }
4469    }
4470
4471    /*
4472     * The pkg name and app id have to be specified.
4473     */
4474    @Override
4475    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4476        if (pkg == null) {
4477            return;
4478        }
4479        // Make sure the uid is valid.
4480        if (appid < 0) {
4481            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4482            return;
4483        }
4484        int callerUid = Binder.getCallingUid();
4485        // Only the system server can kill an application
4486        if (callerUid == Process.SYSTEM_UID) {
4487            // Post an aysnc message to kill the application
4488            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4489            msg.arg1 = appid;
4490            msg.arg2 = 0;
4491            Bundle bundle = new Bundle();
4492            bundle.putString("pkg", pkg);
4493            bundle.putString("reason", reason);
4494            msg.obj = bundle;
4495            mHandler.sendMessage(msg);
4496        } else {
4497            throw new SecurityException(callerUid + " cannot kill pkg: " +
4498                    pkg);
4499        }
4500    }
4501
4502    @Override
4503    public void closeSystemDialogs(String reason) {
4504        enforceNotIsolatedCaller("closeSystemDialogs");
4505
4506        final int pid = Binder.getCallingPid();
4507        final int uid = Binder.getCallingUid();
4508        final long origId = Binder.clearCallingIdentity();
4509        try {
4510            synchronized (this) {
4511                // Only allow this from foreground processes, so that background
4512                // applications can't abuse it to prevent system UI from being shown.
4513                if (uid >= Process.FIRST_APPLICATION_UID) {
4514                    ProcessRecord proc;
4515                    synchronized (mPidsSelfLocked) {
4516                        proc = mPidsSelfLocked.get(pid);
4517                    }
4518                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4519                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4520                                + " from background process " + proc);
4521                        return;
4522                    }
4523                }
4524                closeSystemDialogsLocked(reason);
4525            }
4526        } finally {
4527            Binder.restoreCallingIdentity(origId);
4528        }
4529    }
4530
4531    void closeSystemDialogsLocked(String reason) {
4532        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4533        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4534                | Intent.FLAG_RECEIVER_FOREGROUND);
4535        if (reason != null) {
4536            intent.putExtra("reason", reason);
4537        }
4538        mWindowManager.closeSystemDialogs(reason);
4539
4540        mStackSupervisor.closeSystemDialogsLocked();
4541
4542        broadcastIntentLocked(null, null, intent, null,
4543                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4544                Process.SYSTEM_UID, UserHandle.USER_ALL);
4545    }
4546
4547    @Override
4548    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4549        enforceNotIsolatedCaller("getProcessMemoryInfo");
4550        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4551        for (int i=pids.length-1; i>=0; i--) {
4552            ProcessRecord proc;
4553            int oomAdj;
4554            synchronized (this) {
4555                synchronized (mPidsSelfLocked) {
4556                    proc = mPidsSelfLocked.get(pids[i]);
4557                    oomAdj = proc != null ? proc.setAdj : 0;
4558                }
4559            }
4560            infos[i] = new Debug.MemoryInfo();
4561            Debug.getMemoryInfo(pids[i], infos[i]);
4562            if (proc != null) {
4563                synchronized (this) {
4564                    if (proc.thread != null && proc.setAdj == oomAdj) {
4565                        // Record this for posterity if the process has been stable.
4566                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4567                                infos[i].getTotalUss(), false, proc.pkgList);
4568                    }
4569                }
4570            }
4571        }
4572        return infos;
4573    }
4574
4575    @Override
4576    public long[] getProcessPss(int[] pids) {
4577        enforceNotIsolatedCaller("getProcessPss");
4578        long[] pss = new long[pids.length];
4579        for (int i=pids.length-1; i>=0; i--) {
4580            ProcessRecord proc;
4581            int oomAdj;
4582            synchronized (this) {
4583                synchronized (mPidsSelfLocked) {
4584                    proc = mPidsSelfLocked.get(pids[i]);
4585                    oomAdj = proc != null ? proc.setAdj : 0;
4586                }
4587            }
4588            long[] tmpUss = new long[1];
4589            pss[i] = Debug.getPss(pids[i], tmpUss);
4590            if (proc != null) {
4591                synchronized (this) {
4592                    if (proc.thread != null && proc.setAdj == oomAdj) {
4593                        // Record this for posterity if the process has been stable.
4594                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4595                    }
4596                }
4597            }
4598        }
4599        return pss;
4600    }
4601
4602    @Override
4603    public void killApplicationProcess(String processName, int uid) {
4604        if (processName == null) {
4605            return;
4606        }
4607
4608        int callerUid = Binder.getCallingUid();
4609        // Only the system server can kill an application
4610        if (callerUid == Process.SYSTEM_UID) {
4611            synchronized (this) {
4612                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4613                if (app != null && app.thread != null) {
4614                    try {
4615                        app.thread.scheduleSuicide();
4616                    } catch (RemoteException e) {
4617                        // If the other end already died, then our work here is done.
4618                    }
4619                } else {
4620                    Slog.w(TAG, "Process/uid not found attempting kill of "
4621                            + processName + " / " + uid);
4622                }
4623            }
4624        } else {
4625            throw new SecurityException(callerUid + " cannot kill app process: " +
4626                    processName);
4627        }
4628    }
4629
4630    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4631        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4632                false, true, false, false, UserHandle.getUserId(uid), reason);
4633        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4634                Uri.fromParts("package", packageName, null));
4635        if (!mProcessesReady) {
4636            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4637                    | Intent.FLAG_RECEIVER_FOREGROUND);
4638        }
4639        intent.putExtra(Intent.EXTRA_UID, uid);
4640        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4641        broadcastIntentLocked(null, null, intent,
4642                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4643                false, false,
4644                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4645    }
4646
4647    private void forceStopUserLocked(int userId, String reason) {
4648        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4649        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4650        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4651                | Intent.FLAG_RECEIVER_FOREGROUND);
4652        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4653        broadcastIntentLocked(null, null, intent,
4654                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4655                false, false,
4656                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4657    }
4658
4659    private final boolean killPackageProcessesLocked(String packageName, int appId,
4660            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4661            boolean doit, boolean evenPersistent, String reason) {
4662        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4663
4664        // Remove all processes this package may have touched: all with the
4665        // same UID (except for the system or root user), and all whose name
4666        // matches the package name.
4667        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4668        final int NP = mProcessNames.getMap().size();
4669        for (int ip=0; ip<NP; ip++) {
4670            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4671            final int NA = apps.size();
4672            for (int ia=0; ia<NA; ia++) {
4673                ProcessRecord app = apps.valueAt(ia);
4674                if (app.persistent && !evenPersistent) {
4675                    // we don't kill persistent processes
4676                    continue;
4677                }
4678                if (app.removed) {
4679                    if (doit) {
4680                        procs.add(app);
4681                    }
4682                    continue;
4683                }
4684
4685                // Skip process if it doesn't meet our oom adj requirement.
4686                if (app.setAdj < minOomAdj) {
4687                    continue;
4688                }
4689
4690                // If no package is specified, we call all processes under the
4691                // give user id.
4692                if (packageName == null) {
4693                    if (app.userId != userId) {
4694                        continue;
4695                    }
4696                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4697                        continue;
4698                    }
4699                // Package has been specified, we want to hit all processes
4700                // that match it.  We need to qualify this by the processes
4701                // that are running under the specified app and user ID.
4702                } else {
4703                    if (UserHandle.getAppId(app.uid) != appId) {
4704                        continue;
4705                    }
4706                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4707                        continue;
4708                    }
4709                    if (!app.pkgList.containsKey(packageName)) {
4710                        continue;
4711                    }
4712                }
4713
4714                // Process has passed all conditions, kill it!
4715                if (!doit) {
4716                    return true;
4717                }
4718                app.removed = true;
4719                procs.add(app);
4720            }
4721        }
4722
4723        int N = procs.size();
4724        for (int i=0; i<N; i++) {
4725            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4726        }
4727        updateOomAdjLocked();
4728        return N > 0;
4729    }
4730
4731    private final boolean forceStopPackageLocked(String name, int appId,
4732            boolean callerWillRestart, boolean purgeCache, boolean doit,
4733            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4734        int i;
4735        int N;
4736
4737        if (userId == UserHandle.USER_ALL && name == null) {
4738            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4739        }
4740
4741        if (appId < 0 && name != null) {
4742            try {
4743                appId = UserHandle.getAppId(
4744                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4745            } catch (RemoteException e) {
4746            }
4747        }
4748
4749        if (doit) {
4750            if (name != null) {
4751                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4752                        + " user=" + userId + ": " + reason);
4753            } else {
4754                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4755            }
4756
4757            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4758            for (int ip=pmap.size()-1; ip>=0; ip--) {
4759                SparseArray<Long> ba = pmap.valueAt(ip);
4760                for (i=ba.size()-1; i>=0; i--) {
4761                    boolean remove = false;
4762                    final int entUid = ba.keyAt(i);
4763                    if (name != null) {
4764                        if (userId == UserHandle.USER_ALL) {
4765                            if (UserHandle.getAppId(entUid) == appId) {
4766                                remove = true;
4767                            }
4768                        } else {
4769                            if (entUid == UserHandle.getUid(userId, appId)) {
4770                                remove = true;
4771                            }
4772                        }
4773                    } else if (UserHandle.getUserId(entUid) == userId) {
4774                        remove = true;
4775                    }
4776                    if (remove) {
4777                        ba.removeAt(i);
4778                    }
4779                }
4780                if (ba.size() == 0) {
4781                    pmap.removeAt(ip);
4782                }
4783            }
4784        }
4785
4786        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4787                -100, callerWillRestart, true, doit, evenPersistent,
4788                name == null ? ("stop user " + userId) : ("stop " + name));
4789
4790        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4791            if (!doit) {
4792                return true;
4793            }
4794            didSomething = true;
4795        }
4796
4797        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4798            if (!doit) {
4799                return true;
4800            }
4801            didSomething = true;
4802        }
4803
4804        if (name == null) {
4805            // Remove all sticky broadcasts from this user.
4806            mStickyBroadcasts.remove(userId);
4807        }
4808
4809        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4810        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4811                userId, providers)) {
4812            if (!doit) {
4813                return true;
4814            }
4815            didSomething = true;
4816        }
4817        N = providers.size();
4818        for (i=0; i<N; i++) {
4819            removeDyingProviderLocked(null, providers.get(i), true);
4820        }
4821
4822        // Remove transient permissions granted from/to this package/user
4823        removeUriPermissionsForPackageLocked(name, userId, false);
4824
4825        if (name == null || uninstalling) {
4826            // Remove pending intents.  For now we only do this when force
4827            // stopping users, because we have some problems when doing this
4828            // for packages -- app widgets are not currently cleaned up for
4829            // such packages, so they can be left with bad pending intents.
4830            if (mIntentSenderRecords.size() > 0) {
4831                Iterator<WeakReference<PendingIntentRecord>> it
4832                        = mIntentSenderRecords.values().iterator();
4833                while (it.hasNext()) {
4834                    WeakReference<PendingIntentRecord> wpir = it.next();
4835                    if (wpir == null) {
4836                        it.remove();
4837                        continue;
4838                    }
4839                    PendingIntentRecord pir = wpir.get();
4840                    if (pir == null) {
4841                        it.remove();
4842                        continue;
4843                    }
4844                    if (name == null) {
4845                        // Stopping user, remove all objects for the user.
4846                        if (pir.key.userId != userId) {
4847                            // Not the same user, skip it.
4848                            continue;
4849                        }
4850                    } else {
4851                        if (UserHandle.getAppId(pir.uid) != appId) {
4852                            // Different app id, skip it.
4853                            continue;
4854                        }
4855                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4856                            // Different user, skip it.
4857                            continue;
4858                        }
4859                        if (!pir.key.packageName.equals(name)) {
4860                            // Different package, skip it.
4861                            continue;
4862                        }
4863                    }
4864                    if (!doit) {
4865                        return true;
4866                    }
4867                    didSomething = true;
4868                    it.remove();
4869                    pir.canceled = true;
4870                    if (pir.key.activity != null) {
4871                        pir.key.activity.pendingResults.remove(pir.ref);
4872                    }
4873                }
4874            }
4875        }
4876
4877        if (doit) {
4878            if (purgeCache && name != null) {
4879                AttributeCache ac = AttributeCache.instance();
4880                if (ac != null) {
4881                    ac.removePackage(name);
4882                }
4883            }
4884            if (mBooted) {
4885                mStackSupervisor.resumeTopActivitiesLocked();
4886                mStackSupervisor.scheduleIdleLocked();
4887            }
4888        }
4889
4890        return didSomething;
4891    }
4892
4893    private final boolean removeProcessLocked(ProcessRecord app,
4894            boolean callerWillRestart, boolean allowRestart, String reason) {
4895        final String name = app.processName;
4896        final int uid = app.uid;
4897        if (DEBUG_PROCESSES) Slog.d(
4898            TAG, "Force removing proc " + app.toShortString() + " (" + name
4899            + "/" + uid + ")");
4900
4901        mProcessNames.remove(name, uid);
4902        mIsolatedProcesses.remove(app.uid);
4903        if (mHeavyWeightProcess == app) {
4904            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4905                    mHeavyWeightProcess.userId, 0));
4906            mHeavyWeightProcess = null;
4907        }
4908        boolean needRestart = false;
4909        if (app.pid > 0 && app.pid != MY_PID) {
4910            int pid = app.pid;
4911            synchronized (mPidsSelfLocked) {
4912                mPidsSelfLocked.remove(pid);
4913                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4914            }
4915            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4916                    app.processName, app.info.uid);
4917            if (app.isolated) {
4918                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4919            }
4920            killUnneededProcessLocked(app, reason);
4921            handleAppDiedLocked(app, true, allowRestart);
4922            removeLruProcessLocked(app);
4923
4924            if (app.persistent && !app.isolated) {
4925                if (!callerWillRestart) {
4926                    addAppLocked(app.info, false);
4927                } else {
4928                    needRestart = true;
4929                }
4930            }
4931        } else {
4932            mRemovedProcesses.add(app);
4933        }
4934
4935        return needRestart;
4936    }
4937
4938    private final void processStartTimedOutLocked(ProcessRecord app) {
4939        final int pid = app.pid;
4940        boolean gone = false;
4941        synchronized (mPidsSelfLocked) {
4942            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4943            if (knownApp != null && knownApp.thread == null) {
4944                mPidsSelfLocked.remove(pid);
4945                gone = true;
4946            }
4947        }
4948
4949        if (gone) {
4950            Slog.w(TAG, "Process " + app + " failed to attach");
4951            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4952                    pid, app.uid, app.processName);
4953            mProcessNames.remove(app.processName, app.uid);
4954            mIsolatedProcesses.remove(app.uid);
4955            if (mHeavyWeightProcess == app) {
4956                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4957                        mHeavyWeightProcess.userId, 0));
4958                mHeavyWeightProcess = null;
4959            }
4960            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4961                    app.processName, app.info.uid);
4962            if (app.isolated) {
4963                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4964            }
4965            // Take care of any launching providers waiting for this process.
4966            checkAppInLaunchingProvidersLocked(app, true);
4967            // Take care of any services that are waiting for the process.
4968            mServices.processStartTimedOutLocked(app);
4969            killUnneededProcessLocked(app, "start timeout");
4970            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4971                Slog.w(TAG, "Unattached app died before backup, skipping");
4972                try {
4973                    IBackupManager bm = IBackupManager.Stub.asInterface(
4974                            ServiceManager.getService(Context.BACKUP_SERVICE));
4975                    bm.agentDisconnected(app.info.packageName);
4976                } catch (RemoteException e) {
4977                    // Can't happen; the backup manager is local
4978                }
4979            }
4980            if (isPendingBroadcastProcessLocked(pid)) {
4981                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4982                skipPendingBroadcastLocked(pid);
4983            }
4984        } else {
4985            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4986        }
4987    }
4988
4989    private final boolean attachApplicationLocked(IApplicationThread thread,
4990            int pid) {
4991
4992        // Find the application record that is being attached...  either via
4993        // the pid if we are running in multiple processes, or just pull the
4994        // next app record if we are emulating process with anonymous threads.
4995        ProcessRecord app;
4996        if (pid != MY_PID && pid >= 0) {
4997            synchronized (mPidsSelfLocked) {
4998                app = mPidsSelfLocked.get(pid);
4999            }
5000        } else {
5001            app = null;
5002        }
5003
5004        if (app == null) {
5005            Slog.w(TAG, "No pending application record for pid " + pid
5006                    + " (IApplicationThread " + thread + "); dropping process");
5007            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5008            if (pid > 0 && pid != MY_PID) {
5009                Process.killProcessQuiet(pid);
5010            } else {
5011                try {
5012                    thread.scheduleExit();
5013                } catch (Exception e) {
5014                    // Ignore exceptions.
5015                }
5016            }
5017            return false;
5018        }
5019
5020        // If this application record is still attached to a previous
5021        // process, clean it up now.
5022        if (app.thread != null) {
5023            handleAppDiedLocked(app, true, true);
5024        }
5025
5026        // Tell the process all about itself.
5027
5028        if (localLOGV) Slog.v(
5029                TAG, "Binding process pid " + pid + " to record " + app);
5030
5031        final String processName = app.processName;
5032        try {
5033            AppDeathRecipient adr = new AppDeathRecipient(
5034                    app, pid, thread);
5035            thread.asBinder().linkToDeath(adr, 0);
5036            app.deathRecipient = adr;
5037        } catch (RemoteException e) {
5038            app.resetPackageList(mProcessStats);
5039            startProcessLocked(app, "link fail", processName);
5040            return false;
5041        }
5042
5043        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5044
5045        app.makeActive(thread, mProcessStats);
5046        app.curAdj = app.setAdj = -100;
5047        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5048        app.forcingToForeground = null;
5049        updateProcessForegroundLocked(app, false, false);
5050        app.hasShownUi = false;
5051        app.debugging = false;
5052        app.cached = false;
5053
5054        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5055
5056        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5057        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5058
5059        if (!normalMode) {
5060            Slog.i(TAG, "Launching preboot mode app: " + app);
5061        }
5062
5063        if (localLOGV) Slog.v(
5064            TAG, "New app record " + app
5065            + " thread=" + thread.asBinder() + " pid=" + pid);
5066        try {
5067            int testMode = IApplicationThread.DEBUG_OFF;
5068            if (mDebugApp != null && mDebugApp.equals(processName)) {
5069                testMode = mWaitForDebugger
5070                    ? IApplicationThread.DEBUG_WAIT
5071                    : IApplicationThread.DEBUG_ON;
5072                app.debugging = true;
5073                if (mDebugTransient) {
5074                    mDebugApp = mOrigDebugApp;
5075                    mWaitForDebugger = mOrigWaitForDebugger;
5076                }
5077            }
5078            String profileFile = app.instrumentationProfileFile;
5079            ParcelFileDescriptor profileFd = null;
5080            boolean profileAutoStop = false;
5081            if (mProfileApp != null && mProfileApp.equals(processName)) {
5082                mProfileProc = app;
5083                profileFile = mProfileFile;
5084                profileFd = mProfileFd;
5085                profileAutoStop = mAutoStopProfiler;
5086            }
5087            boolean enableOpenGlTrace = false;
5088            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5089                enableOpenGlTrace = true;
5090                mOpenGlTraceApp = null;
5091            }
5092
5093            // If the app is being launched for restore or full backup, set it up specially
5094            boolean isRestrictedBackupMode = false;
5095            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5096                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5097                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5098                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5099            }
5100
5101            ensurePackageDexOpt(app.instrumentationInfo != null
5102                    ? app.instrumentationInfo.packageName
5103                    : app.info.packageName);
5104            if (app.instrumentationClass != null) {
5105                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5106            }
5107            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5108                    + processName + " with config " + mConfiguration);
5109            ApplicationInfo appInfo = app.instrumentationInfo != null
5110                    ? app.instrumentationInfo : app.info;
5111            app.compat = compatibilityInfoForPackageLocked(appInfo);
5112            if (profileFd != null) {
5113                profileFd = profileFd.dup();
5114            }
5115            thread.bindApplication(processName, appInfo, providers,
5116                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5117                    app.instrumentationArguments, app.instrumentationWatcher,
5118                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5119                    isRestrictedBackupMode || !normalMode, app.persistent,
5120                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5121                    mCoreSettingsObserver.getCoreSettingsLocked());
5122            updateLruProcessLocked(app, false, null);
5123            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5124        } catch (Exception e) {
5125            // todo: Yikes!  What should we do?  For now we will try to
5126            // start another process, but that could easily get us in
5127            // an infinite loop of restarting processes...
5128            Slog.w(TAG, "Exception thrown during bind!", e);
5129
5130            app.resetPackageList(mProcessStats);
5131            app.unlinkDeathRecipient();
5132            startProcessLocked(app, "bind fail", processName);
5133            return false;
5134        }
5135
5136        // Remove this record from the list of starting applications.
5137        mPersistentStartingProcesses.remove(app);
5138        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5139                "Attach application locked removing on hold: " + app);
5140        mProcessesOnHold.remove(app);
5141
5142        boolean badApp = false;
5143        boolean didSomething = false;
5144
5145        // See if the top visible activity is waiting to run in this process...
5146        if (normalMode) {
5147            try {
5148                if (mStackSupervisor.attachApplicationLocked(app)) {
5149                    didSomething = true;
5150                }
5151            } catch (Exception e) {
5152                badApp = true;
5153            }
5154        }
5155
5156        // Find any services that should be running in this process...
5157        if (!badApp) {
5158            try {
5159                didSomething |= mServices.attachApplicationLocked(app, processName);
5160            } catch (Exception e) {
5161                badApp = true;
5162            }
5163        }
5164
5165        // Check if a next-broadcast receiver is in this process...
5166        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5167            try {
5168                didSomething |= sendPendingBroadcastsLocked(app);
5169            } catch (Exception e) {
5170                // If the app died trying to launch the receiver we declare it 'bad'
5171                badApp = true;
5172            }
5173        }
5174
5175        // Check whether the next backup agent is in this process...
5176        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5177            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5178            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5179            try {
5180                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5181                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5182                        mBackupTarget.backupMode);
5183            } catch (Exception e) {
5184                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5185                e.printStackTrace();
5186            }
5187        }
5188
5189        if (badApp) {
5190            // todo: Also need to kill application to deal with all
5191            // kinds of exceptions.
5192            handleAppDiedLocked(app, false, true);
5193            return false;
5194        }
5195
5196        if (!didSomething) {
5197            updateOomAdjLocked();
5198        }
5199
5200        return true;
5201    }
5202
5203    @Override
5204    public final void attachApplication(IApplicationThread thread) {
5205        synchronized (this) {
5206            int callingPid = Binder.getCallingPid();
5207            final long origId = Binder.clearCallingIdentity();
5208            attachApplicationLocked(thread, callingPid);
5209            Binder.restoreCallingIdentity(origId);
5210        }
5211    }
5212
5213    @Override
5214    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5215        final long origId = Binder.clearCallingIdentity();
5216        synchronized (this) {
5217            ActivityStack stack = ActivityRecord.getStackLocked(token);
5218            if (stack != null) {
5219                ActivityRecord r =
5220                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5221                if (stopProfiling) {
5222                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5223                        try {
5224                            mProfileFd.close();
5225                        } catch (IOException e) {
5226                        }
5227                        clearProfilerLocked();
5228                    }
5229                }
5230            }
5231        }
5232        Binder.restoreCallingIdentity(origId);
5233    }
5234
5235    void enableScreenAfterBoot() {
5236        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5237                SystemClock.uptimeMillis());
5238        mWindowManager.enableScreenAfterBoot();
5239
5240        synchronized (this) {
5241            updateEventDispatchingLocked();
5242        }
5243    }
5244
5245    @Override
5246    public void showBootMessage(final CharSequence msg, final boolean always) {
5247        enforceNotIsolatedCaller("showBootMessage");
5248        mWindowManager.showBootMessage(msg, always);
5249    }
5250
5251    @Override
5252    public void dismissKeyguardOnNextActivity() {
5253        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5254        final long token = Binder.clearCallingIdentity();
5255        try {
5256            synchronized (this) {
5257                if (DEBUG_LOCKSCREEN) logLockScreen("");
5258                if (mLockScreenShown) {
5259                    mLockScreenShown = false;
5260                    comeOutOfSleepIfNeededLocked();
5261                }
5262                mStackSupervisor.setDismissKeyguard(true);
5263            }
5264        } finally {
5265            Binder.restoreCallingIdentity(token);
5266        }
5267    }
5268
5269    final void finishBooting() {
5270        IntentFilter pkgFilter = new IntentFilter();
5271        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5272        pkgFilter.addDataScheme("package");
5273        mContext.registerReceiver(new BroadcastReceiver() {
5274            @Override
5275            public void onReceive(Context context, Intent intent) {
5276                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5277                if (pkgs != null) {
5278                    for (String pkg : pkgs) {
5279                        synchronized (ActivityManagerService.this) {
5280                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5281                                    "finished booting")) {
5282                                setResultCode(Activity.RESULT_OK);
5283                                return;
5284                            }
5285                        }
5286                    }
5287                }
5288            }
5289        }, pkgFilter);
5290
5291        synchronized (this) {
5292            // Ensure that any processes we had put on hold are now started
5293            // up.
5294            final int NP = mProcessesOnHold.size();
5295            if (NP > 0) {
5296                ArrayList<ProcessRecord> procs =
5297                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5298                for (int ip=0; ip<NP; ip++) {
5299                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5300                            + procs.get(ip));
5301                    startProcessLocked(procs.get(ip), "on-hold", null);
5302                }
5303            }
5304
5305            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5306                // Start looking for apps that are abusing wake locks.
5307                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5308                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5309                // Tell anyone interested that we are done booting!
5310                SystemProperties.set("sys.boot_completed", "1");
5311                SystemProperties.set("dev.bootcomplete", "1");
5312                for (int i=0; i<mStartedUsers.size(); i++) {
5313                    UserStartedState uss = mStartedUsers.valueAt(i);
5314                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5315                        uss.mState = UserStartedState.STATE_RUNNING;
5316                        final int userId = mStartedUsers.keyAt(i);
5317                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5318                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5319                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5320                        broadcastIntentLocked(null, null, intent, null,
5321                                new IIntentReceiver.Stub() {
5322                                    @Override
5323                                    public void performReceive(Intent intent, int resultCode,
5324                                            String data, Bundle extras, boolean ordered,
5325                                            boolean sticky, int sendingUser) {
5326                                        synchronized (ActivityManagerService.this) {
5327                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5328                                                    true, false);
5329                                        }
5330                                    }
5331                                },
5332                                0, null, null,
5333                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5334                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5335                                userId);
5336                    }
5337                }
5338                scheduleStartProfilesLocked();
5339            }
5340        }
5341    }
5342
5343    final void ensureBootCompleted() {
5344        boolean booting;
5345        boolean enableScreen;
5346        synchronized (this) {
5347            booting = mBooting;
5348            mBooting = false;
5349            enableScreen = !mBooted;
5350            mBooted = true;
5351        }
5352
5353        if (booting) {
5354            finishBooting();
5355        }
5356
5357        if (enableScreen) {
5358            enableScreenAfterBoot();
5359        }
5360    }
5361
5362    @Override
5363    public final void activityResumed(IBinder token) {
5364        final long origId = Binder.clearCallingIdentity();
5365        synchronized(this) {
5366            ActivityStack stack = ActivityRecord.getStackLocked(token);
5367            if (stack != null) {
5368                ActivityRecord.activityResumedLocked(token);
5369            }
5370        }
5371        Binder.restoreCallingIdentity(origId);
5372    }
5373
5374    @Override
5375    public final void activityPaused(IBinder token) {
5376        final long origId = Binder.clearCallingIdentity();
5377        synchronized(this) {
5378            ActivityStack stack = ActivityRecord.getStackLocked(token);
5379            if (stack != null) {
5380                stack.activityPausedLocked(token, false);
5381            }
5382        }
5383        Binder.restoreCallingIdentity(origId);
5384    }
5385
5386    @Override
5387    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5388            CharSequence description) {
5389        if (localLOGV) Slog.v(
5390            TAG, "Activity stopped: token=" + token);
5391
5392        // Refuse possible leaked file descriptors
5393        if (icicle != null && icicle.hasFileDescriptors()) {
5394            throw new IllegalArgumentException("File descriptors passed in Bundle");
5395        }
5396
5397        ActivityRecord r = null;
5398
5399        final long origId = Binder.clearCallingIdentity();
5400
5401        synchronized (this) {
5402            r = ActivityRecord.isInStackLocked(token);
5403            if (r != null) {
5404                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5405            }
5406        }
5407
5408        if (r != null) {
5409            sendPendingThumbnail(r, null, null, null, false);
5410        }
5411
5412        trimApplications();
5413
5414        Binder.restoreCallingIdentity(origId);
5415    }
5416
5417    @Override
5418    public final void activityDestroyed(IBinder token) {
5419        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5420        synchronized (this) {
5421            ActivityStack stack = ActivityRecord.getStackLocked(token);
5422            if (stack != null) {
5423                stack.activityDestroyedLocked(token);
5424            }
5425        }
5426    }
5427
5428    @Override
5429    public String getCallingPackage(IBinder token) {
5430        synchronized (this) {
5431            ActivityRecord r = getCallingRecordLocked(token);
5432            return r != null ? r.info.packageName : null;
5433        }
5434    }
5435
5436    @Override
5437    public ComponentName getCallingActivity(IBinder token) {
5438        synchronized (this) {
5439            ActivityRecord r = getCallingRecordLocked(token);
5440            return r != null ? r.intent.getComponent() : null;
5441        }
5442    }
5443
5444    private ActivityRecord getCallingRecordLocked(IBinder token) {
5445        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5446        if (r == null) {
5447            return null;
5448        }
5449        return r.resultTo;
5450    }
5451
5452    @Override
5453    public ComponentName getActivityClassForToken(IBinder token) {
5454        synchronized(this) {
5455            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5456            if (r == null) {
5457                return null;
5458            }
5459            return r.intent.getComponent();
5460        }
5461    }
5462
5463    @Override
5464    public String getPackageForToken(IBinder token) {
5465        synchronized(this) {
5466            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5467            if (r == null) {
5468                return null;
5469            }
5470            return r.packageName;
5471        }
5472    }
5473
5474    @Override
5475    public IIntentSender getIntentSender(int type,
5476            String packageName, IBinder token, String resultWho,
5477            int requestCode, Intent[] intents, String[] resolvedTypes,
5478            int flags, Bundle options, int userId) {
5479        enforceNotIsolatedCaller("getIntentSender");
5480        // Refuse possible leaked file descriptors
5481        if (intents != null) {
5482            if (intents.length < 1) {
5483                throw new IllegalArgumentException("Intents array length must be >= 1");
5484            }
5485            for (int i=0; i<intents.length; i++) {
5486                Intent intent = intents[i];
5487                if (intent != null) {
5488                    if (intent.hasFileDescriptors()) {
5489                        throw new IllegalArgumentException("File descriptors passed in Intent");
5490                    }
5491                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5492                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5493                        throw new IllegalArgumentException(
5494                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5495                    }
5496                    intents[i] = new Intent(intent);
5497                }
5498            }
5499            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5500                throw new IllegalArgumentException(
5501                        "Intent array length does not match resolvedTypes length");
5502            }
5503        }
5504        if (options != null) {
5505            if (options.hasFileDescriptors()) {
5506                throw new IllegalArgumentException("File descriptors passed in options");
5507            }
5508        }
5509
5510        synchronized(this) {
5511            int callingUid = Binder.getCallingUid();
5512            int origUserId = userId;
5513            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5514                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5515                    "getIntentSender", null);
5516            if (origUserId == UserHandle.USER_CURRENT) {
5517                // We don't want to evaluate this until the pending intent is
5518                // actually executed.  However, we do want to always do the
5519                // security checking for it above.
5520                userId = UserHandle.USER_CURRENT;
5521            }
5522            try {
5523                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5524                    int uid = AppGlobals.getPackageManager()
5525                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5526                    if (!UserHandle.isSameApp(callingUid, uid)) {
5527                        String msg = "Permission Denial: getIntentSender() from pid="
5528                            + Binder.getCallingPid()
5529                            + ", uid=" + Binder.getCallingUid()
5530                            + ", (need uid=" + uid + ")"
5531                            + " is not allowed to send as package " + packageName;
5532                        Slog.w(TAG, msg);
5533                        throw new SecurityException(msg);
5534                    }
5535                }
5536
5537                return getIntentSenderLocked(type, packageName, callingUid, userId,
5538                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5539
5540            } catch (RemoteException e) {
5541                throw new SecurityException(e);
5542            }
5543        }
5544    }
5545
5546    IIntentSender getIntentSenderLocked(int type, String packageName,
5547            int callingUid, int userId, IBinder token, String resultWho,
5548            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5549            Bundle options) {
5550        if (DEBUG_MU)
5551            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5552        ActivityRecord activity = null;
5553        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5554            activity = ActivityRecord.isInStackLocked(token);
5555            if (activity == null) {
5556                return null;
5557            }
5558            if (activity.finishing) {
5559                return null;
5560            }
5561        }
5562
5563        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5564        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5565        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5566        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5567                |PendingIntent.FLAG_UPDATE_CURRENT);
5568
5569        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5570                type, packageName, activity, resultWho,
5571                requestCode, intents, resolvedTypes, flags, options, userId);
5572        WeakReference<PendingIntentRecord> ref;
5573        ref = mIntentSenderRecords.get(key);
5574        PendingIntentRecord rec = ref != null ? ref.get() : null;
5575        if (rec != null) {
5576            if (!cancelCurrent) {
5577                if (updateCurrent) {
5578                    if (rec.key.requestIntent != null) {
5579                        rec.key.requestIntent.replaceExtras(intents != null ?
5580                                intents[intents.length - 1] : null);
5581                    }
5582                    if (intents != null) {
5583                        intents[intents.length-1] = rec.key.requestIntent;
5584                        rec.key.allIntents = intents;
5585                        rec.key.allResolvedTypes = resolvedTypes;
5586                    } else {
5587                        rec.key.allIntents = null;
5588                        rec.key.allResolvedTypes = null;
5589                    }
5590                }
5591                return rec;
5592            }
5593            rec.canceled = true;
5594            mIntentSenderRecords.remove(key);
5595        }
5596        if (noCreate) {
5597            return rec;
5598        }
5599        rec = new PendingIntentRecord(this, key, callingUid);
5600        mIntentSenderRecords.put(key, rec.ref);
5601        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5602            if (activity.pendingResults == null) {
5603                activity.pendingResults
5604                        = new HashSet<WeakReference<PendingIntentRecord>>();
5605            }
5606            activity.pendingResults.add(rec.ref);
5607        }
5608        return rec;
5609    }
5610
5611    @Override
5612    public void cancelIntentSender(IIntentSender sender) {
5613        if (!(sender instanceof PendingIntentRecord)) {
5614            return;
5615        }
5616        synchronized(this) {
5617            PendingIntentRecord rec = (PendingIntentRecord)sender;
5618            try {
5619                int uid = AppGlobals.getPackageManager()
5620                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5621                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5622                    String msg = "Permission Denial: cancelIntentSender() from pid="
5623                        + Binder.getCallingPid()
5624                        + ", uid=" + Binder.getCallingUid()
5625                        + " is not allowed to cancel packges "
5626                        + rec.key.packageName;
5627                    Slog.w(TAG, msg);
5628                    throw new SecurityException(msg);
5629                }
5630            } catch (RemoteException e) {
5631                throw new SecurityException(e);
5632            }
5633            cancelIntentSenderLocked(rec, true);
5634        }
5635    }
5636
5637    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5638        rec.canceled = true;
5639        mIntentSenderRecords.remove(rec.key);
5640        if (cleanActivity && rec.key.activity != null) {
5641            rec.key.activity.pendingResults.remove(rec.ref);
5642        }
5643    }
5644
5645    @Override
5646    public String getPackageForIntentSender(IIntentSender pendingResult) {
5647        if (!(pendingResult instanceof PendingIntentRecord)) {
5648            return null;
5649        }
5650        try {
5651            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5652            return res.key.packageName;
5653        } catch (ClassCastException e) {
5654        }
5655        return null;
5656    }
5657
5658    @Override
5659    public int getUidForIntentSender(IIntentSender sender) {
5660        if (sender instanceof PendingIntentRecord) {
5661            try {
5662                PendingIntentRecord res = (PendingIntentRecord)sender;
5663                return res.uid;
5664            } catch (ClassCastException e) {
5665            }
5666        }
5667        return -1;
5668    }
5669
5670    @Override
5671    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5672        if (!(pendingResult instanceof PendingIntentRecord)) {
5673            return false;
5674        }
5675        try {
5676            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5677            if (res.key.allIntents == null) {
5678                return false;
5679            }
5680            for (int i=0; i<res.key.allIntents.length; i++) {
5681                Intent intent = res.key.allIntents[i];
5682                if (intent.getPackage() != null && intent.getComponent() != null) {
5683                    return false;
5684                }
5685            }
5686            return true;
5687        } catch (ClassCastException e) {
5688        }
5689        return false;
5690    }
5691
5692    @Override
5693    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5694        if (!(pendingResult instanceof PendingIntentRecord)) {
5695            return false;
5696        }
5697        try {
5698            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5699            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5700                return true;
5701            }
5702            return false;
5703        } catch (ClassCastException e) {
5704        }
5705        return false;
5706    }
5707
5708    @Override
5709    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5710        if (!(pendingResult instanceof PendingIntentRecord)) {
5711            return null;
5712        }
5713        try {
5714            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5715            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5716        } catch (ClassCastException e) {
5717        }
5718        return null;
5719    }
5720
5721    @Override
5722    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5723        if (!(pendingResult instanceof PendingIntentRecord)) {
5724            return null;
5725        }
5726        try {
5727            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5728            Intent intent = res.key.requestIntent;
5729            if (intent != null) {
5730                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5731                        || res.lastTagPrefix.equals(prefix))) {
5732                    return res.lastTag;
5733                }
5734                res.lastTagPrefix = prefix;
5735                StringBuilder sb = new StringBuilder(128);
5736                if (prefix != null) {
5737                    sb.append(prefix);
5738                }
5739                if (intent.getAction() != null) {
5740                    sb.append(intent.getAction());
5741                } else if (intent.getComponent() != null) {
5742                    intent.getComponent().appendShortString(sb);
5743                } else {
5744                    sb.append("?");
5745                }
5746                return res.lastTag = sb.toString();
5747            }
5748        } catch (ClassCastException e) {
5749        }
5750        return null;
5751    }
5752
5753    @Override
5754    public void setProcessLimit(int max) {
5755        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5756                "setProcessLimit()");
5757        synchronized (this) {
5758            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5759            mProcessLimitOverride = max;
5760        }
5761        trimApplications();
5762    }
5763
5764    @Override
5765    public int getProcessLimit() {
5766        synchronized (this) {
5767            return mProcessLimitOverride;
5768        }
5769    }
5770
5771    void foregroundTokenDied(ForegroundToken token) {
5772        synchronized (ActivityManagerService.this) {
5773            synchronized (mPidsSelfLocked) {
5774                ForegroundToken cur
5775                    = mForegroundProcesses.get(token.pid);
5776                if (cur != token) {
5777                    return;
5778                }
5779                mForegroundProcesses.remove(token.pid);
5780                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5781                if (pr == null) {
5782                    return;
5783                }
5784                pr.forcingToForeground = null;
5785                updateProcessForegroundLocked(pr, false, false);
5786            }
5787            updateOomAdjLocked();
5788        }
5789    }
5790
5791    @Override
5792    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5793        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5794                "setProcessForeground()");
5795        synchronized(this) {
5796            boolean changed = false;
5797
5798            synchronized (mPidsSelfLocked) {
5799                ProcessRecord pr = mPidsSelfLocked.get(pid);
5800                if (pr == null && isForeground) {
5801                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5802                    return;
5803                }
5804                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5805                if (oldToken != null) {
5806                    oldToken.token.unlinkToDeath(oldToken, 0);
5807                    mForegroundProcesses.remove(pid);
5808                    if (pr != null) {
5809                        pr.forcingToForeground = null;
5810                    }
5811                    changed = true;
5812                }
5813                if (isForeground && token != null) {
5814                    ForegroundToken newToken = new ForegroundToken() {
5815                        @Override
5816                        public void binderDied() {
5817                            foregroundTokenDied(this);
5818                        }
5819                    };
5820                    newToken.pid = pid;
5821                    newToken.token = token;
5822                    try {
5823                        token.linkToDeath(newToken, 0);
5824                        mForegroundProcesses.put(pid, newToken);
5825                        pr.forcingToForeground = token;
5826                        changed = true;
5827                    } catch (RemoteException e) {
5828                        // If the process died while doing this, we will later
5829                        // do the cleanup with the process death link.
5830                    }
5831                }
5832            }
5833
5834            if (changed) {
5835                updateOomAdjLocked();
5836            }
5837        }
5838    }
5839
5840    // =========================================================
5841    // PERMISSIONS
5842    // =========================================================
5843
5844    static class PermissionController extends IPermissionController.Stub {
5845        ActivityManagerService mActivityManagerService;
5846        PermissionController(ActivityManagerService activityManagerService) {
5847            mActivityManagerService = activityManagerService;
5848        }
5849
5850        @Override
5851        public boolean checkPermission(String permission, int pid, int uid) {
5852            return mActivityManagerService.checkPermission(permission, pid,
5853                    uid) == PackageManager.PERMISSION_GRANTED;
5854        }
5855    }
5856
5857    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5858        @Override
5859        public int checkComponentPermission(String permission, int pid, int uid,
5860                int owningUid, boolean exported) {
5861            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5862                    owningUid, exported);
5863        }
5864
5865        @Override
5866        public Object getAMSLock() {
5867            return ActivityManagerService.this;
5868        }
5869    }
5870
5871    /**
5872     * This can be called with or without the global lock held.
5873     */
5874    int checkComponentPermission(String permission, int pid, int uid,
5875            int owningUid, boolean exported) {
5876        // We might be performing an operation on behalf of an indirect binder
5877        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5878        // client identity accordingly before proceeding.
5879        Identity tlsIdentity = sCallerIdentity.get();
5880        if (tlsIdentity != null) {
5881            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5882                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5883            uid = tlsIdentity.uid;
5884            pid = tlsIdentity.pid;
5885        }
5886
5887        if (pid == MY_PID) {
5888            return PackageManager.PERMISSION_GRANTED;
5889        }
5890
5891        return ActivityManager.checkComponentPermission(permission, uid,
5892                owningUid, exported);
5893    }
5894
5895    /**
5896     * As the only public entry point for permissions checking, this method
5897     * can enforce the semantic that requesting a check on a null global
5898     * permission is automatically denied.  (Internally a null permission
5899     * string is used when calling {@link #checkComponentPermission} in cases
5900     * when only uid-based security is needed.)
5901     *
5902     * This can be called with or without the global lock held.
5903     */
5904    @Override
5905    public int checkPermission(String permission, int pid, int uid) {
5906        if (permission == null) {
5907            return PackageManager.PERMISSION_DENIED;
5908        }
5909        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5910    }
5911
5912    /**
5913     * Binder IPC calls go through the public entry point.
5914     * This can be called with or without the global lock held.
5915     */
5916    int checkCallingPermission(String permission) {
5917        return checkPermission(permission,
5918                Binder.getCallingPid(),
5919                UserHandle.getAppId(Binder.getCallingUid()));
5920    }
5921
5922    /**
5923     * This can be called with or without the global lock held.
5924     */
5925    void enforceCallingPermission(String permission, String func) {
5926        if (checkCallingPermission(permission)
5927                == PackageManager.PERMISSION_GRANTED) {
5928            return;
5929        }
5930
5931        String msg = "Permission Denial: " + func + " from pid="
5932                + Binder.getCallingPid()
5933                + ", uid=" + Binder.getCallingUid()
5934                + " requires " + permission;
5935        Slog.w(TAG, msg);
5936        throw new SecurityException(msg);
5937    }
5938
5939    /**
5940     * Determine if UID is holding permissions required to access {@link Uri} in
5941     * the given {@link ProviderInfo}. Final permission checking is always done
5942     * in {@link ContentProvider}.
5943     */
5944    private final boolean checkHoldingPermissionsLocked(
5945            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
5946        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5947                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5948
5949        if (pi.applicationInfo.uid == uid) {
5950            return true;
5951        } else if (!pi.exported) {
5952            return false;
5953        }
5954
5955        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5956        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5957        try {
5958            // check if target holds top-level <provider> permissions
5959            if (!readMet && pi.readPermission != null
5960                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5961                readMet = true;
5962            }
5963            if (!writeMet && pi.writePermission != null
5964                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5965                writeMet = true;
5966            }
5967
5968            // track if unprotected read/write is allowed; any denied
5969            // <path-permission> below removes this ability
5970            boolean allowDefaultRead = pi.readPermission == null;
5971            boolean allowDefaultWrite = pi.writePermission == null;
5972
5973            // check if target holds any <path-permission> that match uri
5974            final PathPermission[] pps = pi.pathPermissions;
5975            if (pps != null) {
5976                final String path = uri.getPath();
5977                int i = pps.length;
5978                while (i > 0 && (!readMet || !writeMet)) {
5979                    i--;
5980                    PathPermission pp = pps[i];
5981                    if (pp.match(path)) {
5982                        if (!readMet) {
5983                            final String pprperm = pp.getReadPermission();
5984                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5985                                    + pprperm + " for " + pp.getPath()
5986                                    + ": match=" + pp.match(path)
5987                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5988                            if (pprperm != null) {
5989                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5990                                    readMet = true;
5991                                } else {
5992                                    allowDefaultRead = false;
5993                                }
5994                            }
5995                        }
5996                        if (!writeMet) {
5997                            final String ppwperm = pp.getWritePermission();
5998                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5999                                    + ppwperm + " for " + pp.getPath()
6000                                    + ": match=" + pp.match(path)
6001                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6002                            if (ppwperm != null) {
6003                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6004                                    writeMet = true;
6005                                } else {
6006                                    allowDefaultWrite = false;
6007                                }
6008                            }
6009                        }
6010                    }
6011                }
6012            }
6013
6014            // grant unprotected <provider> read/write, if not blocked by
6015            // <path-permission> above
6016            if (allowDefaultRead) readMet = true;
6017            if (allowDefaultWrite) writeMet = true;
6018
6019        } catch (RemoteException e) {
6020            return false;
6021        }
6022
6023        return readMet && writeMet;
6024    }
6025
6026    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6027        ProviderInfo pi = null;
6028        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6029        if (cpr != null) {
6030            pi = cpr.info;
6031        } else {
6032            try {
6033                pi = AppGlobals.getPackageManager().resolveContentProvider(
6034                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6035            } catch (RemoteException ex) {
6036            }
6037        }
6038        return pi;
6039    }
6040
6041    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
6042        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6043        if (targetUris != null) {
6044            return targetUris.get(uri);
6045        }
6046        return null;
6047    }
6048
6049    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6050            String targetPkg, int targetUid, GrantUri uri) {
6051        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6052        if (targetUris == null) {
6053            targetUris = Maps.newArrayMap();
6054            mGrantedUriPermissions.put(targetUid, targetUris);
6055        }
6056
6057        UriPermission perm = targetUris.get(uri);
6058        if (perm == null) {
6059            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
6060            targetUris.put(uri, perm);
6061        }
6062
6063        return perm;
6064    }
6065
6066    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6067        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6068        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6069                : UriPermission.STRENGTH_OWNED;
6070
6071        // Root gets to do everything.
6072        if (uid == 0) {
6073            return true;
6074        }
6075
6076        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6077        if (perms == null) return false;
6078
6079        // First look for exact match
6080        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6081        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6082            return true;
6083        }
6084
6085        // No exact match, look for prefixes
6086        final int N = perms.size();
6087        for (int i = 0; i < N; i++) {
6088            final UriPermission perm = perms.valueAt(i);
6089            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6090                    && perm.getStrength(modeFlags) >= minStrength) {
6091                return true;
6092            }
6093        }
6094
6095        return false;
6096    }
6097
6098    @Override
6099    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6100        enforceNotIsolatedCaller("checkUriPermission");
6101
6102        // Another redirected-binder-call permissions check as in
6103        // {@link checkComponentPermission}.
6104        Identity tlsIdentity = sCallerIdentity.get();
6105        if (tlsIdentity != null) {
6106            uid = tlsIdentity.uid;
6107            pid = tlsIdentity.pid;
6108        }
6109
6110        // Our own process gets to do everything.
6111        if (pid == MY_PID) {
6112            return PackageManager.PERMISSION_GRANTED;
6113        }
6114        synchronized (this) {
6115            return checkUriPermissionLocked(uri, uid, modeFlags)
6116                    ? PackageManager.PERMISSION_GRANTED
6117                    : PackageManager.PERMISSION_DENIED;
6118        }
6119    }
6120
6121    /**
6122     * Check if the targetPkg can be granted permission to access uri by
6123     * the callingUid using the given modeFlags.  Throws a security exception
6124     * if callingUid is not allowed to do this.  Returns the uid of the target
6125     * if the URI permission grant should be performed; returns -1 if it is not
6126     * needed (for example targetPkg already has permission to access the URI).
6127     * If you already know the uid of the target, you can supply it in
6128     * lastTargetUid else set that to -1.
6129     */
6130    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6131            Uri uri, final int modeFlags, int lastTargetUid) {
6132        if (!Intent.isAccessUriMode(modeFlags)) {
6133            return -1;
6134        }
6135
6136        if (targetPkg != null) {
6137            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6138                    "Checking grant " + targetPkg + " permission to " + uri);
6139        }
6140
6141        final IPackageManager pm = AppGlobals.getPackageManager();
6142
6143        // If this is not a content: uri, we can't do anything with it.
6144        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6145            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6146                    "Can't grant URI permission for non-content URI: " + uri);
6147            return -1;
6148        }
6149
6150        final String authority = uri.getAuthority();
6151        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6152        if (pi == null) {
6153            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6154            return -1;
6155        }
6156
6157        int targetUid = lastTargetUid;
6158        if (targetUid < 0 && targetPkg != null) {
6159            try {
6160                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6161                if (targetUid < 0) {
6162                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6163                            "Can't grant URI permission no uid for: " + targetPkg);
6164                    return -1;
6165                }
6166            } catch (RemoteException ex) {
6167                return -1;
6168            }
6169        }
6170
6171        if (targetUid >= 0) {
6172            // First...  does the target actually need this permission?
6173            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6174                // No need to grant the target this permission.
6175                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6176                        "Target " + targetPkg + " already has full permission to " + uri);
6177                return -1;
6178            }
6179        } else {
6180            // First...  there is no target package, so can anyone access it?
6181            boolean allowed = pi.exported;
6182            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6183                if (pi.readPermission != null) {
6184                    allowed = false;
6185                }
6186            }
6187            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6188                if (pi.writePermission != null) {
6189                    allowed = false;
6190                }
6191            }
6192            if (allowed) {
6193                return -1;
6194            }
6195        }
6196
6197        // Second...  is the provider allowing granting of URI permissions?
6198        if (!pi.grantUriPermissions) {
6199            throw new SecurityException("Provider " + pi.packageName
6200                    + "/" + pi.name
6201                    + " does not allow granting of Uri permissions (uri "
6202                    + uri + ")");
6203        }
6204        if (pi.uriPermissionPatterns != null) {
6205            final int N = pi.uriPermissionPatterns.length;
6206            boolean allowed = false;
6207            for (int i=0; i<N; i++) {
6208                if (pi.uriPermissionPatterns[i] != null
6209                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6210                    allowed = true;
6211                    break;
6212                }
6213            }
6214            if (!allowed) {
6215                throw new SecurityException("Provider " + pi.packageName
6216                        + "/" + pi.name
6217                        + " does not allow granting of permission to path of Uri "
6218                        + uri);
6219            }
6220        }
6221
6222        // Third...  does the caller itself have permission to access
6223        // this uri?
6224        if (callingUid != Process.myUid()) {
6225            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6226                // Require they hold a strong enough Uri permission
6227                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6228                    throw new SecurityException("Uid " + callingUid
6229                            + " does not have permission to uri " + uri);
6230                }
6231            }
6232        }
6233
6234        return targetUid;
6235    }
6236
6237    @Override
6238    public int checkGrantUriPermission(int callingUid, String targetPkg,
6239            Uri uri, final int modeFlags) {
6240        enforceNotIsolatedCaller("checkGrantUriPermission");
6241        synchronized(this) {
6242            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6243        }
6244    }
6245
6246    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6247            final int modeFlags, UriPermissionOwner owner) {
6248        if (!Intent.isAccessUriMode(modeFlags)) {
6249            return;
6250        }
6251
6252        // So here we are: the caller has the assumed permission
6253        // to the uri, and the target doesn't.  Let's now give this to
6254        // the target.
6255
6256        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6257                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6258
6259        final String authority = uri.getAuthority();
6260        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6261        if (pi == null) {
6262            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6263            return;
6264        }
6265
6266        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6267        final UriPermission perm = findOrCreateUriPermissionLocked(
6268                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6269        perm.grantModes(modeFlags, owner);
6270    }
6271
6272    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6273            final int modeFlags, UriPermissionOwner owner) {
6274        if (targetPkg == null) {
6275            throw new NullPointerException("targetPkg");
6276        }
6277
6278        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6279        if (targetUid < 0) {
6280            return;
6281        }
6282
6283        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6284    }
6285
6286    static class NeededUriGrants extends ArrayList<Uri> {
6287        final String targetPkg;
6288        final int targetUid;
6289        final int flags;
6290
6291        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6292            this.targetPkg = targetPkg;
6293            this.targetUid = targetUid;
6294            this.flags = flags;
6295        }
6296    }
6297
6298    /**
6299     * Like checkGrantUriPermissionLocked, but takes an Intent.
6300     */
6301    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6302            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6303        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6304                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6305                + " clip=" + (intent != null ? intent.getClipData() : null)
6306                + " from " + intent + "; flags=0x"
6307                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6308
6309        if (targetPkg == null) {
6310            throw new NullPointerException("targetPkg");
6311        }
6312
6313        if (intent == null) {
6314            return null;
6315        }
6316        Uri data = intent.getData();
6317        ClipData clip = intent.getClipData();
6318        if (data == null && clip == null) {
6319            return null;
6320        }
6321
6322        if (data != null) {
6323            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6324                mode, needed != null ? needed.targetUid : -1);
6325            if (targetUid > 0) {
6326                if (needed == null) {
6327                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6328                }
6329                needed.add(data);
6330            }
6331        }
6332        if (clip != null) {
6333            for (int i=0; i<clip.getItemCount(); i++) {
6334                Uri uri = clip.getItemAt(i).getUri();
6335                if (uri != null) {
6336                    int targetUid = -1;
6337                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6338                            mode, needed != null ? needed.targetUid : -1);
6339                    if (targetUid > 0) {
6340                        if (needed == null) {
6341                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6342                        }
6343                        needed.add(uri);
6344                    }
6345                } else {
6346                    Intent clipIntent = clip.getItemAt(i).getIntent();
6347                    if (clipIntent != null) {
6348                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6349                                callingUid, targetPkg, clipIntent, mode, needed);
6350                        if (newNeeded != null) {
6351                            needed = newNeeded;
6352                        }
6353                    }
6354                }
6355            }
6356        }
6357
6358        return needed;
6359    }
6360
6361    /**
6362     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6363     */
6364    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6365            UriPermissionOwner owner) {
6366        if (needed != null) {
6367            for (int i=0; i<needed.size(); i++) {
6368                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6369                        needed.get(i), needed.flags, owner);
6370            }
6371        }
6372    }
6373
6374    void grantUriPermissionFromIntentLocked(int callingUid,
6375            String targetPkg, Intent intent, UriPermissionOwner owner) {
6376        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6377                intent, intent != null ? intent.getFlags() : 0, null);
6378        if (needed == null) {
6379            return;
6380        }
6381
6382        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6383    }
6384
6385    @Override
6386    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6387            Uri uri, final int modeFlags) {
6388        enforceNotIsolatedCaller("grantUriPermission");
6389        synchronized(this) {
6390            final ProcessRecord r = getRecordForAppLocked(caller);
6391            if (r == null) {
6392                throw new SecurityException("Unable to find app for caller "
6393                        + caller
6394                        + " when granting permission to uri " + uri);
6395            }
6396            if (targetPkg == null) {
6397                throw new IllegalArgumentException("null target");
6398            }
6399            if (uri == null) {
6400                throw new IllegalArgumentException("null uri");
6401            }
6402
6403            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6404                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6405                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6406                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6407
6408            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6409        }
6410    }
6411
6412    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6413        if (perm.modeFlags == 0) {
6414            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6415                    perm.targetUid);
6416            if (perms != null) {
6417                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6418                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6419
6420                perms.remove(perm.uri);
6421                if (perms.isEmpty()) {
6422                    mGrantedUriPermissions.remove(perm.targetUid);
6423                }
6424            }
6425        }
6426    }
6427
6428    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6429        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6430
6431        final IPackageManager pm = AppGlobals.getPackageManager();
6432        final String authority = uri.getAuthority();
6433        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6434        if (pi == null) {
6435            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6436            return;
6437        }
6438
6439        // Does the caller have this permission on the URI?
6440        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6441            // Right now, if you are not the original owner of the permission,
6442            // you are not allowed to revoke it.
6443            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6444                throw new SecurityException("Uid " + callingUid
6445                        + " does not have permission to uri " + uri);
6446            //}
6447        }
6448
6449        boolean persistChanged = false;
6450
6451        // Go through all of the permissions and remove any that match.
6452        int N = mGrantedUriPermissions.size();
6453        for (int i = 0; i < N; i++) {
6454            final int targetUid = mGrantedUriPermissions.keyAt(i);
6455            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6456
6457            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6458                final UriPermission perm = it.next();
6459                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6460                    if (DEBUG_URI_PERMISSION)
6461                        Slog.v(TAG,
6462                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6463                    persistChanged |= perm.revokeModes(
6464                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6465                    if (perm.modeFlags == 0) {
6466                        it.remove();
6467                    }
6468                }
6469            }
6470
6471            if (perms.isEmpty()) {
6472                mGrantedUriPermissions.remove(targetUid);
6473                N--;
6474                i--;
6475            }
6476        }
6477
6478        if (persistChanged) {
6479            schedulePersistUriGrants();
6480        }
6481    }
6482
6483    @Override
6484    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6485            final int modeFlags) {
6486        enforceNotIsolatedCaller("revokeUriPermission");
6487        synchronized(this) {
6488            final ProcessRecord r = getRecordForAppLocked(caller);
6489            if (r == null) {
6490                throw new SecurityException("Unable to find app for caller "
6491                        + caller
6492                        + " when revoking permission to uri " + uri);
6493            }
6494            if (uri == null) {
6495                Slog.w(TAG, "revokeUriPermission: null uri");
6496                return;
6497            }
6498
6499            if (!Intent.isAccessUriMode(modeFlags)) {
6500                return;
6501            }
6502
6503            final IPackageManager pm = AppGlobals.getPackageManager();
6504            final String authority = uri.getAuthority();
6505            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6506            if (pi == null) {
6507                Slog.w(TAG, "No content provider found for permission revoke: "
6508                        + uri.toSafeString());
6509                return;
6510            }
6511
6512            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6513        }
6514    }
6515
6516    /**
6517     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6518     * given package.
6519     *
6520     * @param packageName Package name to match, or {@code null} to apply to all
6521     *            packages.
6522     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6523     *            to all users.
6524     * @param persistable If persistable grants should be removed.
6525     */
6526    private void removeUriPermissionsForPackageLocked(
6527            String packageName, int userHandle, boolean persistable) {
6528        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6529            throw new IllegalArgumentException("Must narrow by either package or user");
6530        }
6531
6532        boolean persistChanged = false;
6533
6534        int N = mGrantedUriPermissions.size();
6535        for (int i = 0; i < N; i++) {
6536            final int targetUid = mGrantedUriPermissions.keyAt(i);
6537            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6538
6539            // Only inspect grants matching user
6540            if (userHandle == UserHandle.USER_ALL
6541                    || userHandle == UserHandle.getUserId(targetUid)) {
6542                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6543                    final UriPermission perm = it.next();
6544
6545                    // Only inspect grants matching package
6546                    if (packageName == null || perm.sourcePkg.equals(packageName)
6547                            || perm.targetPkg.equals(packageName)) {
6548                        persistChanged |= perm.revokeModes(
6549                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6550
6551                        // Only remove when no modes remain; any persisted grants
6552                        // will keep this alive.
6553                        if (perm.modeFlags == 0) {
6554                            it.remove();
6555                        }
6556                    }
6557                }
6558
6559                if (perms.isEmpty()) {
6560                    mGrantedUriPermissions.remove(targetUid);
6561                    N--;
6562                    i--;
6563                }
6564            }
6565        }
6566
6567        if (persistChanged) {
6568            schedulePersistUriGrants();
6569        }
6570    }
6571
6572    @Override
6573    public IBinder newUriPermissionOwner(String name) {
6574        enforceNotIsolatedCaller("newUriPermissionOwner");
6575        synchronized(this) {
6576            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6577            return owner.getExternalTokenLocked();
6578        }
6579    }
6580
6581    @Override
6582    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6583            Uri uri, final int modeFlags) {
6584        synchronized(this) {
6585            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6586            if (owner == null) {
6587                throw new IllegalArgumentException("Unknown owner: " + token);
6588            }
6589            if (fromUid != Binder.getCallingUid()) {
6590                if (Binder.getCallingUid() != Process.myUid()) {
6591                    // Only system code can grant URI permissions on behalf
6592                    // of other users.
6593                    throw new SecurityException("nice try");
6594                }
6595            }
6596            if (targetPkg == null) {
6597                throw new IllegalArgumentException("null target");
6598            }
6599            if (uri == null) {
6600                throw new IllegalArgumentException("null uri");
6601            }
6602
6603            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6604        }
6605    }
6606
6607    @Override
6608    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6609        synchronized(this) {
6610            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6611            if (owner == null) {
6612                throw new IllegalArgumentException("Unknown owner: " + token);
6613            }
6614
6615            if (uri == null) {
6616                owner.removeUriPermissionsLocked(mode);
6617            } else {
6618                owner.removeUriPermissionLocked(uri, mode);
6619            }
6620        }
6621    }
6622
6623    private void schedulePersistUriGrants() {
6624        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6625            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6626                    10 * DateUtils.SECOND_IN_MILLIS);
6627        }
6628    }
6629
6630    private void writeGrantedUriPermissions() {
6631        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6632
6633        // Snapshot permissions so we can persist without lock
6634        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6635        synchronized (this) {
6636            final int size = mGrantedUriPermissions.size();
6637            for (int i = 0; i < size; i++) {
6638                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6639                for (UriPermission perm : perms.values()) {
6640                    if (perm.persistedModeFlags != 0) {
6641                        persist.add(perm.snapshot());
6642                    }
6643                }
6644            }
6645        }
6646
6647        FileOutputStream fos = null;
6648        try {
6649            fos = mGrantFile.startWrite();
6650
6651            XmlSerializer out = new FastXmlSerializer();
6652            out.setOutput(fos, "utf-8");
6653            out.startDocument(null, true);
6654            out.startTag(null, TAG_URI_GRANTS);
6655            for (UriPermission.Snapshot perm : persist) {
6656                out.startTag(null, TAG_URI_GRANT);
6657                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6658                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6659                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6660                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6661                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6662                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6663                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6664                out.endTag(null, TAG_URI_GRANT);
6665            }
6666            out.endTag(null, TAG_URI_GRANTS);
6667            out.endDocument();
6668
6669            mGrantFile.finishWrite(fos);
6670        } catch (IOException e) {
6671            if (fos != null) {
6672                mGrantFile.failWrite(fos);
6673            }
6674        }
6675    }
6676
6677    private void readGrantedUriPermissionsLocked() {
6678        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6679
6680        final long now = System.currentTimeMillis();
6681
6682        FileInputStream fis = null;
6683        try {
6684            fis = mGrantFile.openRead();
6685            final XmlPullParser in = Xml.newPullParser();
6686            in.setInput(fis, null);
6687
6688            int type;
6689            while ((type = in.next()) != END_DOCUMENT) {
6690                final String tag = in.getName();
6691                if (type == START_TAG) {
6692                    if (TAG_URI_GRANT.equals(tag)) {
6693                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6694                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6695                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6696                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6697                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6698                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6699                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6700
6701                        // Sanity check that provider still belongs to source package
6702                        final ProviderInfo pi = getProviderInfoLocked(
6703                                uri.getAuthority(), userHandle);
6704                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6705                            int targetUid = -1;
6706                            try {
6707                                targetUid = AppGlobals.getPackageManager()
6708                                        .getPackageUid(targetPkg, userHandle);
6709                            } catch (RemoteException e) {
6710                            }
6711                            if (targetUid != -1) {
6712                                final UriPermission perm = findOrCreateUriPermissionLocked(
6713                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6714                                perm.initPersistedModes(modeFlags, createdTime);
6715                            }
6716                        } else {
6717                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6718                                    + " but instead found " + pi);
6719                        }
6720                    }
6721                }
6722            }
6723        } catch (FileNotFoundException e) {
6724            // Missing grants is okay
6725        } catch (IOException e) {
6726            Log.wtf(TAG, "Failed reading Uri grants", e);
6727        } catch (XmlPullParserException e) {
6728            Log.wtf(TAG, "Failed reading Uri grants", e);
6729        } finally {
6730            IoUtils.closeQuietly(fis);
6731        }
6732    }
6733
6734    @Override
6735    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6736        enforceNotIsolatedCaller("takePersistableUriPermission");
6737
6738        Preconditions.checkFlagsArgument(modeFlags,
6739                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6740
6741        synchronized (this) {
6742            final int callingUid = Binder.getCallingUid();
6743            boolean persistChanged = false;
6744
6745            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6746            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6747
6748            final boolean exactValid = (exactPerm != null)
6749                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6750            final boolean prefixValid = (prefixPerm != null)
6751                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6752
6753            if (!(exactValid || prefixValid)) {
6754                throw new SecurityException("No persistable permission grants found for UID "
6755                        + callingUid + " and Uri " + uri.toSafeString());
6756            }
6757
6758            if (exactValid) {
6759                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6760            }
6761            if (prefixValid) {
6762                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6763            }
6764
6765            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6766
6767            if (persistChanged) {
6768                schedulePersistUriGrants();
6769            }
6770        }
6771    }
6772
6773    @Override
6774    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6775        enforceNotIsolatedCaller("releasePersistableUriPermission");
6776
6777        Preconditions.checkFlagsArgument(modeFlags,
6778                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6779
6780        synchronized (this) {
6781            final int callingUid = Binder.getCallingUid();
6782            boolean persistChanged = false;
6783
6784            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6785            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6786            if (exactPerm == null && prefixPerm == null) {
6787                throw new SecurityException("No permission grants found for UID " + callingUid
6788                        + " and Uri " + uri.toSafeString());
6789            }
6790
6791            if (exactPerm != null) {
6792                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6793                removeUriPermissionIfNeededLocked(exactPerm);
6794            }
6795            if (prefixPerm != null) {
6796                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6797                removeUriPermissionIfNeededLocked(prefixPerm);
6798            }
6799
6800            if (persistChanged) {
6801                schedulePersistUriGrants();
6802            }
6803        }
6804    }
6805
6806    /**
6807     * Prune any older {@link UriPermission} for the given UID until outstanding
6808     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6809     *
6810     * @return if any mutations occured that require persisting.
6811     */
6812    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6813        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6814        if (perms == null) return false;
6815        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6816
6817        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6818        for (UriPermission perm : perms.values()) {
6819            if (perm.persistedModeFlags != 0) {
6820                persisted.add(perm);
6821            }
6822        }
6823
6824        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6825        if (trimCount <= 0) return false;
6826
6827        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6828        for (int i = 0; i < trimCount; i++) {
6829            final UriPermission perm = persisted.get(i);
6830
6831            if (DEBUG_URI_PERMISSION) {
6832                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6833            }
6834
6835            perm.releasePersistableModes(~0);
6836            removeUriPermissionIfNeededLocked(perm);
6837        }
6838
6839        return true;
6840    }
6841
6842    @Override
6843    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6844            String packageName, boolean incoming) {
6845        enforceNotIsolatedCaller("getPersistedUriPermissions");
6846        Preconditions.checkNotNull(packageName, "packageName");
6847
6848        final int callingUid = Binder.getCallingUid();
6849        final IPackageManager pm = AppGlobals.getPackageManager();
6850        try {
6851            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6852            if (packageUid != callingUid) {
6853                throw new SecurityException(
6854                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6855            }
6856        } catch (RemoteException e) {
6857            throw new SecurityException("Failed to verify package name ownership");
6858        }
6859
6860        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6861        synchronized (this) {
6862            if (incoming) {
6863                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6864                        callingUid);
6865                if (perms == null) {
6866                    Slog.w(TAG, "No permission grants found for " + packageName);
6867                } else {
6868                    for (UriPermission perm : perms.values()) {
6869                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6870                            result.add(perm.buildPersistedPublicApiObject());
6871                        }
6872                    }
6873                }
6874            } else {
6875                final int size = mGrantedUriPermissions.size();
6876                for (int i = 0; i < size; i++) {
6877                    final ArrayMap<GrantUri, UriPermission> perms =
6878                            mGrantedUriPermissions.valueAt(i);
6879                    for (UriPermission perm : perms.values()) {
6880                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6881                            result.add(perm.buildPersistedPublicApiObject());
6882                        }
6883                    }
6884                }
6885            }
6886        }
6887        return new ParceledListSlice<android.content.UriPermission>(result);
6888    }
6889
6890    @Override
6891    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6892        synchronized (this) {
6893            ProcessRecord app =
6894                who != null ? getRecordForAppLocked(who) : null;
6895            if (app == null) return;
6896
6897            Message msg = Message.obtain();
6898            msg.what = WAIT_FOR_DEBUGGER_MSG;
6899            msg.obj = app;
6900            msg.arg1 = waiting ? 1 : 0;
6901            mHandler.sendMessage(msg);
6902        }
6903    }
6904
6905    @Override
6906    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6907        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6908        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6909        outInfo.availMem = Process.getFreeMemory();
6910        outInfo.totalMem = Process.getTotalMemory();
6911        outInfo.threshold = homeAppMem;
6912        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6913        outInfo.hiddenAppThreshold = cachedAppMem;
6914        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6915                ProcessList.SERVICE_ADJ);
6916        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6917                ProcessList.VISIBLE_APP_ADJ);
6918        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6919                ProcessList.FOREGROUND_APP_ADJ);
6920    }
6921
6922    // =========================================================
6923    // TASK MANAGEMENT
6924    // =========================================================
6925
6926    @Override
6927    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6928                         IThumbnailReceiver receiver) {
6929        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6930
6931        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6932        ActivityRecord topRecord = null;
6933
6934        synchronized(this) {
6935            if (localLOGV) Slog.v(
6936                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6937                + ", receiver=" + receiver);
6938
6939            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6940                    != PackageManager.PERMISSION_GRANTED) {
6941                if (receiver != null) {
6942                    // If the caller wants to wait for pending thumbnails,
6943                    // it ain't gonna get them.
6944                    try {
6945                        receiver.finished();
6946                    } catch (RemoteException ex) {
6947                    }
6948                }
6949                String msg = "Permission Denial: getTasks() from pid="
6950                        + Binder.getCallingPid()
6951                        + ", uid=" + Binder.getCallingUid()
6952                        + " requires " + android.Manifest.permission.GET_TASKS;
6953                Slog.w(TAG, msg);
6954                throw new SecurityException(msg);
6955            }
6956
6957            // TODO: Improve with MRU list from all ActivityStacks.
6958            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6959
6960            if (!pending.pendingRecords.isEmpty()) {
6961                mPendingThumbnails.add(pending);
6962            }
6963        }
6964
6965        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6966
6967        if (topRecord != null) {
6968            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6969            try {
6970                IApplicationThread topThumbnail = topRecord.app.thread;
6971                topThumbnail.requestThumbnail(topRecord.appToken);
6972            } catch (Exception e) {
6973                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6974                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6975            }
6976        }
6977
6978        if (pending.pendingRecords.isEmpty() && receiver != null) {
6979            // In this case all thumbnails were available and the client
6980            // is being asked to be told when the remaining ones come in...
6981            // which is unusually, since the top-most currently running
6982            // activity should never have a canned thumbnail!  Oh well.
6983            try {
6984                receiver.finished();
6985            } catch (RemoteException ex) {
6986            }
6987        }
6988
6989        return list;
6990    }
6991
6992    TaskRecord getMostRecentTask() {
6993        return mRecentTasks.get(0);
6994    }
6995
6996    @Override
6997    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6998            int flags, int userId) {
6999        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7000                false, true, "getRecentTasks", null);
7001
7002        synchronized (this) {
7003            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
7004                    "getRecentTasks()");
7005            final boolean detailed = checkCallingPermission(
7006                    android.Manifest.permission.GET_DETAILED_TASKS)
7007                    == PackageManager.PERMISSION_GRANTED;
7008
7009            IPackageManager pm = AppGlobals.getPackageManager();
7010
7011            final int N = mRecentTasks.size();
7012            ArrayList<ActivityManager.RecentTaskInfo> res
7013                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7014                            maxNum < N ? maxNum : N);
7015
7016            final Set<Integer> includedUsers;
7017            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7018                includedUsers = getProfileIdsLocked(userId);
7019            } else {
7020                includedUsers = new HashSet<Integer>();
7021            }
7022            includedUsers.add(Integer.valueOf(userId));
7023            for (int i=0; i<N && maxNum > 0; i++) {
7024                TaskRecord tr = mRecentTasks.get(i);
7025                // Only add calling user or related users recent tasks
7026                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7027
7028                // Return the entry if desired by the caller.  We always return
7029                // the first entry, because callers always expect this to be the
7030                // foreground app.  We may filter others if the caller has
7031                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7032                // we should exclude the entry.
7033
7034                if (i == 0
7035                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7036                        || (tr.intent == null)
7037                        || ((tr.intent.getFlags()
7038                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7039                    ActivityManager.RecentTaskInfo rti
7040                            = new ActivityManager.RecentTaskInfo();
7041                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7042                    rti.persistentId = tr.taskId;
7043                    rti.baseIntent = new Intent(
7044                            tr.intent != null ? tr.intent : tr.affinityIntent);
7045                    if (!detailed) {
7046                        rti.baseIntent.replaceExtras((Bundle)null);
7047                    }
7048                    rti.origActivity = tr.origActivity;
7049                    rti.description = tr.lastDescription;
7050                    rti.stackId = tr.stack.mStackId;
7051                    rti.userId = tr.userId;
7052
7053                    // Traverse upwards looking for any break between main task activities and
7054                    // utility activities.
7055                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7056                    int activityNdx;
7057                    final int numActivities = activities.size();
7058                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7059                            ++activityNdx) {
7060                        final ActivityRecord r = activities.get(activityNdx);
7061                        if (r.intent != null &&
7062                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7063                                        != 0) {
7064                            break;
7065                        }
7066                    }
7067                    // Traverse downwards starting below break looking for set label and icon.
7068                    for (--activityNdx; activityNdx >= 0; --activityNdx) {
7069                        final ActivityRecord r = activities.get(activityNdx);
7070                        if (r.activityLabel != null || r.activityIcon != null) {
7071                            rti.activityLabel = r.activityLabel;
7072                            rti.activityIcon = r.activityIcon;
7073                            break;
7074                        }
7075                    }
7076
7077                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7078                        // Check whether this activity is currently available.
7079                        try {
7080                            if (rti.origActivity != null) {
7081                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7082                                        == null) {
7083                                    continue;
7084                                }
7085                            } else if (rti.baseIntent != null) {
7086                                if (pm.queryIntentActivities(rti.baseIntent,
7087                                        null, 0, userId) == null) {
7088                                    continue;
7089                                }
7090                            }
7091                        } catch (RemoteException e) {
7092                            // Will never happen.
7093                        }
7094                    }
7095
7096                    res.add(rti);
7097                    maxNum--;
7098                }
7099            }
7100            return res;
7101        }
7102    }
7103
7104    private TaskRecord recentTaskForIdLocked(int id) {
7105        final int N = mRecentTasks.size();
7106            for (int i=0; i<N; i++) {
7107                TaskRecord tr = mRecentTasks.get(i);
7108                if (tr.taskId == id) {
7109                    return tr;
7110                }
7111            }
7112            return null;
7113    }
7114
7115    @Override
7116    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7117        synchronized (this) {
7118            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7119                    "getTaskThumbnails()");
7120            TaskRecord tr = recentTaskForIdLocked(id);
7121            if (tr != null) {
7122                return tr.getTaskThumbnailsLocked();
7123            }
7124        }
7125        return null;
7126    }
7127
7128    @Override
7129    public Bitmap getTaskTopThumbnail(int id) {
7130        synchronized (this) {
7131            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7132                    "getTaskTopThumbnail()");
7133            TaskRecord tr = recentTaskForIdLocked(id);
7134            if (tr != null) {
7135                return tr.getTaskTopThumbnailLocked();
7136            }
7137        }
7138        return null;
7139    }
7140
7141    @Override
7142    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel,
7143            Bitmap activityIcon) {
7144        synchronized (this) {
7145            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7146            if (r != null) {
7147                r.activityLabel = activityLabel.toString();
7148                r.activityIcon = activityIcon;
7149            }
7150        }
7151    }
7152
7153    @Override
7154    public boolean removeSubTask(int taskId, int subTaskIndex) {
7155        synchronized (this) {
7156            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7157                    "removeSubTask()");
7158            long ident = Binder.clearCallingIdentity();
7159            try {
7160                TaskRecord tr = recentTaskForIdLocked(taskId);
7161                if (tr != null) {
7162                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7163                }
7164                return false;
7165            } finally {
7166                Binder.restoreCallingIdentity(ident);
7167            }
7168        }
7169    }
7170
7171    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7172        if (!pr.killedByAm) {
7173            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7174            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7175                    pr.processName, pr.setAdj, reason);
7176            pr.killedByAm = true;
7177            Process.killProcessQuiet(pr.pid);
7178        }
7179    }
7180
7181    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7182        tr.disposeThumbnail();
7183        mRecentTasks.remove(tr);
7184        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7185        Intent baseIntent = new Intent(
7186                tr.intent != null ? tr.intent : tr.affinityIntent);
7187        ComponentName component = baseIntent.getComponent();
7188        if (component == null) {
7189            Slog.w(TAG, "Now component for base intent of task: " + tr);
7190            return;
7191        }
7192
7193        // Find any running services associated with this app.
7194        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7195
7196        if (killProcesses) {
7197            // Find any running processes associated with this app.
7198            final String pkg = component.getPackageName();
7199            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7200            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7201            for (int i=0; i<pmap.size(); i++) {
7202                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7203                for (int j=0; j<uids.size(); j++) {
7204                    ProcessRecord proc = uids.valueAt(j);
7205                    if (proc.userId != tr.userId) {
7206                        continue;
7207                    }
7208                    if (!proc.pkgList.containsKey(pkg)) {
7209                        continue;
7210                    }
7211                    procs.add(proc);
7212                }
7213            }
7214
7215            // Kill the running processes.
7216            for (int i=0; i<procs.size(); i++) {
7217                ProcessRecord pr = procs.get(i);
7218                if (pr == mHomeProcess) {
7219                    // Don't kill the home process along with tasks from the same package.
7220                    continue;
7221                }
7222                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7223                    killUnneededProcessLocked(pr, "remove task");
7224                } else {
7225                    pr.waitingToKill = "remove task";
7226                }
7227            }
7228        }
7229    }
7230
7231    /**
7232     * Removes the task with the specified task id.
7233     *
7234     * @param taskId Identifier of the task to be removed.
7235     * @param flags Additional operational flags.  May be 0 or
7236     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7237     * @return Returns true if the given task was found and removed.
7238     */
7239    private boolean removeTaskByIdLocked(int taskId, int flags) {
7240        TaskRecord tr = recentTaskForIdLocked(taskId);
7241        if (tr != null) {
7242            tr.removeTaskActivitiesLocked(-1, false);
7243            cleanUpRemovedTaskLocked(tr, flags);
7244            return true;
7245        }
7246        return false;
7247    }
7248
7249    @Override
7250    public boolean removeTask(int taskId, int flags) {
7251        synchronized (this) {
7252            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7253                    "removeTask()");
7254            long ident = Binder.clearCallingIdentity();
7255            try {
7256                return removeTaskByIdLocked(taskId, flags);
7257            } finally {
7258                Binder.restoreCallingIdentity(ident);
7259            }
7260        }
7261    }
7262
7263    /**
7264     * TODO: Add mController hook
7265     */
7266    @Override
7267    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7268        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7269                "moveTaskToFront()");
7270
7271        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7272        synchronized(this) {
7273            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7274                    Binder.getCallingUid(), "Task to front")) {
7275                ActivityOptions.abort(options);
7276                return;
7277            }
7278            final long origId = Binder.clearCallingIdentity();
7279            try {
7280                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7281                if (task == null) {
7282                    return;
7283                }
7284                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7285                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7286                    return;
7287                }
7288                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7289            } finally {
7290                Binder.restoreCallingIdentity(origId);
7291            }
7292            ActivityOptions.abort(options);
7293        }
7294    }
7295
7296    @Override
7297    public void moveTaskToBack(int taskId) {
7298        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7299                "moveTaskToBack()");
7300
7301        synchronized(this) {
7302            TaskRecord tr = recentTaskForIdLocked(taskId);
7303            if (tr != null) {
7304                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7305                ActivityStack stack = tr.stack;
7306                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7307                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7308                            Binder.getCallingUid(), "Task to back")) {
7309                        return;
7310                    }
7311                }
7312                final long origId = Binder.clearCallingIdentity();
7313                try {
7314                    stack.moveTaskToBackLocked(taskId, null);
7315                } finally {
7316                    Binder.restoreCallingIdentity(origId);
7317                }
7318            }
7319        }
7320    }
7321
7322    /**
7323     * Moves an activity, and all of the other activities within the same task, to the bottom
7324     * of the history stack.  The activity's order within the task is unchanged.
7325     *
7326     * @param token A reference to the activity we wish to move
7327     * @param nonRoot If false then this only works if the activity is the root
7328     *                of a task; if true it will work for any activity in a task.
7329     * @return Returns true if the move completed, false if not.
7330     */
7331    @Override
7332    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7333        enforceNotIsolatedCaller("moveActivityTaskToBack");
7334        synchronized(this) {
7335            final long origId = Binder.clearCallingIdentity();
7336            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7337            if (taskId >= 0) {
7338                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7339            }
7340            Binder.restoreCallingIdentity(origId);
7341        }
7342        return false;
7343    }
7344
7345    @Override
7346    public void moveTaskBackwards(int task) {
7347        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7348                "moveTaskBackwards()");
7349
7350        synchronized(this) {
7351            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7352                    Binder.getCallingUid(), "Task backwards")) {
7353                return;
7354            }
7355            final long origId = Binder.clearCallingIdentity();
7356            moveTaskBackwardsLocked(task);
7357            Binder.restoreCallingIdentity(origId);
7358        }
7359    }
7360
7361    private final void moveTaskBackwardsLocked(int task) {
7362        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7363    }
7364
7365    @Override
7366    public IBinder getHomeActivityToken() throws RemoteException {
7367        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7368                "getHomeActivityToken()");
7369        synchronized (this) {
7370            return mStackSupervisor.getHomeActivityToken();
7371        }
7372    }
7373
7374    @Override
7375    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7376            IActivityContainerCallback callback) throws RemoteException {
7377        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7378                "createActivityContainer()");
7379        synchronized (this) {
7380            if (parentActivityToken == null) {
7381                throw new IllegalArgumentException("parent token must not be null");
7382            }
7383            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7384            if (r == null) {
7385                return null;
7386            }
7387            if (callback == null) {
7388                throw new IllegalArgumentException("callback must not be null");
7389            }
7390            return mStackSupervisor.createActivityContainer(r, callback);
7391        }
7392    }
7393
7394    @Override
7395    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7396        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7397                "deleteActivityContainer()");
7398        synchronized (this) {
7399            mStackSupervisor.deleteActivityContainer(container);
7400        }
7401    }
7402
7403    @Override
7404    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7405            throws RemoteException {
7406        synchronized (this) {
7407            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7408            if (stack != null) {
7409                return stack.mActivityContainer;
7410            }
7411            return null;
7412        }
7413    }
7414
7415    @Override
7416    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7417        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7418                "moveTaskToStack()");
7419        if (stackId == HOME_STACK_ID) {
7420            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7421                    new RuntimeException("here").fillInStackTrace());
7422        }
7423        synchronized (this) {
7424            long ident = Binder.clearCallingIdentity();
7425            try {
7426                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7427                        + stackId + " toTop=" + toTop);
7428                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7429            } finally {
7430                Binder.restoreCallingIdentity(ident);
7431            }
7432        }
7433    }
7434
7435    @Override
7436    public void resizeStack(int stackBoxId, Rect bounds) {
7437        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7438                "resizeStackBox()");
7439        long ident = Binder.clearCallingIdentity();
7440        try {
7441            mWindowManager.resizeStack(stackBoxId, bounds);
7442        } finally {
7443            Binder.restoreCallingIdentity(ident);
7444        }
7445    }
7446
7447    @Override
7448    public List<StackInfo> getAllStackInfos() {
7449        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7450                "getAllStackInfos()");
7451        long ident = Binder.clearCallingIdentity();
7452        try {
7453            synchronized (this) {
7454                return mStackSupervisor.getAllStackInfosLocked();
7455            }
7456        } finally {
7457            Binder.restoreCallingIdentity(ident);
7458        }
7459    }
7460
7461    @Override
7462    public StackInfo getStackInfo(int stackId) {
7463        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7464                "getStackInfo()");
7465        long ident = Binder.clearCallingIdentity();
7466        try {
7467            synchronized (this) {
7468                return mStackSupervisor.getStackInfoLocked(stackId);
7469            }
7470        } finally {
7471            Binder.restoreCallingIdentity(ident);
7472        }
7473    }
7474
7475    @Override
7476    public boolean isInHomeStack(int taskId) {
7477        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7478                "getStackInfo()");
7479        long ident = Binder.clearCallingIdentity();
7480        try {
7481            synchronized (this) {
7482                TaskRecord tr = recentTaskForIdLocked(taskId);
7483                if (tr != null) {
7484                    return tr.stack.isHomeStack();
7485                }
7486            }
7487        } finally {
7488            Binder.restoreCallingIdentity(ident);
7489        }
7490        return false;
7491    }
7492
7493    @Override
7494    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7495        synchronized(this) {
7496            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7497        }
7498    }
7499
7500    private boolean isLockTaskAuthorized(ComponentName name) {
7501//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7502//                "startLockTaskMode()");
7503//        DevicePolicyManager dpm = (DevicePolicyManager)
7504//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7505//        return dpm != null && dpm.isLockTaskPermitted(name);
7506        return true;
7507    }
7508
7509    private void startLockTaskMode(TaskRecord task) {
7510        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7511            return;
7512        }
7513        long ident = Binder.clearCallingIdentity();
7514        try {
7515            synchronized (this) {
7516                // Since we lost lock on task, make sure it is still there.
7517                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7518                if (task != null) {
7519                    mStackSupervisor.setLockTaskModeLocked(task);
7520                }
7521            }
7522        } finally {
7523            Binder.restoreCallingIdentity(ident);
7524        }
7525    }
7526
7527    @Override
7528    public void startLockTaskMode(int taskId) {
7529        long ident = Binder.clearCallingIdentity();
7530        try {
7531            final TaskRecord task;
7532            synchronized (this) {
7533                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7534            }
7535            if (task != null) {
7536                startLockTaskMode(task);
7537            }
7538        } finally {
7539            Binder.restoreCallingIdentity(ident);
7540        }
7541    }
7542
7543    @Override
7544    public void startLockTaskMode(IBinder token) {
7545        long ident = Binder.clearCallingIdentity();
7546        try {
7547            final TaskRecord task;
7548            synchronized (this) {
7549                final ActivityRecord r = ActivityRecord.forToken(token);
7550                if (r == null) {
7551                    return;
7552                }
7553                task = r.task;
7554            }
7555            if (task != null) {
7556                startLockTaskMode(task);
7557            }
7558        } finally {
7559            Binder.restoreCallingIdentity(ident);
7560        }
7561    }
7562
7563    @Override
7564    public void stopLockTaskMode() {
7565//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7566//                "stopLockTaskMode()");
7567        synchronized (this) {
7568            mStackSupervisor.setLockTaskModeLocked(null);
7569        }
7570    }
7571
7572    @Override
7573    public boolean isInLockTaskMode() {
7574        synchronized (this) {
7575            return mStackSupervisor.isInLockTaskMode();
7576        }
7577    }
7578
7579    // =========================================================
7580    // THUMBNAILS
7581    // =========================================================
7582
7583    public void reportThumbnail(IBinder token,
7584            Bitmap thumbnail, CharSequence description) {
7585        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7586        final long origId = Binder.clearCallingIdentity();
7587        sendPendingThumbnail(null, token, thumbnail, description, true);
7588        Binder.restoreCallingIdentity(origId);
7589    }
7590
7591    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7592            Bitmap thumbnail, CharSequence description, boolean always) {
7593        TaskRecord task;
7594        ArrayList<PendingThumbnailsRecord> receivers = null;
7595
7596        //System.out.println("Send pending thumbnail: " + r);
7597
7598        synchronized(this) {
7599            if (r == null) {
7600                r = ActivityRecord.isInStackLocked(token);
7601                if (r == null) {
7602                    return;
7603                }
7604            }
7605            if (thumbnail == null && r.thumbHolder != null) {
7606                thumbnail = r.thumbHolder.lastThumbnail;
7607                description = r.thumbHolder.lastDescription;
7608            }
7609            if (thumbnail == null && !always) {
7610                // If there is no thumbnail, and this entry is not actually
7611                // going away, then abort for now and pick up the next
7612                // thumbnail we get.
7613                return;
7614            }
7615            task = r.task;
7616
7617            int N = mPendingThumbnails.size();
7618            int i=0;
7619            while (i<N) {
7620                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7621                //System.out.println("Looking in " + pr.pendingRecords);
7622                if (pr.pendingRecords.remove(r)) {
7623                    if (receivers == null) {
7624                        receivers = new ArrayList<PendingThumbnailsRecord>();
7625                    }
7626                    receivers.add(pr);
7627                    if (pr.pendingRecords.size() == 0) {
7628                        pr.finished = true;
7629                        mPendingThumbnails.remove(i);
7630                        N--;
7631                        continue;
7632                    }
7633                }
7634                i++;
7635            }
7636        }
7637
7638        if (receivers != null) {
7639            final int N = receivers.size();
7640            for (int i=0; i<N; i++) {
7641                try {
7642                    PendingThumbnailsRecord pr = receivers.get(i);
7643                    pr.receiver.newThumbnail(
7644                        task != null ? task.taskId : -1, thumbnail, description);
7645                    if (pr.finished) {
7646                        pr.receiver.finished();
7647                    }
7648                } catch (Exception e) {
7649                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7650                }
7651            }
7652        }
7653    }
7654
7655    // =========================================================
7656    // CONTENT PROVIDERS
7657    // =========================================================
7658
7659    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7660        List<ProviderInfo> providers = null;
7661        try {
7662            providers = AppGlobals.getPackageManager().
7663                queryContentProviders(app.processName, app.uid,
7664                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7665        } catch (RemoteException ex) {
7666        }
7667        if (DEBUG_MU)
7668            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7669        int userId = app.userId;
7670        if (providers != null) {
7671            int N = providers.size();
7672            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7673            for (int i=0; i<N; i++) {
7674                ProviderInfo cpi =
7675                    (ProviderInfo)providers.get(i);
7676                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7677                        cpi.name, cpi.flags);
7678                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7679                    // This is a singleton provider, but a user besides the
7680                    // default user is asking to initialize a process it runs
7681                    // in...  well, no, it doesn't actually run in this process,
7682                    // it runs in the process of the default user.  Get rid of it.
7683                    providers.remove(i);
7684                    N--;
7685                    i--;
7686                    continue;
7687                }
7688
7689                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7690                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7691                if (cpr == null) {
7692                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7693                    mProviderMap.putProviderByClass(comp, cpr);
7694                }
7695                if (DEBUG_MU)
7696                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7697                app.pubProviders.put(cpi.name, cpr);
7698                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7699                    // Don't add this if it is a platform component that is marked
7700                    // to run in multiple processes, because this is actually
7701                    // part of the framework so doesn't make sense to track as a
7702                    // separate apk in the process.
7703                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7704                }
7705                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7706            }
7707        }
7708        return providers;
7709    }
7710
7711    /**
7712     * Check if {@link ProcessRecord} has a possible chance at accessing the
7713     * given {@link ProviderInfo}. Final permission checking is always done
7714     * in {@link ContentProvider}.
7715     */
7716    private final String checkContentProviderPermissionLocked(
7717            ProviderInfo cpi, ProcessRecord r) {
7718        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7719        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7720        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7721                cpi.applicationInfo.uid, cpi.exported)
7722                == PackageManager.PERMISSION_GRANTED) {
7723            return null;
7724        }
7725        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7726                cpi.applicationInfo.uid, cpi.exported)
7727                == PackageManager.PERMISSION_GRANTED) {
7728            return null;
7729        }
7730
7731        PathPermission[] pps = cpi.pathPermissions;
7732        if (pps != null) {
7733            int i = pps.length;
7734            while (i > 0) {
7735                i--;
7736                PathPermission pp = pps[i];
7737                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7738                        cpi.applicationInfo.uid, cpi.exported)
7739                        == PackageManager.PERMISSION_GRANTED) {
7740                    return null;
7741                }
7742                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7743                        cpi.applicationInfo.uid, cpi.exported)
7744                        == PackageManager.PERMISSION_GRANTED) {
7745                    return null;
7746                }
7747            }
7748        }
7749
7750        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7751        if (perms != null) {
7752            for (GrantUri uri : perms.keySet()) {
7753                if (uri.uri.getAuthority().equals(cpi.authority)) {
7754                    return null;
7755                }
7756            }
7757        }
7758
7759        String msg;
7760        if (!cpi.exported) {
7761            msg = "Permission Denial: opening provider " + cpi.name
7762                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7763                    + ", uid=" + callingUid + ") that is not exported from uid "
7764                    + cpi.applicationInfo.uid;
7765        } else {
7766            msg = "Permission Denial: opening provider " + cpi.name
7767                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7768                    + ", uid=" + callingUid + ") requires "
7769                    + cpi.readPermission + " or " + cpi.writePermission;
7770        }
7771        Slog.w(TAG, msg);
7772        return msg;
7773    }
7774
7775    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7776            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7777        if (r != null) {
7778            for (int i=0; i<r.conProviders.size(); i++) {
7779                ContentProviderConnection conn = r.conProviders.get(i);
7780                if (conn.provider == cpr) {
7781                    if (DEBUG_PROVIDER) Slog.v(TAG,
7782                            "Adding provider requested by "
7783                            + r.processName + " from process "
7784                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7785                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7786                    if (stable) {
7787                        conn.stableCount++;
7788                        conn.numStableIncs++;
7789                    } else {
7790                        conn.unstableCount++;
7791                        conn.numUnstableIncs++;
7792                    }
7793                    return conn;
7794                }
7795            }
7796            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7797            if (stable) {
7798                conn.stableCount = 1;
7799                conn.numStableIncs = 1;
7800            } else {
7801                conn.unstableCount = 1;
7802                conn.numUnstableIncs = 1;
7803            }
7804            cpr.connections.add(conn);
7805            r.conProviders.add(conn);
7806            return conn;
7807        }
7808        cpr.addExternalProcessHandleLocked(externalProcessToken);
7809        return null;
7810    }
7811
7812    boolean decProviderCountLocked(ContentProviderConnection conn,
7813            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7814        if (conn != null) {
7815            cpr = conn.provider;
7816            if (DEBUG_PROVIDER) Slog.v(TAG,
7817                    "Removing provider requested by "
7818                    + conn.client.processName + " from process "
7819                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7820                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7821            if (stable) {
7822                conn.stableCount--;
7823            } else {
7824                conn.unstableCount--;
7825            }
7826            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7827                cpr.connections.remove(conn);
7828                conn.client.conProviders.remove(conn);
7829                return true;
7830            }
7831            return false;
7832        }
7833        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7834        return false;
7835    }
7836
7837    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7838            String name, IBinder token, boolean stable, int userId) {
7839        ContentProviderRecord cpr;
7840        ContentProviderConnection conn = null;
7841        ProviderInfo cpi = null;
7842
7843        synchronized(this) {
7844            ProcessRecord r = null;
7845            if (caller != null) {
7846                r = getRecordForAppLocked(caller);
7847                if (r == null) {
7848                    throw new SecurityException(
7849                            "Unable to find app for caller " + caller
7850                          + " (pid=" + Binder.getCallingPid()
7851                          + ") when getting content provider " + name);
7852                }
7853            }
7854
7855            // First check if this content provider has been published...
7856            cpr = mProviderMap.getProviderByName(name, userId);
7857            boolean providerRunning = cpr != null;
7858            if (providerRunning) {
7859                cpi = cpr.info;
7860                String msg;
7861                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7862                    throw new SecurityException(msg);
7863                }
7864
7865                if (r != null && cpr.canRunHere(r)) {
7866                    // This provider has been published or is in the process
7867                    // of being published...  but it is also allowed to run
7868                    // in the caller's process, so don't make a connection
7869                    // and just let the caller instantiate its own instance.
7870                    ContentProviderHolder holder = cpr.newHolder(null);
7871                    // don't give caller the provider object, it needs
7872                    // to make its own.
7873                    holder.provider = null;
7874                    return holder;
7875                }
7876
7877                final long origId = Binder.clearCallingIdentity();
7878
7879                // In this case the provider instance already exists, so we can
7880                // return it right away.
7881                conn = incProviderCountLocked(r, cpr, token, stable);
7882                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7883                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7884                        // If this is a perceptible app accessing the provider,
7885                        // make sure to count it as being accessed and thus
7886                        // back up on the LRU list.  This is good because
7887                        // content providers are often expensive to start.
7888                        updateLruProcessLocked(cpr.proc, false, null);
7889                    }
7890                }
7891
7892                if (cpr.proc != null) {
7893                    if (false) {
7894                        if (cpr.name.flattenToShortString().equals(
7895                                "com.android.providers.calendar/.CalendarProvider2")) {
7896                            Slog.v(TAG, "****************** KILLING "
7897                                + cpr.name.flattenToShortString());
7898                            Process.killProcess(cpr.proc.pid);
7899                        }
7900                    }
7901                    boolean success = updateOomAdjLocked(cpr.proc);
7902                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7903                    // NOTE: there is still a race here where a signal could be
7904                    // pending on the process even though we managed to update its
7905                    // adj level.  Not sure what to do about this, but at least
7906                    // the race is now smaller.
7907                    if (!success) {
7908                        // Uh oh...  it looks like the provider's process
7909                        // has been killed on us.  We need to wait for a new
7910                        // process to be started, and make sure its death
7911                        // doesn't kill our process.
7912                        Slog.i(TAG,
7913                                "Existing provider " + cpr.name.flattenToShortString()
7914                                + " is crashing; detaching " + r);
7915                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7916                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7917                        if (!lastRef) {
7918                            // This wasn't the last ref our process had on
7919                            // the provider...  we have now been killed, bail.
7920                            return null;
7921                        }
7922                        providerRunning = false;
7923                        conn = null;
7924                    }
7925                }
7926
7927                Binder.restoreCallingIdentity(origId);
7928            }
7929
7930            boolean singleton;
7931            if (!providerRunning) {
7932                try {
7933                    cpi = AppGlobals.getPackageManager().
7934                        resolveContentProvider(name,
7935                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7936                } catch (RemoteException ex) {
7937                }
7938                if (cpi == null) {
7939                    return null;
7940                }
7941                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7942                        cpi.name, cpi.flags);
7943                if (singleton) {
7944                    userId = 0;
7945                }
7946                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7947
7948                String msg;
7949                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7950                    throw new SecurityException(msg);
7951                }
7952
7953                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7954                        && !cpi.processName.equals("system")) {
7955                    // If this content provider does not run in the system
7956                    // process, and the system is not yet ready to run other
7957                    // processes, then fail fast instead of hanging.
7958                    throw new IllegalArgumentException(
7959                            "Attempt to launch content provider before system ready");
7960                }
7961
7962                // Make sure that the user who owns this provider is started.  If not,
7963                // we don't want to allow it to run.
7964                if (mStartedUsers.get(userId) == null) {
7965                    Slog.w(TAG, "Unable to launch app "
7966                            + cpi.applicationInfo.packageName + "/"
7967                            + cpi.applicationInfo.uid + " for provider "
7968                            + name + ": user " + userId + " is stopped");
7969                    return null;
7970                }
7971
7972                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7973                cpr = mProviderMap.getProviderByClass(comp, userId);
7974                final boolean firstClass = cpr == null;
7975                if (firstClass) {
7976                    try {
7977                        ApplicationInfo ai =
7978                            AppGlobals.getPackageManager().
7979                                getApplicationInfo(
7980                                        cpi.applicationInfo.packageName,
7981                                        STOCK_PM_FLAGS, userId);
7982                        if (ai == null) {
7983                            Slog.w(TAG, "No package info for content provider "
7984                                    + cpi.name);
7985                            return null;
7986                        }
7987                        ai = getAppInfoForUser(ai, userId);
7988                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7989                    } catch (RemoteException ex) {
7990                        // pm is in same process, this will never happen.
7991                    }
7992                }
7993
7994                if (r != null && cpr.canRunHere(r)) {
7995                    // If this is a multiprocess provider, then just return its
7996                    // info and allow the caller to instantiate it.  Only do
7997                    // this if the provider is the same user as the caller's
7998                    // process, or can run as root (so can be in any process).
7999                    return cpr.newHolder(null);
8000                }
8001
8002                if (DEBUG_PROVIDER) {
8003                    RuntimeException e = new RuntimeException("here");
8004                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8005                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8006                }
8007
8008                // This is single process, and our app is now connecting to it.
8009                // See if we are already in the process of launching this
8010                // provider.
8011                final int N = mLaunchingProviders.size();
8012                int i;
8013                for (i=0; i<N; i++) {
8014                    if (mLaunchingProviders.get(i) == cpr) {
8015                        break;
8016                    }
8017                }
8018
8019                // If the provider is not already being launched, then get it
8020                // started.
8021                if (i >= N) {
8022                    final long origId = Binder.clearCallingIdentity();
8023
8024                    try {
8025                        // Content provider is now in use, its package can't be stopped.
8026                        try {
8027                            AppGlobals.getPackageManager().setPackageStoppedState(
8028                                    cpr.appInfo.packageName, false, userId);
8029                        } catch (RemoteException e) {
8030                        } catch (IllegalArgumentException e) {
8031                            Slog.w(TAG, "Failed trying to unstop package "
8032                                    + cpr.appInfo.packageName + ": " + e);
8033                        }
8034
8035                        // Use existing process if already started
8036                        ProcessRecord proc = getProcessRecordLocked(
8037                                cpi.processName, cpr.appInfo.uid, false);
8038                        if (proc != null && proc.thread != null) {
8039                            if (DEBUG_PROVIDER) {
8040                                Slog.d(TAG, "Installing in existing process " + proc);
8041                            }
8042                            proc.pubProviders.put(cpi.name, cpr);
8043                            try {
8044                                proc.thread.scheduleInstallProvider(cpi);
8045                            } catch (RemoteException e) {
8046                            }
8047                        } else {
8048                            proc = startProcessLocked(cpi.processName,
8049                                    cpr.appInfo, false, 0, "content provider",
8050                                    new ComponentName(cpi.applicationInfo.packageName,
8051                                            cpi.name), false, false, false);
8052                            if (proc == null) {
8053                                Slog.w(TAG, "Unable to launch app "
8054                                        + cpi.applicationInfo.packageName + "/"
8055                                        + cpi.applicationInfo.uid + " for provider "
8056                                        + name + ": process is bad");
8057                                return null;
8058                            }
8059                        }
8060                        cpr.launchingApp = proc;
8061                        mLaunchingProviders.add(cpr);
8062                    } finally {
8063                        Binder.restoreCallingIdentity(origId);
8064                    }
8065                }
8066
8067                // Make sure the provider is published (the same provider class
8068                // may be published under multiple names).
8069                if (firstClass) {
8070                    mProviderMap.putProviderByClass(comp, cpr);
8071                }
8072
8073                mProviderMap.putProviderByName(name, cpr);
8074                conn = incProviderCountLocked(r, cpr, token, stable);
8075                if (conn != null) {
8076                    conn.waiting = true;
8077                }
8078            }
8079        }
8080
8081        // Wait for the provider to be published...
8082        synchronized (cpr) {
8083            while (cpr.provider == null) {
8084                if (cpr.launchingApp == null) {
8085                    Slog.w(TAG, "Unable to launch app "
8086                            + cpi.applicationInfo.packageName + "/"
8087                            + cpi.applicationInfo.uid + " for provider "
8088                            + name + ": launching app became null");
8089                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8090                            UserHandle.getUserId(cpi.applicationInfo.uid),
8091                            cpi.applicationInfo.packageName,
8092                            cpi.applicationInfo.uid, name);
8093                    return null;
8094                }
8095                try {
8096                    if (DEBUG_MU) {
8097                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8098                                + cpr.launchingApp);
8099                    }
8100                    if (conn != null) {
8101                        conn.waiting = true;
8102                    }
8103                    cpr.wait();
8104                } catch (InterruptedException ex) {
8105                } finally {
8106                    if (conn != null) {
8107                        conn.waiting = false;
8108                    }
8109                }
8110            }
8111        }
8112        return cpr != null ? cpr.newHolder(conn) : null;
8113    }
8114
8115    public final ContentProviderHolder getContentProvider(
8116            IApplicationThread caller, String name, int userId, boolean stable) {
8117        enforceNotIsolatedCaller("getContentProvider");
8118        if (caller == null) {
8119            String msg = "null IApplicationThread when getting content provider "
8120                    + name;
8121            Slog.w(TAG, msg);
8122            throw new SecurityException(msg);
8123        }
8124
8125        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8126                false, true, "getContentProvider", null);
8127        return getContentProviderImpl(caller, name, null, stable, userId);
8128    }
8129
8130    public ContentProviderHolder getContentProviderExternal(
8131            String name, int userId, IBinder token) {
8132        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8133            "Do not have permission in call getContentProviderExternal()");
8134        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8135                false, true, "getContentProvider", null);
8136        return getContentProviderExternalUnchecked(name, token, userId);
8137    }
8138
8139    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8140            IBinder token, int userId) {
8141        return getContentProviderImpl(null, name, token, true, userId);
8142    }
8143
8144    /**
8145     * Drop a content provider from a ProcessRecord's bookkeeping
8146     */
8147    public void removeContentProvider(IBinder connection, boolean stable) {
8148        enforceNotIsolatedCaller("removeContentProvider");
8149        long ident = Binder.clearCallingIdentity();
8150        try {
8151            synchronized (this) {
8152                ContentProviderConnection conn;
8153                try {
8154                    conn = (ContentProviderConnection)connection;
8155                } catch (ClassCastException e) {
8156                    String msg ="removeContentProvider: " + connection
8157                            + " not a ContentProviderConnection";
8158                    Slog.w(TAG, msg);
8159                    throw new IllegalArgumentException(msg);
8160                }
8161                if (conn == null) {
8162                    throw new NullPointerException("connection is null");
8163                }
8164                if (decProviderCountLocked(conn, null, null, stable)) {
8165                    updateOomAdjLocked();
8166                }
8167            }
8168        } finally {
8169            Binder.restoreCallingIdentity(ident);
8170        }
8171    }
8172
8173    public void removeContentProviderExternal(String name, IBinder token) {
8174        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8175            "Do not have permission in call removeContentProviderExternal()");
8176        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8177    }
8178
8179    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8180        synchronized (this) {
8181            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8182            if(cpr == null) {
8183                //remove from mProvidersByClass
8184                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8185                return;
8186            }
8187
8188            //update content provider record entry info
8189            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8190            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8191            if (localCpr.hasExternalProcessHandles()) {
8192                if (localCpr.removeExternalProcessHandleLocked(token)) {
8193                    updateOomAdjLocked();
8194                } else {
8195                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8196                            + " with no external reference for token: "
8197                            + token + ".");
8198                }
8199            } else {
8200                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8201                        + " with no external references.");
8202            }
8203        }
8204    }
8205
8206    public final void publishContentProviders(IApplicationThread caller,
8207            List<ContentProviderHolder> providers) {
8208        if (providers == null) {
8209            return;
8210        }
8211
8212        enforceNotIsolatedCaller("publishContentProviders");
8213        synchronized (this) {
8214            final ProcessRecord r = getRecordForAppLocked(caller);
8215            if (DEBUG_MU)
8216                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8217            if (r == null) {
8218                throw new SecurityException(
8219                        "Unable to find app for caller " + caller
8220                      + " (pid=" + Binder.getCallingPid()
8221                      + ") when publishing content providers");
8222            }
8223
8224            final long origId = Binder.clearCallingIdentity();
8225
8226            final int N = providers.size();
8227            for (int i=0; i<N; i++) {
8228                ContentProviderHolder src = providers.get(i);
8229                if (src == null || src.info == null || src.provider == null) {
8230                    continue;
8231                }
8232                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8233                if (DEBUG_MU)
8234                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8235                if (dst != null) {
8236                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8237                    mProviderMap.putProviderByClass(comp, dst);
8238                    String names[] = dst.info.authority.split(";");
8239                    for (int j = 0; j < names.length; j++) {
8240                        mProviderMap.putProviderByName(names[j], dst);
8241                    }
8242
8243                    int NL = mLaunchingProviders.size();
8244                    int j;
8245                    for (j=0; j<NL; j++) {
8246                        if (mLaunchingProviders.get(j) == dst) {
8247                            mLaunchingProviders.remove(j);
8248                            j--;
8249                            NL--;
8250                        }
8251                    }
8252                    synchronized (dst) {
8253                        dst.provider = src.provider;
8254                        dst.proc = r;
8255                        dst.notifyAll();
8256                    }
8257                    updateOomAdjLocked(r);
8258                }
8259            }
8260
8261            Binder.restoreCallingIdentity(origId);
8262        }
8263    }
8264
8265    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8266        ContentProviderConnection conn;
8267        try {
8268            conn = (ContentProviderConnection)connection;
8269        } catch (ClassCastException e) {
8270            String msg ="refContentProvider: " + connection
8271                    + " not a ContentProviderConnection";
8272            Slog.w(TAG, msg);
8273            throw new IllegalArgumentException(msg);
8274        }
8275        if (conn == null) {
8276            throw new NullPointerException("connection is null");
8277        }
8278
8279        synchronized (this) {
8280            if (stable > 0) {
8281                conn.numStableIncs += stable;
8282            }
8283            stable = conn.stableCount + stable;
8284            if (stable < 0) {
8285                throw new IllegalStateException("stableCount < 0: " + stable);
8286            }
8287
8288            if (unstable > 0) {
8289                conn.numUnstableIncs += unstable;
8290            }
8291            unstable = conn.unstableCount + unstable;
8292            if (unstable < 0) {
8293                throw new IllegalStateException("unstableCount < 0: " + unstable);
8294            }
8295
8296            if ((stable+unstable) <= 0) {
8297                throw new IllegalStateException("ref counts can't go to zero here: stable="
8298                        + stable + " unstable=" + unstable);
8299            }
8300            conn.stableCount = stable;
8301            conn.unstableCount = unstable;
8302            return !conn.dead;
8303        }
8304    }
8305
8306    public void unstableProviderDied(IBinder connection) {
8307        ContentProviderConnection conn;
8308        try {
8309            conn = (ContentProviderConnection)connection;
8310        } catch (ClassCastException e) {
8311            String msg ="refContentProvider: " + connection
8312                    + " not a ContentProviderConnection";
8313            Slog.w(TAG, msg);
8314            throw new IllegalArgumentException(msg);
8315        }
8316        if (conn == null) {
8317            throw new NullPointerException("connection is null");
8318        }
8319
8320        // Safely retrieve the content provider associated with the connection.
8321        IContentProvider provider;
8322        synchronized (this) {
8323            provider = conn.provider.provider;
8324        }
8325
8326        if (provider == null) {
8327            // Um, yeah, we're way ahead of you.
8328            return;
8329        }
8330
8331        // Make sure the caller is being honest with us.
8332        if (provider.asBinder().pingBinder()) {
8333            // Er, no, still looks good to us.
8334            synchronized (this) {
8335                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8336                        + " says " + conn + " died, but we don't agree");
8337                return;
8338            }
8339        }
8340
8341        // Well look at that!  It's dead!
8342        synchronized (this) {
8343            if (conn.provider.provider != provider) {
8344                // But something changed...  good enough.
8345                return;
8346            }
8347
8348            ProcessRecord proc = conn.provider.proc;
8349            if (proc == null || proc.thread == null) {
8350                // Seems like the process is already cleaned up.
8351                return;
8352            }
8353
8354            // As far as we're concerned, this is just like receiving a
8355            // death notification...  just a bit prematurely.
8356            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8357                    + ") early provider death");
8358            final long ident = Binder.clearCallingIdentity();
8359            try {
8360                appDiedLocked(proc, proc.pid, proc.thread);
8361            } finally {
8362                Binder.restoreCallingIdentity(ident);
8363            }
8364        }
8365    }
8366
8367    @Override
8368    public void appNotRespondingViaProvider(IBinder connection) {
8369        enforceCallingPermission(
8370                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8371
8372        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8373        if (conn == null) {
8374            Slog.w(TAG, "ContentProviderConnection is null");
8375            return;
8376        }
8377
8378        final ProcessRecord host = conn.provider.proc;
8379        if (host == null) {
8380            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8381            return;
8382        }
8383
8384        final long token = Binder.clearCallingIdentity();
8385        try {
8386            appNotResponding(host, null, null, false, "ContentProvider not responding");
8387        } finally {
8388            Binder.restoreCallingIdentity(token);
8389        }
8390    }
8391
8392    public final void installSystemProviders() {
8393        List<ProviderInfo> providers;
8394        synchronized (this) {
8395            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8396            providers = generateApplicationProvidersLocked(app);
8397            if (providers != null) {
8398                for (int i=providers.size()-1; i>=0; i--) {
8399                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8400                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8401                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8402                                + ": not system .apk");
8403                        providers.remove(i);
8404                    }
8405                }
8406            }
8407        }
8408        if (providers != null) {
8409            mSystemThread.installSystemProviders(providers);
8410        }
8411
8412        mCoreSettingsObserver = new CoreSettingsObserver(this);
8413
8414        mUsageStatsService.monitorPackages();
8415    }
8416
8417    /**
8418     * Allows app to retrieve the MIME type of a URI without having permission
8419     * to access its content provider.
8420     *
8421     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8422     *
8423     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8424     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8425     */
8426    public String getProviderMimeType(Uri uri, int userId) {
8427        enforceNotIsolatedCaller("getProviderMimeType");
8428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8429                userId, false, true, "getProviderMimeType", null);
8430        final String name = uri.getAuthority();
8431        final long ident = Binder.clearCallingIdentity();
8432        ContentProviderHolder holder = null;
8433
8434        try {
8435            holder = getContentProviderExternalUnchecked(name, null, userId);
8436            if (holder != null) {
8437                return holder.provider.getType(uri);
8438            }
8439        } catch (RemoteException e) {
8440            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8441            return null;
8442        } finally {
8443            if (holder != null) {
8444                removeContentProviderExternalUnchecked(name, null, userId);
8445            }
8446            Binder.restoreCallingIdentity(ident);
8447        }
8448
8449        return null;
8450    }
8451
8452    // =========================================================
8453    // GLOBAL MANAGEMENT
8454    // =========================================================
8455
8456    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8457            boolean isolated) {
8458        String proc = customProcess != null ? customProcess : info.processName;
8459        BatteryStatsImpl.Uid.Proc ps = null;
8460        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8461        int uid = info.uid;
8462        if (isolated) {
8463            int userId = UserHandle.getUserId(uid);
8464            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8465            while (true) {
8466                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8467                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8468                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8469                }
8470                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8471                mNextIsolatedProcessUid++;
8472                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8473                    // No process for this uid, use it.
8474                    break;
8475                }
8476                stepsLeft--;
8477                if (stepsLeft <= 0) {
8478                    return null;
8479                }
8480            }
8481        }
8482        return new ProcessRecord(stats, info, proc, uid);
8483    }
8484
8485    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8486        ProcessRecord app;
8487        if (!isolated) {
8488            app = getProcessRecordLocked(info.processName, info.uid, true);
8489        } else {
8490            app = null;
8491        }
8492
8493        if (app == null) {
8494            app = newProcessRecordLocked(info, null, isolated);
8495            mProcessNames.put(info.processName, app.uid, app);
8496            if (isolated) {
8497                mIsolatedProcesses.put(app.uid, app);
8498            }
8499            updateLruProcessLocked(app, false, null);
8500            updateOomAdjLocked();
8501        }
8502
8503        // This package really, really can not be stopped.
8504        try {
8505            AppGlobals.getPackageManager().setPackageStoppedState(
8506                    info.packageName, false, UserHandle.getUserId(app.uid));
8507        } catch (RemoteException e) {
8508        } catch (IllegalArgumentException e) {
8509            Slog.w(TAG, "Failed trying to unstop package "
8510                    + info.packageName + ": " + e);
8511        }
8512
8513        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8514                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8515            app.persistent = true;
8516            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8517        }
8518        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8519            mPersistentStartingProcesses.add(app);
8520            startProcessLocked(app, "added application", app.processName);
8521        }
8522
8523        return app;
8524    }
8525
8526    public void unhandledBack() {
8527        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8528                "unhandledBack()");
8529
8530        synchronized(this) {
8531            final long origId = Binder.clearCallingIdentity();
8532            try {
8533                getFocusedStack().unhandledBackLocked();
8534            } finally {
8535                Binder.restoreCallingIdentity(origId);
8536            }
8537        }
8538    }
8539
8540    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8541        enforceNotIsolatedCaller("openContentUri");
8542        final int userId = UserHandle.getCallingUserId();
8543        String name = uri.getAuthority();
8544        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8545        ParcelFileDescriptor pfd = null;
8546        if (cph != null) {
8547            // We record the binder invoker's uid in thread-local storage before
8548            // going to the content provider to open the file.  Later, in the code
8549            // that handles all permissions checks, we look for this uid and use
8550            // that rather than the Activity Manager's own uid.  The effect is that
8551            // we do the check against the caller's permissions even though it looks
8552            // to the content provider like the Activity Manager itself is making
8553            // the request.
8554            sCallerIdentity.set(new Identity(
8555                    Binder.getCallingPid(), Binder.getCallingUid()));
8556            try {
8557                pfd = cph.provider.openFile(null, uri, "r", null);
8558            } catch (FileNotFoundException e) {
8559                // do nothing; pfd will be returned null
8560            } finally {
8561                // Ensure that whatever happens, we clean up the identity state
8562                sCallerIdentity.remove();
8563            }
8564
8565            // We've got the fd now, so we're done with the provider.
8566            removeContentProviderExternalUnchecked(name, null, userId);
8567        } else {
8568            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8569        }
8570        return pfd;
8571    }
8572
8573    // Actually is sleeping or shutting down or whatever else in the future
8574    // is an inactive state.
8575    public boolean isSleepingOrShuttingDown() {
8576        return mSleeping || mShuttingDown;
8577    }
8578
8579    public boolean isSleeping() {
8580        return mSleeping;
8581    }
8582
8583    void goingToSleep() {
8584        synchronized(this) {
8585            mWentToSleep = true;
8586            updateEventDispatchingLocked();
8587            goToSleepIfNeededLocked();
8588        }
8589    }
8590
8591    void finishRunningVoiceLocked() {
8592        if (mRunningVoice) {
8593            mRunningVoice = false;
8594            goToSleepIfNeededLocked();
8595        }
8596    }
8597
8598    void goToSleepIfNeededLocked() {
8599        if (mWentToSleep && !mRunningVoice) {
8600            if (!mSleeping) {
8601                mSleeping = true;
8602                mStackSupervisor.goingToSleepLocked();
8603
8604                // Initialize the wake times of all processes.
8605                checkExcessivePowerUsageLocked(false);
8606                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8607                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8608                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8609            }
8610        }
8611    }
8612
8613    @Override
8614    public boolean shutdown(int timeout) {
8615        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8616                != PackageManager.PERMISSION_GRANTED) {
8617            throw new SecurityException("Requires permission "
8618                    + android.Manifest.permission.SHUTDOWN);
8619        }
8620
8621        boolean timedout = false;
8622
8623        synchronized(this) {
8624            mShuttingDown = true;
8625            updateEventDispatchingLocked();
8626            timedout = mStackSupervisor.shutdownLocked(timeout);
8627        }
8628
8629        mAppOpsService.shutdown();
8630        mUsageStatsService.shutdown();
8631        mBatteryStatsService.shutdown();
8632        synchronized (this) {
8633            mProcessStats.shutdownLocked();
8634        }
8635
8636        return timedout;
8637    }
8638
8639    public final void activitySlept(IBinder token) {
8640        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8641
8642        final long origId = Binder.clearCallingIdentity();
8643
8644        synchronized (this) {
8645            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8646            if (r != null) {
8647                mStackSupervisor.activitySleptLocked(r);
8648            }
8649        }
8650
8651        Binder.restoreCallingIdentity(origId);
8652    }
8653
8654    void logLockScreen(String msg) {
8655        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8656                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8657                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8658                mStackSupervisor.mDismissKeyguardOnNextActivity);
8659    }
8660
8661    private void comeOutOfSleepIfNeededLocked() {
8662        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8663            if (mSleeping) {
8664                mSleeping = false;
8665                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8666            }
8667        }
8668    }
8669
8670    void wakingUp() {
8671        synchronized(this) {
8672            mWentToSleep = false;
8673            updateEventDispatchingLocked();
8674            comeOutOfSleepIfNeededLocked();
8675        }
8676    }
8677
8678    void startRunningVoiceLocked() {
8679        if (!mRunningVoice) {
8680            mRunningVoice = true;
8681            comeOutOfSleepIfNeededLocked();
8682        }
8683    }
8684
8685    private void updateEventDispatchingLocked() {
8686        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8687    }
8688
8689    public void setLockScreenShown(boolean shown) {
8690        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8691                != PackageManager.PERMISSION_GRANTED) {
8692            throw new SecurityException("Requires permission "
8693                    + android.Manifest.permission.DEVICE_POWER);
8694        }
8695
8696        synchronized(this) {
8697            long ident = Binder.clearCallingIdentity();
8698            try {
8699                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8700                mLockScreenShown = shown;
8701                comeOutOfSleepIfNeededLocked();
8702            } finally {
8703                Binder.restoreCallingIdentity(ident);
8704            }
8705        }
8706    }
8707
8708    public void stopAppSwitches() {
8709        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8710                != PackageManager.PERMISSION_GRANTED) {
8711            throw new SecurityException("Requires permission "
8712                    + android.Manifest.permission.STOP_APP_SWITCHES);
8713        }
8714
8715        synchronized(this) {
8716            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8717                    + APP_SWITCH_DELAY_TIME;
8718            mDidAppSwitch = false;
8719            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8720            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8721            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8722        }
8723    }
8724
8725    public void resumeAppSwitches() {
8726        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8727                != PackageManager.PERMISSION_GRANTED) {
8728            throw new SecurityException("Requires permission "
8729                    + android.Manifest.permission.STOP_APP_SWITCHES);
8730        }
8731
8732        synchronized(this) {
8733            // Note that we don't execute any pending app switches... we will
8734            // let those wait until either the timeout, or the next start
8735            // activity request.
8736            mAppSwitchesAllowedTime = 0;
8737        }
8738    }
8739
8740    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8741            String name) {
8742        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8743            return true;
8744        }
8745
8746        final int perm = checkComponentPermission(
8747                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8748                callingUid, -1, true);
8749        if (perm == PackageManager.PERMISSION_GRANTED) {
8750            return true;
8751        }
8752
8753        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8754        return false;
8755    }
8756
8757    public void setDebugApp(String packageName, boolean waitForDebugger,
8758            boolean persistent) {
8759        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8760                "setDebugApp()");
8761
8762        long ident = Binder.clearCallingIdentity();
8763        try {
8764            // Note that this is not really thread safe if there are multiple
8765            // callers into it at the same time, but that's not a situation we
8766            // care about.
8767            if (persistent) {
8768                final ContentResolver resolver = mContext.getContentResolver();
8769                Settings.Global.putString(
8770                    resolver, Settings.Global.DEBUG_APP,
8771                    packageName);
8772                Settings.Global.putInt(
8773                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8774                    waitForDebugger ? 1 : 0);
8775            }
8776
8777            synchronized (this) {
8778                if (!persistent) {
8779                    mOrigDebugApp = mDebugApp;
8780                    mOrigWaitForDebugger = mWaitForDebugger;
8781                }
8782                mDebugApp = packageName;
8783                mWaitForDebugger = waitForDebugger;
8784                mDebugTransient = !persistent;
8785                if (packageName != null) {
8786                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8787                            false, UserHandle.USER_ALL, "set debug app");
8788                }
8789            }
8790        } finally {
8791            Binder.restoreCallingIdentity(ident);
8792        }
8793    }
8794
8795    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8796        synchronized (this) {
8797            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8798            if (!isDebuggable) {
8799                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8800                    throw new SecurityException("Process not debuggable: " + app.packageName);
8801                }
8802            }
8803
8804            mOpenGlTraceApp = processName;
8805        }
8806    }
8807
8808    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8809            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8810        synchronized (this) {
8811            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8812            if (!isDebuggable) {
8813                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8814                    throw new SecurityException("Process not debuggable: " + app.packageName);
8815                }
8816            }
8817            mProfileApp = processName;
8818            mProfileFile = profileFile;
8819            if (mProfileFd != null) {
8820                try {
8821                    mProfileFd.close();
8822                } catch (IOException e) {
8823                }
8824                mProfileFd = null;
8825            }
8826            mProfileFd = profileFd;
8827            mProfileType = 0;
8828            mAutoStopProfiler = autoStopProfiler;
8829        }
8830    }
8831
8832    @Override
8833    public void setAlwaysFinish(boolean enabled) {
8834        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8835                "setAlwaysFinish()");
8836
8837        Settings.Global.putInt(
8838                mContext.getContentResolver(),
8839                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8840
8841        synchronized (this) {
8842            mAlwaysFinishActivities = enabled;
8843        }
8844    }
8845
8846    @Override
8847    public void setActivityController(IActivityController controller) {
8848        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8849                "setActivityController()");
8850        synchronized (this) {
8851            mController = controller;
8852            Watchdog.getInstance().setActivityController(controller);
8853        }
8854    }
8855
8856    @Override
8857    public void setUserIsMonkey(boolean userIsMonkey) {
8858        synchronized (this) {
8859            synchronized (mPidsSelfLocked) {
8860                final int callingPid = Binder.getCallingPid();
8861                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8862                if (precessRecord == null) {
8863                    throw new SecurityException("Unknown process: " + callingPid);
8864                }
8865                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8866                    throw new SecurityException("Only an instrumentation process "
8867                            + "with a UiAutomation can call setUserIsMonkey");
8868                }
8869            }
8870            mUserIsMonkey = userIsMonkey;
8871        }
8872    }
8873
8874    @Override
8875    public boolean isUserAMonkey() {
8876        synchronized (this) {
8877            // If there is a controller also implies the user is a monkey.
8878            return (mUserIsMonkey || mController != null);
8879        }
8880    }
8881
8882    public void requestBugReport() {
8883        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8884        SystemProperties.set("ctl.start", "bugreport");
8885    }
8886
8887    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8888        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8889    }
8890
8891    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8892        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8893            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8894        }
8895        return KEY_DISPATCHING_TIMEOUT;
8896    }
8897
8898    @Override
8899    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8900        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8901                != PackageManager.PERMISSION_GRANTED) {
8902            throw new SecurityException("Requires permission "
8903                    + android.Manifest.permission.FILTER_EVENTS);
8904        }
8905        ProcessRecord proc;
8906        long timeout;
8907        synchronized (this) {
8908            synchronized (mPidsSelfLocked) {
8909                proc = mPidsSelfLocked.get(pid);
8910            }
8911            timeout = getInputDispatchingTimeoutLocked(proc);
8912        }
8913
8914        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8915            return -1;
8916        }
8917
8918        return timeout;
8919    }
8920
8921    /**
8922     * Handle input dispatching timeouts.
8923     * Returns whether input dispatching should be aborted or not.
8924     */
8925    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8926            final ActivityRecord activity, final ActivityRecord parent,
8927            final boolean aboveSystem, String reason) {
8928        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8929                != PackageManager.PERMISSION_GRANTED) {
8930            throw new SecurityException("Requires permission "
8931                    + android.Manifest.permission.FILTER_EVENTS);
8932        }
8933
8934        final String annotation;
8935        if (reason == null) {
8936            annotation = "Input dispatching timed out";
8937        } else {
8938            annotation = "Input dispatching timed out (" + reason + ")";
8939        }
8940
8941        if (proc != null) {
8942            synchronized (this) {
8943                if (proc.debugging) {
8944                    return false;
8945                }
8946
8947                if (mDidDexOpt) {
8948                    // Give more time since we were dexopting.
8949                    mDidDexOpt = false;
8950                    return false;
8951                }
8952
8953                if (proc.instrumentationClass != null) {
8954                    Bundle info = new Bundle();
8955                    info.putString("shortMsg", "keyDispatchingTimedOut");
8956                    info.putString("longMsg", annotation);
8957                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8958                    return true;
8959                }
8960            }
8961            mHandler.post(new Runnable() {
8962                @Override
8963                public void run() {
8964                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8965                }
8966            });
8967        }
8968
8969        return true;
8970    }
8971
8972    public Bundle getAssistContextExtras(int requestType) {
8973        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8974                "getAssistContextExtras()");
8975        PendingAssistExtras pae;
8976        Bundle extras = new Bundle();
8977        synchronized (this) {
8978            ActivityRecord activity = getFocusedStack().mResumedActivity;
8979            if (activity == null) {
8980                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8981                return null;
8982            }
8983            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8984            if (activity.app == null || activity.app.thread == null) {
8985                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8986                return extras;
8987            }
8988            if (activity.app.pid == Binder.getCallingPid()) {
8989                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8990                return extras;
8991            }
8992            pae = new PendingAssistExtras(activity);
8993            try {
8994                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8995                        requestType);
8996                mPendingAssistExtras.add(pae);
8997                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8998            } catch (RemoteException e) {
8999                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9000                return extras;
9001            }
9002        }
9003        synchronized (pae) {
9004            while (!pae.haveResult) {
9005                try {
9006                    pae.wait();
9007                } catch (InterruptedException e) {
9008                }
9009            }
9010            if (pae.result != null) {
9011                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9012            }
9013        }
9014        synchronized (this) {
9015            mPendingAssistExtras.remove(pae);
9016            mHandler.removeCallbacks(pae);
9017        }
9018        return extras;
9019    }
9020
9021    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9022        PendingAssistExtras pae = (PendingAssistExtras)token;
9023        synchronized (pae) {
9024            pae.result = extras;
9025            pae.haveResult = true;
9026            pae.notifyAll();
9027        }
9028    }
9029
9030    public void registerProcessObserver(IProcessObserver observer) {
9031        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9032                "registerProcessObserver()");
9033        synchronized (this) {
9034            mProcessObservers.register(observer);
9035        }
9036    }
9037
9038    @Override
9039    public void unregisterProcessObserver(IProcessObserver observer) {
9040        synchronized (this) {
9041            mProcessObservers.unregister(observer);
9042        }
9043    }
9044
9045    @Override
9046    public boolean convertFromTranslucent(IBinder token) {
9047        final long origId = Binder.clearCallingIdentity();
9048        try {
9049            synchronized (this) {
9050                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9051                if (r == null) {
9052                    return false;
9053                }
9054                if (r.changeWindowTranslucency(true)) {
9055                    mWindowManager.setAppFullscreen(token, true);
9056                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9057                    return true;
9058                }
9059                return false;
9060            }
9061        } finally {
9062            Binder.restoreCallingIdentity(origId);
9063        }
9064    }
9065
9066    @Override
9067    public boolean convertToTranslucent(IBinder token) {
9068        final long origId = Binder.clearCallingIdentity();
9069        try {
9070            synchronized (this) {
9071                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9072                if (r == null) {
9073                    return false;
9074                }
9075                if (r.changeWindowTranslucency(false)) {
9076                    r.task.stack.convertToTranslucent(r);
9077                    mWindowManager.setAppFullscreen(token, false);
9078                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9079                    return true;
9080                }
9081                return false;
9082            }
9083        } finally {
9084            Binder.restoreCallingIdentity(origId);
9085        }
9086    }
9087
9088    @Override
9089    public void setImmersive(IBinder token, boolean immersive) {
9090        synchronized(this) {
9091            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9092            if (r == null) {
9093                throw new IllegalArgumentException();
9094            }
9095            r.immersive = immersive;
9096
9097            // update associated state if we're frontmost
9098            if (r == mFocusedActivity) {
9099                if (DEBUG_IMMERSIVE) {
9100                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9101                }
9102                applyUpdateLockStateLocked(r);
9103            }
9104        }
9105    }
9106
9107    @Override
9108    public boolean isImmersive(IBinder token) {
9109        synchronized (this) {
9110            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9111            if (r == null) {
9112                throw new IllegalArgumentException();
9113            }
9114            return r.immersive;
9115        }
9116    }
9117
9118    public boolean isTopActivityImmersive() {
9119        enforceNotIsolatedCaller("startActivity");
9120        synchronized (this) {
9121            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9122            return (r != null) ? r.immersive : false;
9123        }
9124    }
9125
9126    public final void enterSafeMode() {
9127        synchronized(this) {
9128            // It only makes sense to do this before the system is ready
9129            // and started launching other packages.
9130            if (!mSystemReady) {
9131                try {
9132                    AppGlobals.getPackageManager().enterSafeMode();
9133                } catch (RemoteException e) {
9134                }
9135            }
9136
9137            mSafeMode = true;
9138        }
9139    }
9140
9141    public final void showSafeModeOverlay() {
9142        View v = LayoutInflater.from(mContext).inflate(
9143                com.android.internal.R.layout.safe_mode, null);
9144        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9145        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9146        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9147        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9148        lp.gravity = Gravity.BOTTOM | Gravity.START;
9149        lp.format = v.getBackground().getOpacity();
9150        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9151                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9152        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9153        ((WindowManager)mContext.getSystemService(
9154                Context.WINDOW_SERVICE)).addView(v, lp);
9155    }
9156
9157    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9158        if (!(sender instanceof PendingIntentRecord)) {
9159            return;
9160        }
9161        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9162        synchronized (stats) {
9163            if (mBatteryStatsService.isOnBattery()) {
9164                mBatteryStatsService.enforceCallingPermission();
9165                PendingIntentRecord rec = (PendingIntentRecord)sender;
9166                int MY_UID = Binder.getCallingUid();
9167                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9168                BatteryStatsImpl.Uid.Pkg pkg =
9169                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9170                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9171                pkg.incWakeupsLocked();
9172            }
9173        }
9174    }
9175
9176    public boolean killPids(int[] pids, String pReason, boolean secure) {
9177        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9178            throw new SecurityException("killPids only available to the system");
9179        }
9180        String reason = (pReason == null) ? "Unknown" : pReason;
9181        // XXX Note: don't acquire main activity lock here, because the window
9182        // manager calls in with its locks held.
9183
9184        boolean killed = false;
9185        synchronized (mPidsSelfLocked) {
9186            int[] types = new int[pids.length];
9187            int worstType = 0;
9188            for (int i=0; i<pids.length; i++) {
9189                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9190                if (proc != null) {
9191                    int type = proc.setAdj;
9192                    types[i] = type;
9193                    if (type > worstType) {
9194                        worstType = type;
9195                    }
9196                }
9197            }
9198
9199            // If the worst oom_adj is somewhere in the cached proc LRU range,
9200            // then constrain it so we will kill all cached procs.
9201            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9202                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9203                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9204            }
9205
9206            // If this is not a secure call, don't let it kill processes that
9207            // are important.
9208            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9209                worstType = ProcessList.SERVICE_ADJ;
9210            }
9211
9212            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9213            for (int i=0; i<pids.length; i++) {
9214                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9215                if (proc == null) {
9216                    continue;
9217                }
9218                int adj = proc.setAdj;
9219                if (adj >= worstType && !proc.killedByAm) {
9220                    killUnneededProcessLocked(proc, reason);
9221                    killed = true;
9222                }
9223            }
9224        }
9225        return killed;
9226    }
9227
9228    @Override
9229    public void killUid(int uid, String reason) {
9230        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9231            throw new SecurityException("killUid only available to the system");
9232        }
9233        synchronized (this) {
9234            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9235                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9236                    reason != null ? reason : "kill uid");
9237        }
9238    }
9239
9240    @Override
9241    public boolean killProcessesBelowForeground(String reason) {
9242        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9243            throw new SecurityException("killProcessesBelowForeground() only available to system");
9244        }
9245
9246        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9247    }
9248
9249    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9250        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9251            throw new SecurityException("killProcessesBelowAdj() only available to system");
9252        }
9253
9254        boolean killed = false;
9255        synchronized (mPidsSelfLocked) {
9256            final int size = mPidsSelfLocked.size();
9257            for (int i = 0; i < size; i++) {
9258                final int pid = mPidsSelfLocked.keyAt(i);
9259                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9260                if (proc == null) continue;
9261
9262                final int adj = proc.setAdj;
9263                if (adj > belowAdj && !proc.killedByAm) {
9264                    killUnneededProcessLocked(proc, reason);
9265                    killed = true;
9266                }
9267            }
9268        }
9269        return killed;
9270    }
9271
9272    @Override
9273    public void hang(final IBinder who, boolean allowRestart) {
9274        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9275                != PackageManager.PERMISSION_GRANTED) {
9276            throw new SecurityException("Requires permission "
9277                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9278        }
9279
9280        final IBinder.DeathRecipient death = new DeathRecipient() {
9281            @Override
9282            public void binderDied() {
9283                synchronized (this) {
9284                    notifyAll();
9285                }
9286            }
9287        };
9288
9289        try {
9290            who.linkToDeath(death, 0);
9291        } catch (RemoteException e) {
9292            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9293            return;
9294        }
9295
9296        synchronized (this) {
9297            Watchdog.getInstance().setAllowRestart(allowRestart);
9298            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9299            synchronized (death) {
9300                while (who.isBinderAlive()) {
9301                    try {
9302                        death.wait();
9303                    } catch (InterruptedException e) {
9304                    }
9305                }
9306            }
9307            Watchdog.getInstance().setAllowRestart(true);
9308        }
9309    }
9310
9311    @Override
9312    public void restart() {
9313        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9314                != PackageManager.PERMISSION_GRANTED) {
9315            throw new SecurityException("Requires permission "
9316                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9317        }
9318
9319        Log.i(TAG, "Sending shutdown broadcast...");
9320
9321        BroadcastReceiver br = new BroadcastReceiver() {
9322            @Override public void onReceive(Context context, Intent intent) {
9323                // Now the broadcast is done, finish up the low-level shutdown.
9324                Log.i(TAG, "Shutting down activity manager...");
9325                shutdown(10000);
9326                Log.i(TAG, "Shutdown complete, restarting!");
9327                Process.killProcess(Process.myPid());
9328                System.exit(10);
9329            }
9330        };
9331
9332        // First send the high-level shut down broadcast.
9333        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9334        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9335        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9336        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9337        mContext.sendOrderedBroadcastAsUser(intent,
9338                UserHandle.ALL, null, br, mHandler, 0, null, null);
9339        */
9340        br.onReceive(mContext, intent);
9341    }
9342
9343    private long getLowRamTimeSinceIdle(long now) {
9344        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9345    }
9346
9347    @Override
9348    public void performIdleMaintenance() {
9349        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9350                != PackageManager.PERMISSION_GRANTED) {
9351            throw new SecurityException("Requires permission "
9352                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9353        }
9354
9355        synchronized (this) {
9356            final long now = SystemClock.uptimeMillis();
9357            final long timeSinceLastIdle = now - mLastIdleTime;
9358            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9359            mLastIdleTime = now;
9360            mLowRamTimeSinceLastIdle = 0;
9361            if (mLowRamStartTime != 0) {
9362                mLowRamStartTime = now;
9363            }
9364
9365            StringBuilder sb = new StringBuilder(128);
9366            sb.append("Idle maintenance over ");
9367            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9368            sb.append(" low RAM for ");
9369            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9370            Slog.i(TAG, sb.toString());
9371
9372            // If at least 1/3 of our time since the last idle period has been spent
9373            // with RAM low, then we want to kill processes.
9374            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9375
9376            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9377                ProcessRecord proc = mLruProcesses.get(i);
9378                if (proc.notCachedSinceIdle) {
9379                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9380                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9381                        if (doKilling && proc.initialIdlePss != 0
9382                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9383                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9384                                    + " from " + proc.initialIdlePss + ")");
9385                        }
9386                    }
9387                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9388                    proc.notCachedSinceIdle = true;
9389                    proc.initialIdlePss = 0;
9390                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9391                            isSleeping(), now);
9392                }
9393            }
9394
9395            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9396            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9397        }
9398    }
9399
9400    private void retrieveSettings() {
9401        final ContentResolver resolver = mContext.getContentResolver();
9402        String debugApp = Settings.Global.getString(
9403            resolver, Settings.Global.DEBUG_APP);
9404        boolean waitForDebugger = Settings.Global.getInt(
9405            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9406        boolean alwaysFinishActivities = Settings.Global.getInt(
9407            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9408        boolean forceRtl = Settings.Global.getInt(
9409                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9410        // Transfer any global setting for forcing RTL layout, into a System Property
9411        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9412
9413        Configuration configuration = new Configuration();
9414        Settings.System.getConfiguration(resolver, configuration);
9415        if (forceRtl) {
9416            // This will take care of setting the correct layout direction flags
9417            configuration.setLayoutDirection(configuration.locale);
9418        }
9419
9420        synchronized (this) {
9421            mDebugApp = mOrigDebugApp = debugApp;
9422            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9423            mAlwaysFinishActivities = alwaysFinishActivities;
9424            // This happens before any activities are started, so we can
9425            // change mConfiguration in-place.
9426            updateConfigurationLocked(configuration, null, false, true);
9427            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9428        }
9429    }
9430
9431    public boolean testIsSystemReady() {
9432        // no need to synchronize(this) just to read & return the value
9433        return mSystemReady;
9434    }
9435
9436    private static File getCalledPreBootReceiversFile() {
9437        File dataDir = Environment.getDataDirectory();
9438        File systemDir = new File(dataDir, "system");
9439        File fname = new File(systemDir, "called_pre_boots.dat");
9440        return fname;
9441    }
9442
9443    static final int LAST_DONE_VERSION = 10000;
9444
9445    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9446        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9447        File file = getCalledPreBootReceiversFile();
9448        FileInputStream fis = null;
9449        try {
9450            fis = new FileInputStream(file);
9451            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9452            int fvers = dis.readInt();
9453            if (fvers == LAST_DONE_VERSION) {
9454                String vers = dis.readUTF();
9455                String codename = dis.readUTF();
9456                String build = dis.readUTF();
9457                if (android.os.Build.VERSION.RELEASE.equals(vers)
9458                        && android.os.Build.VERSION.CODENAME.equals(codename)
9459                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9460                    int num = dis.readInt();
9461                    while (num > 0) {
9462                        num--;
9463                        String pkg = dis.readUTF();
9464                        String cls = dis.readUTF();
9465                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9466                    }
9467                }
9468            }
9469        } catch (FileNotFoundException e) {
9470        } catch (IOException e) {
9471            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9472        } finally {
9473            if (fis != null) {
9474                try {
9475                    fis.close();
9476                } catch (IOException e) {
9477                }
9478            }
9479        }
9480        return lastDoneReceivers;
9481    }
9482
9483    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9484        File file = getCalledPreBootReceiversFile();
9485        FileOutputStream fos = null;
9486        DataOutputStream dos = null;
9487        try {
9488            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9489            fos = new FileOutputStream(file);
9490            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9491            dos.writeInt(LAST_DONE_VERSION);
9492            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9493            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9494            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9495            dos.writeInt(list.size());
9496            for (int i=0; i<list.size(); i++) {
9497                dos.writeUTF(list.get(i).getPackageName());
9498                dos.writeUTF(list.get(i).getClassName());
9499            }
9500        } catch (IOException e) {
9501            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9502            file.delete();
9503        } finally {
9504            FileUtils.sync(fos);
9505            if (dos != null) {
9506                try {
9507                    dos.close();
9508                } catch (IOException e) {
9509                    // TODO Auto-generated catch block
9510                    e.printStackTrace();
9511                }
9512            }
9513        }
9514    }
9515
9516    public void systemReady(final Runnable goingCallback) {
9517        synchronized(this) {
9518            if (mSystemReady) {
9519                if (goingCallback != null) goingCallback.run();
9520                return;
9521            }
9522
9523            // Check to see if there are any update receivers to run.
9524            if (!mDidUpdate) {
9525                if (mWaitingUpdate) {
9526                    return;
9527                }
9528                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9529                List<ResolveInfo> ris = null;
9530                try {
9531                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9532                            intent, null, 0, 0);
9533                } catch (RemoteException e) {
9534                }
9535                if (ris != null) {
9536                    for (int i=ris.size()-1; i>=0; i--) {
9537                        if ((ris.get(i).activityInfo.applicationInfo.flags
9538                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9539                            ris.remove(i);
9540                        }
9541                    }
9542                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9543
9544                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9545
9546                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9547                    for (int i=0; i<ris.size(); i++) {
9548                        ActivityInfo ai = ris.get(i).activityInfo;
9549                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9550                        if (lastDoneReceivers.contains(comp)) {
9551                            // We already did the pre boot receiver for this app with the current
9552                            // platform version, so don't do it again...
9553                            ris.remove(i);
9554                            i--;
9555                            // ...however, do keep it as one that has been done, so we don't
9556                            // forget about it when rewriting the file of last done receivers.
9557                            doneReceivers.add(comp);
9558                        }
9559                    }
9560
9561                    final int[] users = getUsersLocked();
9562                    for (int i=0; i<ris.size(); i++) {
9563                        ActivityInfo ai = ris.get(i).activityInfo;
9564                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9565                        doneReceivers.add(comp);
9566                        intent.setComponent(comp);
9567                        for (int j=0; j<users.length; j++) {
9568                            IIntentReceiver finisher = null;
9569                            if (i == ris.size()-1 && j == users.length-1) {
9570                                finisher = new IIntentReceiver.Stub() {
9571                                    public void performReceive(Intent intent, int resultCode,
9572                                            String data, Bundle extras, boolean ordered,
9573                                            boolean sticky, int sendingUser) {
9574                                        // The raw IIntentReceiver interface is called
9575                                        // with the AM lock held, so redispatch to
9576                                        // execute our code without the lock.
9577                                        mHandler.post(new Runnable() {
9578                                            public void run() {
9579                                                synchronized (ActivityManagerService.this) {
9580                                                    mDidUpdate = true;
9581                                                }
9582                                                writeLastDonePreBootReceivers(doneReceivers);
9583                                                showBootMessage(mContext.getText(
9584                                                        R.string.android_upgrading_complete),
9585                                                        false);
9586                                                systemReady(goingCallback);
9587                                            }
9588                                        });
9589                                    }
9590                                };
9591                            }
9592                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9593                                    + " for user " + users[j]);
9594                            broadcastIntentLocked(null, null, intent, null, finisher,
9595                                    0, null, null, null, AppOpsManager.OP_NONE,
9596                                    true, false, MY_PID, Process.SYSTEM_UID,
9597                                    users[j]);
9598                            if (finisher != null) {
9599                                mWaitingUpdate = true;
9600                            }
9601                        }
9602                    }
9603                }
9604                if (mWaitingUpdate) {
9605                    return;
9606                }
9607                mDidUpdate = true;
9608            }
9609
9610            mAppOpsService.systemReady();
9611            mSystemReady = true;
9612        }
9613
9614        ArrayList<ProcessRecord> procsToKill = null;
9615        synchronized(mPidsSelfLocked) {
9616            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9617                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9618                if (!isAllowedWhileBooting(proc.info)){
9619                    if (procsToKill == null) {
9620                        procsToKill = new ArrayList<ProcessRecord>();
9621                    }
9622                    procsToKill.add(proc);
9623                }
9624            }
9625        }
9626
9627        synchronized(this) {
9628            if (procsToKill != null) {
9629                for (int i=procsToKill.size()-1; i>=0; i--) {
9630                    ProcessRecord proc = procsToKill.get(i);
9631                    Slog.i(TAG, "Removing system update proc: " + proc);
9632                    removeProcessLocked(proc, true, false, "system update done");
9633                }
9634            }
9635
9636            // Now that we have cleaned up any update processes, we
9637            // are ready to start launching real processes and know that
9638            // we won't trample on them any more.
9639            mProcessesReady = true;
9640        }
9641
9642        Slog.i(TAG, "System now ready");
9643        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9644            SystemClock.uptimeMillis());
9645
9646        synchronized(this) {
9647            // Make sure we have no pre-ready processes sitting around.
9648
9649            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9650                ResolveInfo ri = mContext.getPackageManager()
9651                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9652                                STOCK_PM_FLAGS);
9653                CharSequence errorMsg = null;
9654                if (ri != null) {
9655                    ActivityInfo ai = ri.activityInfo;
9656                    ApplicationInfo app = ai.applicationInfo;
9657                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9658                        mTopAction = Intent.ACTION_FACTORY_TEST;
9659                        mTopData = null;
9660                        mTopComponent = new ComponentName(app.packageName,
9661                                ai.name);
9662                    } else {
9663                        errorMsg = mContext.getResources().getText(
9664                                com.android.internal.R.string.factorytest_not_system);
9665                    }
9666                } else {
9667                    errorMsg = mContext.getResources().getText(
9668                            com.android.internal.R.string.factorytest_no_action);
9669                }
9670                if (errorMsg != null) {
9671                    mTopAction = null;
9672                    mTopData = null;
9673                    mTopComponent = null;
9674                    Message msg = Message.obtain();
9675                    msg.what = SHOW_FACTORY_ERROR_MSG;
9676                    msg.getData().putCharSequence("msg", errorMsg);
9677                    mHandler.sendMessage(msg);
9678                }
9679            }
9680        }
9681
9682        retrieveSettings();
9683
9684        synchronized (this) {
9685            readGrantedUriPermissionsLocked();
9686        }
9687
9688        if (goingCallback != null) goingCallback.run();
9689
9690        mSystemServiceManager.startUser(mCurrentUserId);
9691
9692        synchronized (this) {
9693            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9694                try {
9695                    List apps = AppGlobals.getPackageManager().
9696                        getPersistentApplications(STOCK_PM_FLAGS);
9697                    if (apps != null) {
9698                        int N = apps.size();
9699                        int i;
9700                        for (i=0; i<N; i++) {
9701                            ApplicationInfo info
9702                                = (ApplicationInfo)apps.get(i);
9703                            if (info != null &&
9704                                    !info.packageName.equals("android")) {
9705                                addAppLocked(info, false);
9706                            }
9707                        }
9708                    }
9709                } catch (RemoteException ex) {
9710                    // pm is in same process, this will never happen.
9711                }
9712            }
9713
9714            // Start up initial activity.
9715            mBooting = true;
9716
9717            try {
9718                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9719                    Message msg = Message.obtain();
9720                    msg.what = SHOW_UID_ERROR_MSG;
9721                    mHandler.sendMessage(msg);
9722                }
9723            } catch (RemoteException e) {
9724            }
9725
9726            long ident = Binder.clearCallingIdentity();
9727            try {
9728                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9729                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9730                        | Intent.FLAG_RECEIVER_FOREGROUND);
9731                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9732                broadcastIntentLocked(null, null, intent,
9733                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9734                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9735                intent = new Intent(Intent.ACTION_USER_STARTING);
9736                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9737                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9738                broadcastIntentLocked(null, null, intent,
9739                        null, new IIntentReceiver.Stub() {
9740                            @Override
9741                            public void performReceive(Intent intent, int resultCode, String data,
9742                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9743                                    throws RemoteException {
9744                            }
9745                        }, 0, null, null,
9746                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9747                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9748            } catch (Throwable t) {
9749                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9750            } finally {
9751                Binder.restoreCallingIdentity(ident);
9752            }
9753            mStackSupervisor.resumeTopActivitiesLocked();
9754            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9755        }
9756    }
9757
9758    private boolean makeAppCrashingLocked(ProcessRecord app,
9759            String shortMsg, String longMsg, String stackTrace) {
9760        app.crashing = true;
9761        app.crashingReport = generateProcessError(app,
9762                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9763        startAppProblemLocked(app);
9764        app.stopFreezingAllLocked();
9765        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9766    }
9767
9768    private void makeAppNotRespondingLocked(ProcessRecord app,
9769            String activity, String shortMsg, String longMsg) {
9770        app.notResponding = true;
9771        app.notRespondingReport = generateProcessError(app,
9772                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9773                activity, shortMsg, longMsg, null);
9774        startAppProblemLocked(app);
9775        app.stopFreezingAllLocked();
9776    }
9777
9778    /**
9779     * Generate a process error record, suitable for attachment to a ProcessRecord.
9780     *
9781     * @param app The ProcessRecord in which the error occurred.
9782     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9783     *                      ActivityManager.AppErrorStateInfo
9784     * @param activity The activity associated with the crash, if known.
9785     * @param shortMsg Short message describing the crash.
9786     * @param longMsg Long message describing the crash.
9787     * @param stackTrace Full crash stack trace, may be null.
9788     *
9789     * @return Returns a fully-formed AppErrorStateInfo record.
9790     */
9791    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9792            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9793        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9794
9795        report.condition = condition;
9796        report.processName = app.processName;
9797        report.pid = app.pid;
9798        report.uid = app.info.uid;
9799        report.tag = activity;
9800        report.shortMsg = shortMsg;
9801        report.longMsg = longMsg;
9802        report.stackTrace = stackTrace;
9803
9804        return report;
9805    }
9806
9807    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9808        synchronized (this) {
9809            app.crashing = false;
9810            app.crashingReport = null;
9811            app.notResponding = false;
9812            app.notRespondingReport = null;
9813            if (app.anrDialog == fromDialog) {
9814                app.anrDialog = null;
9815            }
9816            if (app.waitDialog == fromDialog) {
9817                app.waitDialog = null;
9818            }
9819            if (app.pid > 0 && app.pid != MY_PID) {
9820                handleAppCrashLocked(app, null, null, null);
9821                killUnneededProcessLocked(app, "user request after error");
9822            }
9823        }
9824    }
9825
9826    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9827            String stackTrace) {
9828        long now = SystemClock.uptimeMillis();
9829
9830        Long crashTime;
9831        if (!app.isolated) {
9832            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9833        } else {
9834            crashTime = null;
9835        }
9836        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9837            // This process loses!
9838            Slog.w(TAG, "Process " + app.info.processName
9839                    + " has crashed too many times: killing!");
9840            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9841                    app.userId, app.info.processName, app.uid);
9842            mStackSupervisor.handleAppCrashLocked(app);
9843            if (!app.persistent) {
9844                // We don't want to start this process again until the user
9845                // explicitly does so...  but for persistent process, we really
9846                // need to keep it running.  If a persistent process is actually
9847                // repeatedly crashing, then badness for everyone.
9848                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9849                        app.info.processName);
9850                if (!app.isolated) {
9851                    // XXX We don't have a way to mark isolated processes
9852                    // as bad, since they don't have a peristent identity.
9853                    mBadProcesses.put(app.info.processName, app.uid,
9854                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9855                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9856                }
9857                app.bad = true;
9858                app.removed = true;
9859                // Don't let services in this process be restarted and potentially
9860                // annoy the user repeatedly.  Unless it is persistent, since those
9861                // processes run critical code.
9862                removeProcessLocked(app, false, false, "crash");
9863                mStackSupervisor.resumeTopActivitiesLocked();
9864                return false;
9865            }
9866            mStackSupervisor.resumeTopActivitiesLocked();
9867        } else {
9868            mStackSupervisor.finishTopRunningActivityLocked(app);
9869        }
9870
9871        // Bump up the crash count of any services currently running in the proc.
9872        for (int i=app.services.size()-1; i>=0; i--) {
9873            // Any services running in the application need to be placed
9874            // back in the pending list.
9875            ServiceRecord sr = app.services.valueAt(i);
9876            sr.crashCount++;
9877        }
9878
9879        // If the crashing process is what we consider to be the "home process" and it has been
9880        // replaced by a third-party app, clear the package preferred activities from packages
9881        // with a home activity running in the process to prevent a repeatedly crashing app
9882        // from blocking the user to manually clear the list.
9883        final ArrayList<ActivityRecord> activities = app.activities;
9884        if (app == mHomeProcess && activities.size() > 0
9885                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9886            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9887                final ActivityRecord r = activities.get(activityNdx);
9888                if (r.isHomeActivity()) {
9889                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9890                    try {
9891                        ActivityThread.getPackageManager()
9892                                .clearPackagePreferredActivities(r.packageName);
9893                    } catch (RemoteException c) {
9894                        // pm is in same process, this will never happen.
9895                    }
9896                }
9897            }
9898        }
9899
9900        if (!app.isolated) {
9901            // XXX Can't keep track of crash times for isolated processes,
9902            // because they don't have a perisistent identity.
9903            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9904        }
9905
9906        return true;
9907    }
9908
9909    void startAppProblemLocked(ProcessRecord app) {
9910        if (app.userId == mCurrentUserId) {
9911            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9912                    mContext, app.info.packageName, app.info.flags);
9913        } else {
9914            // If this app is not running under the current user, then we
9915            // can't give it a report button because that would require
9916            // launching the report UI under a different user.
9917            app.errorReportReceiver = null;
9918        }
9919        skipCurrentReceiverLocked(app);
9920    }
9921
9922    void skipCurrentReceiverLocked(ProcessRecord app) {
9923        for (BroadcastQueue queue : mBroadcastQueues) {
9924            queue.skipCurrentReceiverLocked(app);
9925        }
9926    }
9927
9928    /**
9929     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9930     * The application process will exit immediately after this call returns.
9931     * @param app object of the crashing app, null for the system server
9932     * @param crashInfo describing the exception
9933     */
9934    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9935        ProcessRecord r = findAppProcess(app, "Crash");
9936        final String processName = app == null ? "system_server"
9937                : (r == null ? "unknown" : r.processName);
9938
9939        handleApplicationCrashInner("crash", r, processName, crashInfo);
9940    }
9941
9942    /* Native crash reporting uses this inner version because it needs to be somewhat
9943     * decoupled from the AM-managed cleanup lifecycle
9944     */
9945    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9946            ApplicationErrorReport.CrashInfo crashInfo) {
9947        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9948                UserHandle.getUserId(Binder.getCallingUid()), processName,
9949                r == null ? -1 : r.info.flags,
9950                crashInfo.exceptionClassName,
9951                crashInfo.exceptionMessage,
9952                crashInfo.throwFileName,
9953                crashInfo.throwLineNumber);
9954
9955        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9956
9957        crashApplication(r, crashInfo);
9958    }
9959
9960    public void handleApplicationStrictModeViolation(
9961            IBinder app,
9962            int violationMask,
9963            StrictMode.ViolationInfo info) {
9964        ProcessRecord r = findAppProcess(app, "StrictMode");
9965        if (r == null) {
9966            return;
9967        }
9968
9969        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9970            Integer stackFingerprint = info.hashCode();
9971            boolean logIt = true;
9972            synchronized (mAlreadyLoggedViolatedStacks) {
9973                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9974                    logIt = false;
9975                    // TODO: sub-sample into EventLog for these, with
9976                    // the info.durationMillis?  Then we'd get
9977                    // the relative pain numbers, without logging all
9978                    // the stack traces repeatedly.  We'd want to do
9979                    // likewise in the client code, which also does
9980                    // dup suppression, before the Binder call.
9981                } else {
9982                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9983                        mAlreadyLoggedViolatedStacks.clear();
9984                    }
9985                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9986                }
9987            }
9988            if (logIt) {
9989                logStrictModeViolationToDropBox(r, info);
9990            }
9991        }
9992
9993        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9994            AppErrorResult result = new AppErrorResult();
9995            synchronized (this) {
9996                final long origId = Binder.clearCallingIdentity();
9997
9998                Message msg = Message.obtain();
9999                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10000                HashMap<String, Object> data = new HashMap<String, Object>();
10001                data.put("result", result);
10002                data.put("app", r);
10003                data.put("violationMask", violationMask);
10004                data.put("info", info);
10005                msg.obj = data;
10006                mHandler.sendMessage(msg);
10007
10008                Binder.restoreCallingIdentity(origId);
10009            }
10010            int res = result.get();
10011            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10012        }
10013    }
10014
10015    // Depending on the policy in effect, there could be a bunch of
10016    // these in quick succession so we try to batch these together to
10017    // minimize disk writes, number of dropbox entries, and maximize
10018    // compression, by having more fewer, larger records.
10019    private void logStrictModeViolationToDropBox(
10020            ProcessRecord process,
10021            StrictMode.ViolationInfo info) {
10022        if (info == null) {
10023            return;
10024        }
10025        final boolean isSystemApp = process == null ||
10026                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10027                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10028        final String processName = process == null ? "unknown" : process.processName;
10029        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10030        final DropBoxManager dbox = (DropBoxManager)
10031                mContext.getSystemService(Context.DROPBOX_SERVICE);
10032
10033        // Exit early if the dropbox isn't configured to accept this report type.
10034        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10035
10036        boolean bufferWasEmpty;
10037        boolean needsFlush;
10038        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10039        synchronized (sb) {
10040            bufferWasEmpty = sb.length() == 0;
10041            appendDropBoxProcessHeaders(process, processName, sb);
10042            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10043            sb.append("System-App: ").append(isSystemApp).append("\n");
10044            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10045            if (info.violationNumThisLoop != 0) {
10046                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10047            }
10048            if (info.numAnimationsRunning != 0) {
10049                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10050            }
10051            if (info.broadcastIntentAction != null) {
10052                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10053            }
10054            if (info.durationMillis != -1) {
10055                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10056            }
10057            if (info.numInstances != -1) {
10058                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10059            }
10060            if (info.tags != null) {
10061                for (String tag : info.tags) {
10062                    sb.append("Span-Tag: ").append(tag).append("\n");
10063                }
10064            }
10065            sb.append("\n");
10066            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10067                sb.append(info.crashInfo.stackTrace);
10068            }
10069            sb.append("\n");
10070
10071            // Only buffer up to ~64k.  Various logging bits truncate
10072            // things at 128k.
10073            needsFlush = (sb.length() > 64 * 1024);
10074        }
10075
10076        // Flush immediately if the buffer's grown too large, or this
10077        // is a non-system app.  Non-system apps are isolated with a
10078        // different tag & policy and not batched.
10079        //
10080        // Batching is useful during internal testing with
10081        // StrictMode settings turned up high.  Without batching,
10082        // thousands of separate files could be created on boot.
10083        if (!isSystemApp || needsFlush) {
10084            new Thread("Error dump: " + dropboxTag) {
10085                @Override
10086                public void run() {
10087                    String report;
10088                    synchronized (sb) {
10089                        report = sb.toString();
10090                        sb.delete(0, sb.length());
10091                        sb.trimToSize();
10092                    }
10093                    if (report.length() != 0) {
10094                        dbox.addText(dropboxTag, report);
10095                    }
10096                }
10097            }.start();
10098            return;
10099        }
10100
10101        // System app batching:
10102        if (!bufferWasEmpty) {
10103            // An existing dropbox-writing thread is outstanding, so
10104            // we don't need to start it up.  The existing thread will
10105            // catch the buffer appends we just did.
10106            return;
10107        }
10108
10109        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10110        // (After this point, we shouldn't access AMS internal data structures.)
10111        new Thread("Error dump: " + dropboxTag) {
10112            @Override
10113            public void run() {
10114                // 5 second sleep to let stacks arrive and be batched together
10115                try {
10116                    Thread.sleep(5000);  // 5 seconds
10117                } catch (InterruptedException e) {}
10118
10119                String errorReport;
10120                synchronized (mStrictModeBuffer) {
10121                    errorReport = mStrictModeBuffer.toString();
10122                    if (errorReport.length() == 0) {
10123                        return;
10124                    }
10125                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10126                    mStrictModeBuffer.trimToSize();
10127                }
10128                dbox.addText(dropboxTag, errorReport);
10129            }
10130        }.start();
10131    }
10132
10133    /**
10134     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10135     * @param app object of the crashing app, null for the system server
10136     * @param tag reported by the caller
10137     * @param crashInfo describing the context of the error
10138     * @return true if the process should exit immediately (WTF is fatal)
10139     */
10140    public boolean handleApplicationWtf(IBinder app, String tag,
10141            ApplicationErrorReport.CrashInfo crashInfo) {
10142        ProcessRecord r = findAppProcess(app, "WTF");
10143        final String processName = app == null ? "system_server"
10144                : (r == null ? "unknown" : r.processName);
10145
10146        EventLog.writeEvent(EventLogTags.AM_WTF,
10147                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10148                processName,
10149                r == null ? -1 : r.info.flags,
10150                tag, crashInfo.exceptionMessage);
10151
10152        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10153
10154        if (r != null && r.pid != Process.myPid() &&
10155                Settings.Global.getInt(mContext.getContentResolver(),
10156                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10157            crashApplication(r, crashInfo);
10158            return true;
10159        } else {
10160            return false;
10161        }
10162    }
10163
10164    /**
10165     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10166     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10167     */
10168    private ProcessRecord findAppProcess(IBinder app, String reason) {
10169        if (app == null) {
10170            return null;
10171        }
10172
10173        synchronized (this) {
10174            final int NP = mProcessNames.getMap().size();
10175            for (int ip=0; ip<NP; ip++) {
10176                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10177                final int NA = apps.size();
10178                for (int ia=0; ia<NA; ia++) {
10179                    ProcessRecord p = apps.valueAt(ia);
10180                    if (p.thread != null && p.thread.asBinder() == app) {
10181                        return p;
10182                    }
10183                }
10184            }
10185
10186            Slog.w(TAG, "Can't find mystery application for " + reason
10187                    + " from pid=" + Binder.getCallingPid()
10188                    + " uid=" + Binder.getCallingUid() + ": " + app);
10189            return null;
10190        }
10191    }
10192
10193    /**
10194     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10195     * to append various headers to the dropbox log text.
10196     */
10197    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10198            StringBuilder sb) {
10199        // Watchdog thread ends up invoking this function (with
10200        // a null ProcessRecord) to add the stack file to dropbox.
10201        // Do not acquire a lock on this (am) in such cases, as it
10202        // could cause a potential deadlock, if and when watchdog
10203        // is invoked due to unavailability of lock on am and it
10204        // would prevent watchdog from killing system_server.
10205        if (process == null) {
10206            sb.append("Process: ").append(processName).append("\n");
10207            return;
10208        }
10209        // Note: ProcessRecord 'process' is guarded by the service
10210        // instance.  (notably process.pkgList, which could otherwise change
10211        // concurrently during execution of this method)
10212        synchronized (this) {
10213            sb.append("Process: ").append(processName).append("\n");
10214            int flags = process.info.flags;
10215            IPackageManager pm = AppGlobals.getPackageManager();
10216            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10217            for (int ip=0; ip<process.pkgList.size(); ip++) {
10218                String pkg = process.pkgList.keyAt(ip);
10219                sb.append("Package: ").append(pkg);
10220                try {
10221                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10222                    if (pi != null) {
10223                        sb.append(" v").append(pi.versionCode);
10224                        if (pi.versionName != null) {
10225                            sb.append(" (").append(pi.versionName).append(")");
10226                        }
10227                    }
10228                } catch (RemoteException e) {
10229                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10230                }
10231                sb.append("\n");
10232            }
10233        }
10234    }
10235
10236    private static String processClass(ProcessRecord process) {
10237        if (process == null || process.pid == MY_PID) {
10238            return "system_server";
10239        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10240            return "system_app";
10241        } else {
10242            return "data_app";
10243        }
10244    }
10245
10246    /**
10247     * Write a description of an error (crash, WTF, ANR) to the drop box.
10248     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10249     * @param process which caused the error, null means the system server
10250     * @param activity which triggered the error, null if unknown
10251     * @param parent activity related to the error, null if unknown
10252     * @param subject line related to the error, null if absent
10253     * @param report in long form describing the error, null if absent
10254     * @param logFile to include in the report, null if none
10255     * @param crashInfo giving an application stack trace, null if absent
10256     */
10257    public void addErrorToDropBox(String eventType,
10258            ProcessRecord process, String processName, ActivityRecord activity,
10259            ActivityRecord parent, String subject,
10260            final String report, final File logFile,
10261            final ApplicationErrorReport.CrashInfo crashInfo) {
10262        // NOTE -- this must never acquire the ActivityManagerService lock,
10263        // otherwise the watchdog may be prevented from resetting the system.
10264
10265        final String dropboxTag = processClass(process) + "_" + eventType;
10266        final DropBoxManager dbox = (DropBoxManager)
10267                mContext.getSystemService(Context.DROPBOX_SERVICE);
10268
10269        // Exit early if the dropbox isn't configured to accept this report type.
10270        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10271
10272        final StringBuilder sb = new StringBuilder(1024);
10273        appendDropBoxProcessHeaders(process, processName, sb);
10274        if (activity != null) {
10275            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10276        }
10277        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10278            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10279        }
10280        if (parent != null && parent != activity) {
10281            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10282        }
10283        if (subject != null) {
10284            sb.append("Subject: ").append(subject).append("\n");
10285        }
10286        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10287        if (Debug.isDebuggerConnected()) {
10288            sb.append("Debugger: Connected\n");
10289        }
10290        sb.append("\n");
10291
10292        // Do the rest in a worker thread to avoid blocking the caller on I/O
10293        // (After this point, we shouldn't access AMS internal data structures.)
10294        Thread worker = new Thread("Error dump: " + dropboxTag) {
10295            @Override
10296            public void run() {
10297                if (report != null) {
10298                    sb.append(report);
10299                }
10300                if (logFile != null) {
10301                    try {
10302                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10303                                    "\n\n[[TRUNCATED]]"));
10304                    } catch (IOException e) {
10305                        Slog.e(TAG, "Error reading " + logFile, e);
10306                    }
10307                }
10308                if (crashInfo != null && crashInfo.stackTrace != null) {
10309                    sb.append(crashInfo.stackTrace);
10310                }
10311
10312                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10313                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10314                if (lines > 0) {
10315                    sb.append("\n");
10316
10317                    // Merge several logcat streams, and take the last N lines
10318                    InputStreamReader input = null;
10319                    try {
10320                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10321                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10322                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10323
10324                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10325                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10326                        input = new InputStreamReader(logcat.getInputStream());
10327
10328                        int num;
10329                        char[] buf = new char[8192];
10330                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10331                    } catch (IOException e) {
10332                        Slog.e(TAG, "Error running logcat", e);
10333                    } finally {
10334                        if (input != null) try { input.close(); } catch (IOException e) {}
10335                    }
10336                }
10337
10338                dbox.addText(dropboxTag, sb.toString());
10339            }
10340        };
10341
10342        if (process == null) {
10343            // If process is null, we are being called from some internal code
10344            // and may be about to die -- run this synchronously.
10345            worker.run();
10346        } else {
10347            worker.start();
10348        }
10349    }
10350
10351    /**
10352     * Bring up the "unexpected error" dialog box for a crashing app.
10353     * Deal with edge cases (intercepts from instrumented applications,
10354     * ActivityController, error intent receivers, that sort of thing).
10355     * @param r the application crashing
10356     * @param crashInfo describing the failure
10357     */
10358    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10359        long timeMillis = System.currentTimeMillis();
10360        String shortMsg = crashInfo.exceptionClassName;
10361        String longMsg = crashInfo.exceptionMessage;
10362        String stackTrace = crashInfo.stackTrace;
10363        if (shortMsg != null && longMsg != null) {
10364            longMsg = shortMsg + ": " + longMsg;
10365        } else if (shortMsg != null) {
10366            longMsg = shortMsg;
10367        }
10368
10369        AppErrorResult result = new AppErrorResult();
10370        synchronized (this) {
10371            if (mController != null) {
10372                try {
10373                    String name = r != null ? r.processName : null;
10374                    int pid = r != null ? r.pid : Binder.getCallingPid();
10375                    if (!mController.appCrashed(name, pid,
10376                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10377                        Slog.w(TAG, "Force-killing crashed app " + name
10378                                + " at watcher's request");
10379                        Process.killProcess(pid);
10380                        return;
10381                    }
10382                } catch (RemoteException e) {
10383                    mController = null;
10384                    Watchdog.getInstance().setActivityController(null);
10385                }
10386            }
10387
10388            final long origId = Binder.clearCallingIdentity();
10389
10390            // If this process is running instrumentation, finish it.
10391            if (r != null && r.instrumentationClass != null) {
10392                Slog.w(TAG, "Error in app " + r.processName
10393                      + " running instrumentation " + r.instrumentationClass + ":");
10394                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10395                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10396                Bundle info = new Bundle();
10397                info.putString("shortMsg", shortMsg);
10398                info.putString("longMsg", longMsg);
10399                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10400                Binder.restoreCallingIdentity(origId);
10401                return;
10402            }
10403
10404            // If we can't identify the process or it's already exceeded its crash quota,
10405            // quit right away without showing a crash dialog.
10406            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10407                Binder.restoreCallingIdentity(origId);
10408                return;
10409            }
10410
10411            Message msg = Message.obtain();
10412            msg.what = SHOW_ERROR_MSG;
10413            HashMap data = new HashMap();
10414            data.put("result", result);
10415            data.put("app", r);
10416            msg.obj = data;
10417            mHandler.sendMessage(msg);
10418
10419            Binder.restoreCallingIdentity(origId);
10420        }
10421
10422        int res = result.get();
10423
10424        Intent appErrorIntent = null;
10425        synchronized (this) {
10426            if (r != null && !r.isolated) {
10427                // XXX Can't keep track of crash time for isolated processes,
10428                // since they don't have a persistent identity.
10429                mProcessCrashTimes.put(r.info.processName, r.uid,
10430                        SystemClock.uptimeMillis());
10431            }
10432            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10433                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10434            }
10435        }
10436
10437        if (appErrorIntent != null) {
10438            try {
10439                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10440            } catch (ActivityNotFoundException e) {
10441                Slog.w(TAG, "bug report receiver dissappeared", e);
10442            }
10443        }
10444    }
10445
10446    Intent createAppErrorIntentLocked(ProcessRecord r,
10447            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10448        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10449        if (report == null) {
10450            return null;
10451        }
10452        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10453        result.setComponent(r.errorReportReceiver);
10454        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10455        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10456        return result;
10457    }
10458
10459    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10460            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10461        if (r.errorReportReceiver == null) {
10462            return null;
10463        }
10464
10465        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10466            return null;
10467        }
10468
10469        ApplicationErrorReport report = new ApplicationErrorReport();
10470        report.packageName = r.info.packageName;
10471        report.installerPackageName = r.errorReportReceiver.getPackageName();
10472        report.processName = r.processName;
10473        report.time = timeMillis;
10474        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10475
10476        if (r.crashing || r.forceCrashReport) {
10477            report.type = ApplicationErrorReport.TYPE_CRASH;
10478            report.crashInfo = crashInfo;
10479        } else if (r.notResponding) {
10480            report.type = ApplicationErrorReport.TYPE_ANR;
10481            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10482
10483            report.anrInfo.activity = r.notRespondingReport.tag;
10484            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10485            report.anrInfo.info = r.notRespondingReport.longMsg;
10486        }
10487
10488        return report;
10489    }
10490
10491    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10492        enforceNotIsolatedCaller("getProcessesInErrorState");
10493        // assume our apps are happy - lazy create the list
10494        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10495
10496        final boolean allUsers = ActivityManager.checkUidPermission(
10497                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10498                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10499        int userId = UserHandle.getUserId(Binder.getCallingUid());
10500
10501        synchronized (this) {
10502
10503            // iterate across all processes
10504            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10505                ProcessRecord app = mLruProcesses.get(i);
10506                if (!allUsers && app.userId != userId) {
10507                    continue;
10508                }
10509                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10510                    // This one's in trouble, so we'll generate a report for it
10511                    // crashes are higher priority (in case there's a crash *and* an anr)
10512                    ActivityManager.ProcessErrorStateInfo report = null;
10513                    if (app.crashing) {
10514                        report = app.crashingReport;
10515                    } else if (app.notResponding) {
10516                        report = app.notRespondingReport;
10517                    }
10518
10519                    if (report != null) {
10520                        if (errList == null) {
10521                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10522                        }
10523                        errList.add(report);
10524                    } else {
10525                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10526                                " crashing = " + app.crashing +
10527                                " notResponding = " + app.notResponding);
10528                    }
10529                }
10530            }
10531        }
10532
10533        return errList;
10534    }
10535
10536    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10537        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10538            if (currApp != null) {
10539                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10540            }
10541            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10542        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10543            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10544        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10545            if (currApp != null) {
10546                currApp.lru = 0;
10547            }
10548            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10549        } else if (adj >= ProcessList.SERVICE_ADJ) {
10550            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10551        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10552            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10553        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10554            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10555        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10556            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10557        } else {
10558            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10559        }
10560    }
10561
10562    private void fillInProcMemInfo(ProcessRecord app,
10563            ActivityManager.RunningAppProcessInfo outInfo) {
10564        outInfo.pid = app.pid;
10565        outInfo.uid = app.info.uid;
10566        if (mHeavyWeightProcess == app) {
10567            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10568        }
10569        if (app.persistent) {
10570            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10571        }
10572        if (app.activities.size() > 0) {
10573            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10574        }
10575        outInfo.lastTrimLevel = app.trimMemoryLevel;
10576        int adj = app.curAdj;
10577        outInfo.importance = oomAdjToImportance(adj, outInfo);
10578        outInfo.importanceReasonCode = app.adjTypeCode;
10579    }
10580
10581    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10582        enforceNotIsolatedCaller("getRunningAppProcesses");
10583        // Lazy instantiation of list
10584        List<ActivityManager.RunningAppProcessInfo> runList = null;
10585        final boolean allUsers = ActivityManager.checkUidPermission(
10586                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10587                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10588        int userId = UserHandle.getUserId(Binder.getCallingUid());
10589        synchronized (this) {
10590            // Iterate across all processes
10591            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10592                ProcessRecord app = mLruProcesses.get(i);
10593                if (!allUsers && app.userId != userId) {
10594                    continue;
10595                }
10596                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10597                    // Generate process state info for running application
10598                    ActivityManager.RunningAppProcessInfo currApp =
10599                        new ActivityManager.RunningAppProcessInfo(app.processName,
10600                                app.pid, app.getPackageList());
10601                    fillInProcMemInfo(app, currApp);
10602                    if (app.adjSource instanceof ProcessRecord) {
10603                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10604                        currApp.importanceReasonImportance = oomAdjToImportance(
10605                                app.adjSourceOom, null);
10606                    } else if (app.adjSource instanceof ActivityRecord) {
10607                        ActivityRecord r = (ActivityRecord)app.adjSource;
10608                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10609                    }
10610                    if (app.adjTarget instanceof ComponentName) {
10611                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10612                    }
10613                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10614                    //        + " lru=" + currApp.lru);
10615                    if (runList == null) {
10616                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10617                    }
10618                    runList.add(currApp);
10619                }
10620            }
10621        }
10622        return runList;
10623    }
10624
10625    public List<ApplicationInfo> getRunningExternalApplications() {
10626        enforceNotIsolatedCaller("getRunningExternalApplications");
10627        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10628        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10629        if (runningApps != null && runningApps.size() > 0) {
10630            Set<String> extList = new HashSet<String>();
10631            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10632                if (app.pkgList != null) {
10633                    for (String pkg : app.pkgList) {
10634                        extList.add(pkg);
10635                    }
10636                }
10637            }
10638            IPackageManager pm = AppGlobals.getPackageManager();
10639            for (String pkg : extList) {
10640                try {
10641                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10642                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10643                        retList.add(info);
10644                    }
10645                } catch (RemoteException e) {
10646                }
10647            }
10648        }
10649        return retList;
10650    }
10651
10652    @Override
10653    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10654        enforceNotIsolatedCaller("getMyMemoryState");
10655        synchronized (this) {
10656            ProcessRecord proc;
10657            synchronized (mPidsSelfLocked) {
10658                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10659            }
10660            fillInProcMemInfo(proc, outInfo);
10661        }
10662    }
10663
10664    @Override
10665    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10666        if (checkCallingPermission(android.Manifest.permission.DUMP)
10667                != PackageManager.PERMISSION_GRANTED) {
10668            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10669                    + Binder.getCallingPid()
10670                    + ", uid=" + Binder.getCallingUid()
10671                    + " without permission "
10672                    + android.Manifest.permission.DUMP);
10673            return;
10674        }
10675
10676        boolean dumpAll = false;
10677        boolean dumpClient = false;
10678        String dumpPackage = null;
10679
10680        int opti = 0;
10681        while (opti < args.length) {
10682            String opt = args[opti];
10683            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10684                break;
10685            }
10686            opti++;
10687            if ("-a".equals(opt)) {
10688                dumpAll = true;
10689            } else if ("-c".equals(opt)) {
10690                dumpClient = true;
10691            } else if ("-h".equals(opt)) {
10692                pw.println("Activity manager dump options:");
10693                pw.println("  [-a] [-c] [-h] [cmd] ...");
10694                pw.println("  cmd may be one of:");
10695                pw.println("    a[ctivities]: activity stack state");
10696                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10697                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10698                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10699                pw.println("    o[om]: out of memory management");
10700                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10701                pw.println("    provider [COMP_SPEC]: provider client-side state");
10702                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10703                pw.println("    service [COMP_SPEC]: service client-side state");
10704                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10705                pw.println("    all: dump all activities");
10706                pw.println("    top: dump the top activity");
10707                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10708                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10709                pw.println("    a partial substring in a component name, a");
10710                pw.println("    hex object identifier.");
10711                pw.println("  -a: include all available server state.");
10712                pw.println("  -c: include client state.");
10713                return;
10714            } else {
10715                pw.println("Unknown argument: " + opt + "; use -h for help");
10716            }
10717        }
10718
10719        long origId = Binder.clearCallingIdentity();
10720        boolean more = false;
10721        // Is the caller requesting to dump a particular piece of data?
10722        if (opti < args.length) {
10723            String cmd = args[opti];
10724            opti++;
10725            if ("activities".equals(cmd) || "a".equals(cmd)) {
10726                synchronized (this) {
10727                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10728                }
10729            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10730                String[] newArgs;
10731                String name;
10732                if (opti >= args.length) {
10733                    name = null;
10734                    newArgs = EMPTY_STRING_ARRAY;
10735                } else {
10736                    name = args[opti];
10737                    opti++;
10738                    newArgs = new String[args.length - opti];
10739                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10740                            args.length - opti);
10741                }
10742                synchronized (this) {
10743                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10744                }
10745            } else if ("intents".equals(cmd) || "i".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,
10756                            args.length - opti);
10757                }
10758                synchronized (this) {
10759                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10760                }
10761            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10762                String[] newArgs;
10763                String name;
10764                if (opti >= args.length) {
10765                    name = null;
10766                    newArgs = EMPTY_STRING_ARRAY;
10767                } else {
10768                    name = args[opti];
10769                    opti++;
10770                    newArgs = new String[args.length - opti];
10771                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10772                            args.length - opti);
10773                }
10774                synchronized (this) {
10775                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10776                }
10777            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10778                synchronized (this) {
10779                    dumpOomLocked(fd, pw, args, opti, true);
10780                }
10781            } else if ("provider".equals(cmd)) {
10782                String[] newArgs;
10783                String name;
10784                if (opti >= args.length) {
10785                    name = null;
10786                    newArgs = EMPTY_STRING_ARRAY;
10787                } else {
10788                    name = args[opti];
10789                    opti++;
10790                    newArgs = new String[args.length - opti];
10791                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10792                }
10793                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10794                    pw.println("No providers match: " + name);
10795                    pw.println("Use -h for help.");
10796                }
10797            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10798                synchronized (this) {
10799                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10800                }
10801            } else if ("service".equals(cmd)) {
10802                String[] newArgs;
10803                String name;
10804                if (opti >= args.length) {
10805                    name = null;
10806                    newArgs = EMPTY_STRING_ARRAY;
10807                } else {
10808                    name = args[opti];
10809                    opti++;
10810                    newArgs = new String[args.length - opti];
10811                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10812                            args.length - opti);
10813                }
10814                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10815                    pw.println("No services match: " + name);
10816                    pw.println("Use -h for help.");
10817                }
10818            } else if ("package".equals(cmd)) {
10819                String[] newArgs;
10820                if (opti >= args.length) {
10821                    pw.println("package: no package name specified");
10822                    pw.println("Use -h for help.");
10823                } else {
10824                    dumpPackage = args[opti];
10825                    opti++;
10826                    newArgs = new String[args.length - opti];
10827                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10828                            args.length - opti);
10829                    args = newArgs;
10830                    opti = 0;
10831                    more = true;
10832                }
10833            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10834                synchronized (this) {
10835                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10836                }
10837            } else {
10838                // Dumping a single activity?
10839                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10840                    pw.println("Bad activity command, or no activities match: " + cmd);
10841                    pw.println("Use -h for help.");
10842                }
10843            }
10844            if (!more) {
10845                Binder.restoreCallingIdentity(origId);
10846                return;
10847            }
10848        }
10849
10850        // No piece of data specified, dump everything.
10851        synchronized (this) {
10852            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10853            pw.println();
10854            if (dumpAll) {
10855                pw.println("-------------------------------------------------------------------------------");
10856            }
10857            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10858            pw.println();
10859            if (dumpAll) {
10860                pw.println("-------------------------------------------------------------------------------");
10861            }
10862            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10863            pw.println();
10864            if (dumpAll) {
10865                pw.println("-------------------------------------------------------------------------------");
10866            }
10867            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10868            pw.println();
10869            if (dumpAll) {
10870                pw.println("-------------------------------------------------------------------------------");
10871            }
10872            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10873            pw.println();
10874            if (dumpAll) {
10875                pw.println("-------------------------------------------------------------------------------");
10876            }
10877            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10878        }
10879        Binder.restoreCallingIdentity(origId);
10880    }
10881
10882    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10883            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10884        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10885
10886        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10887                dumpPackage);
10888        boolean needSep = printedAnything;
10889
10890        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10891                dumpPackage, needSep, "  mFocusedActivity: ");
10892        if (printed) {
10893            printedAnything = true;
10894            needSep = false;
10895        }
10896
10897        if (dumpPackage == null) {
10898            if (needSep) {
10899                pw.println();
10900            }
10901            needSep = true;
10902            printedAnything = true;
10903            mStackSupervisor.dump(pw, "  ");
10904        }
10905
10906        if (mRecentTasks.size() > 0) {
10907            boolean printedHeader = false;
10908
10909            final int N = mRecentTasks.size();
10910            for (int i=0; i<N; i++) {
10911                TaskRecord tr = mRecentTasks.get(i);
10912                if (dumpPackage != null) {
10913                    if (tr.realActivity == null ||
10914                            !dumpPackage.equals(tr.realActivity)) {
10915                        continue;
10916                    }
10917                }
10918                if (!printedHeader) {
10919                    if (needSep) {
10920                        pw.println();
10921                    }
10922                    pw.println("  Recent tasks:");
10923                    printedHeader = true;
10924                    printedAnything = true;
10925                }
10926                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10927                        pw.println(tr);
10928                if (dumpAll) {
10929                    mRecentTasks.get(i).dump(pw, "    ");
10930                }
10931            }
10932        }
10933
10934        if (!printedAnything) {
10935            pw.println("  (nothing)");
10936        }
10937    }
10938
10939    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10940            int opti, boolean dumpAll, String dumpPackage) {
10941        boolean needSep = false;
10942        boolean printedAnything = false;
10943        int numPers = 0;
10944
10945        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10946
10947        if (dumpAll) {
10948            final int NP = mProcessNames.getMap().size();
10949            for (int ip=0; ip<NP; ip++) {
10950                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10951                final int NA = procs.size();
10952                for (int ia=0; ia<NA; ia++) {
10953                    ProcessRecord r = procs.valueAt(ia);
10954                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10955                        continue;
10956                    }
10957                    if (!needSep) {
10958                        pw.println("  All known processes:");
10959                        needSep = true;
10960                        printedAnything = true;
10961                    }
10962                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10963                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10964                        pw.print(" "); pw.println(r);
10965                    r.dump(pw, "    ");
10966                    if (r.persistent) {
10967                        numPers++;
10968                    }
10969                }
10970            }
10971        }
10972
10973        if (mIsolatedProcesses.size() > 0) {
10974            boolean printed = false;
10975            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10976                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10977                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10978                    continue;
10979                }
10980                if (!printed) {
10981                    if (needSep) {
10982                        pw.println();
10983                    }
10984                    pw.println("  Isolated process list (sorted by uid):");
10985                    printedAnything = true;
10986                    printed = true;
10987                    needSep = true;
10988                }
10989                pw.println(String.format("%sIsolated #%2d: %s",
10990                        "    ", i, r.toString()));
10991            }
10992        }
10993
10994        if (mLruProcesses.size() > 0) {
10995            if (needSep) {
10996                pw.println();
10997            }
10998            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10999                    pw.print(" total, non-act at ");
11000                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11001                    pw.print(", non-svc at ");
11002                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11003                    pw.println("):");
11004            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11005            needSep = true;
11006            printedAnything = true;
11007        }
11008
11009        if (dumpAll || dumpPackage != null) {
11010            synchronized (mPidsSelfLocked) {
11011                boolean printed = false;
11012                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11013                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11014                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11015                        continue;
11016                    }
11017                    if (!printed) {
11018                        if (needSep) pw.println();
11019                        needSep = true;
11020                        pw.println("  PID mappings:");
11021                        printed = true;
11022                        printedAnything = true;
11023                    }
11024                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11025                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11026                }
11027            }
11028        }
11029
11030        if (mForegroundProcesses.size() > 0) {
11031            synchronized (mPidsSelfLocked) {
11032                boolean printed = false;
11033                for (int i=0; i<mForegroundProcesses.size(); i++) {
11034                    ProcessRecord r = mPidsSelfLocked.get(
11035                            mForegroundProcesses.valueAt(i).pid);
11036                    if (dumpPackage != null && (r == null
11037                            || !r.pkgList.containsKey(dumpPackage))) {
11038                        continue;
11039                    }
11040                    if (!printed) {
11041                        if (needSep) pw.println();
11042                        needSep = true;
11043                        pw.println("  Foreground Processes:");
11044                        printed = true;
11045                        printedAnything = true;
11046                    }
11047                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11048                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11049                }
11050            }
11051        }
11052
11053        if (mPersistentStartingProcesses.size() > 0) {
11054            if (needSep) pw.println();
11055            needSep = true;
11056            printedAnything = true;
11057            pw.println("  Persisent processes that are starting:");
11058            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11059                    "Starting Norm", "Restarting PERS", dumpPackage);
11060        }
11061
11062        if (mRemovedProcesses.size() > 0) {
11063            if (needSep) pw.println();
11064            needSep = true;
11065            printedAnything = true;
11066            pw.println("  Processes that are being removed:");
11067            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11068                    "Removed Norm", "Removed PERS", dumpPackage);
11069        }
11070
11071        if (mProcessesOnHold.size() > 0) {
11072            if (needSep) pw.println();
11073            needSep = true;
11074            printedAnything = true;
11075            pw.println("  Processes that are on old until the system is ready:");
11076            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11077                    "OnHold Norm", "OnHold PERS", dumpPackage);
11078        }
11079
11080        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11081
11082        if (mProcessCrashTimes.getMap().size() > 0) {
11083            boolean printed = false;
11084            long now = SystemClock.uptimeMillis();
11085            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11086            final int NP = pmap.size();
11087            for (int ip=0; ip<NP; ip++) {
11088                String pname = pmap.keyAt(ip);
11089                SparseArray<Long> uids = pmap.valueAt(ip);
11090                final int N = uids.size();
11091                for (int i=0; i<N; i++) {
11092                    int puid = uids.keyAt(i);
11093                    ProcessRecord r = mProcessNames.get(pname, puid);
11094                    if (dumpPackage != null && (r == null
11095                            || !r.pkgList.containsKey(dumpPackage))) {
11096                        continue;
11097                    }
11098                    if (!printed) {
11099                        if (needSep) pw.println();
11100                        needSep = true;
11101                        pw.println("  Time since processes crashed:");
11102                        printed = true;
11103                        printedAnything = true;
11104                    }
11105                    pw.print("    Process "); pw.print(pname);
11106                            pw.print(" uid "); pw.print(puid);
11107                            pw.print(": last crashed ");
11108                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11109                            pw.println(" ago");
11110                }
11111            }
11112        }
11113
11114        if (mBadProcesses.getMap().size() > 0) {
11115            boolean printed = false;
11116            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11117            final int NP = pmap.size();
11118            for (int ip=0; ip<NP; ip++) {
11119                String pname = pmap.keyAt(ip);
11120                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11121                final int N = uids.size();
11122                for (int i=0; i<N; i++) {
11123                    int puid = uids.keyAt(i);
11124                    ProcessRecord r = mProcessNames.get(pname, puid);
11125                    if (dumpPackage != null && (r == null
11126                            || !r.pkgList.containsKey(dumpPackage))) {
11127                        continue;
11128                    }
11129                    if (!printed) {
11130                        if (needSep) pw.println();
11131                        needSep = true;
11132                        pw.println("  Bad processes:");
11133                        printedAnything = true;
11134                    }
11135                    BadProcessInfo info = uids.valueAt(i);
11136                    pw.print("    Bad process "); pw.print(pname);
11137                            pw.print(" uid "); pw.print(puid);
11138                            pw.print(": crashed at time "); pw.println(info.time);
11139                    if (info.shortMsg != null) {
11140                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11141                    }
11142                    if (info.longMsg != null) {
11143                        pw.print("      Long msg: "); pw.println(info.longMsg);
11144                    }
11145                    if (info.stack != null) {
11146                        pw.println("      Stack:");
11147                        int lastPos = 0;
11148                        for (int pos=0; pos<info.stack.length(); pos++) {
11149                            if (info.stack.charAt(pos) == '\n') {
11150                                pw.print("        ");
11151                                pw.write(info.stack, lastPos, pos-lastPos);
11152                                pw.println();
11153                                lastPos = pos+1;
11154                            }
11155                        }
11156                        if (lastPos < info.stack.length()) {
11157                            pw.print("        ");
11158                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11159                            pw.println();
11160                        }
11161                    }
11162                }
11163            }
11164        }
11165
11166        if (dumpPackage == null) {
11167            pw.println();
11168            needSep = false;
11169            pw.println("  mStartedUsers:");
11170            for (int i=0; i<mStartedUsers.size(); i++) {
11171                UserStartedState uss = mStartedUsers.valueAt(i);
11172                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11173                        pw.print(": "); uss.dump("", pw);
11174            }
11175            pw.print("  mStartedUserArray: [");
11176            for (int i=0; i<mStartedUserArray.length; i++) {
11177                if (i > 0) pw.print(", ");
11178                pw.print(mStartedUserArray[i]);
11179            }
11180            pw.println("]");
11181            pw.print("  mUserLru: [");
11182            for (int i=0; i<mUserLru.size(); i++) {
11183                if (i > 0) pw.print(", ");
11184                pw.print(mUserLru.get(i));
11185            }
11186            pw.println("]");
11187            if (dumpAll) {
11188                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11189            }
11190        }
11191        if (mHomeProcess != null && (dumpPackage == null
11192                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11193            if (needSep) {
11194                pw.println();
11195                needSep = false;
11196            }
11197            pw.println("  mHomeProcess: " + mHomeProcess);
11198        }
11199        if (mPreviousProcess != null && (dumpPackage == null
11200                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11201            if (needSep) {
11202                pw.println();
11203                needSep = false;
11204            }
11205            pw.println("  mPreviousProcess: " + mPreviousProcess);
11206        }
11207        if (dumpAll) {
11208            StringBuilder sb = new StringBuilder(128);
11209            sb.append("  mPreviousProcessVisibleTime: ");
11210            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11211            pw.println(sb);
11212        }
11213        if (mHeavyWeightProcess != null && (dumpPackage == null
11214                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11215            if (needSep) {
11216                pw.println();
11217                needSep = false;
11218            }
11219            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11220        }
11221        if (dumpPackage == null) {
11222            pw.println("  mConfiguration: " + mConfiguration);
11223        }
11224        if (dumpAll) {
11225            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11226            if (mCompatModePackages.getPackages().size() > 0) {
11227                boolean printed = false;
11228                for (Map.Entry<String, Integer> entry
11229                        : mCompatModePackages.getPackages().entrySet()) {
11230                    String pkg = entry.getKey();
11231                    int mode = entry.getValue();
11232                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11233                        continue;
11234                    }
11235                    if (!printed) {
11236                        pw.println("  mScreenCompatPackages:");
11237                        printed = true;
11238                    }
11239                    pw.print("    "); pw.print(pkg); pw.print(": ");
11240                            pw.print(mode); pw.println();
11241                }
11242            }
11243        }
11244        if (dumpPackage == null) {
11245            if (mSleeping || mWentToSleep || mLockScreenShown) {
11246                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11247                        + " mLockScreenShown " + mLockScreenShown);
11248            }
11249            if (mShuttingDown || mRunningVoice) {
11250                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11251            }
11252        }
11253        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11254                || mOrigWaitForDebugger) {
11255            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11256                    || dumpPackage.equals(mOrigDebugApp)) {
11257                if (needSep) {
11258                    pw.println();
11259                    needSep = false;
11260                }
11261                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11262                        + " mDebugTransient=" + mDebugTransient
11263                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11264            }
11265        }
11266        if (mOpenGlTraceApp != null) {
11267            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11268                if (needSep) {
11269                    pw.println();
11270                    needSep = false;
11271                }
11272                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11273            }
11274        }
11275        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11276                || mProfileFd != null) {
11277            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11278                if (needSep) {
11279                    pw.println();
11280                    needSep = false;
11281                }
11282                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11283                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11284                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11285                        + mAutoStopProfiler);
11286            }
11287        }
11288        if (dumpPackage == null) {
11289            if (mAlwaysFinishActivities || mController != null) {
11290                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11291                        + " mController=" + mController);
11292            }
11293            if (dumpAll) {
11294                pw.println("  Total persistent processes: " + numPers);
11295                pw.println("  mProcessesReady=" + mProcessesReady
11296                        + " mSystemReady=" + mSystemReady);
11297                pw.println("  mBooting=" + mBooting
11298                        + " mBooted=" + mBooted
11299                        + " mFactoryTest=" + mFactoryTest);
11300                pw.print("  mLastPowerCheckRealtime=");
11301                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11302                        pw.println("");
11303                pw.print("  mLastPowerCheckUptime=");
11304                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11305                        pw.println("");
11306                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11307                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11308                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11309                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11310                        + " (" + mLruProcesses.size() + " total)"
11311                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11312                        + " mNumServiceProcs=" + mNumServiceProcs
11313                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11314                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11315                        + " mLastMemoryLevel" + mLastMemoryLevel
11316                        + " mLastNumProcesses" + mLastNumProcesses);
11317                long now = SystemClock.uptimeMillis();
11318                pw.print("  mLastIdleTime=");
11319                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11320                        pw.print(" mLowRamSinceLastIdle=");
11321                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11322                        pw.println();
11323            }
11324        }
11325
11326        if (!printedAnything) {
11327            pw.println("  (nothing)");
11328        }
11329    }
11330
11331    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11332            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11333        if (mProcessesToGc.size() > 0) {
11334            boolean printed = false;
11335            long now = SystemClock.uptimeMillis();
11336            for (int i=0; i<mProcessesToGc.size(); i++) {
11337                ProcessRecord proc = mProcessesToGc.get(i);
11338                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11339                    continue;
11340                }
11341                if (!printed) {
11342                    if (needSep) pw.println();
11343                    needSep = true;
11344                    pw.println("  Processes that are waiting to GC:");
11345                    printed = true;
11346                }
11347                pw.print("    Process "); pw.println(proc);
11348                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11349                        pw.print(", last gced=");
11350                        pw.print(now-proc.lastRequestedGc);
11351                        pw.print(" ms ago, last lowMem=");
11352                        pw.print(now-proc.lastLowMemory);
11353                        pw.println(" ms ago");
11354
11355            }
11356        }
11357        return needSep;
11358    }
11359
11360    void printOomLevel(PrintWriter pw, String name, int adj) {
11361        pw.print("    ");
11362        if (adj >= 0) {
11363            pw.print(' ');
11364            if (adj < 10) pw.print(' ');
11365        } else {
11366            if (adj > -10) pw.print(' ');
11367        }
11368        pw.print(adj);
11369        pw.print(": ");
11370        pw.print(name);
11371        pw.print(" (");
11372        pw.print(mProcessList.getMemLevel(adj)/1024);
11373        pw.println(" kB)");
11374    }
11375
11376    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11377            int opti, boolean dumpAll) {
11378        boolean needSep = false;
11379
11380        if (mLruProcesses.size() > 0) {
11381            if (needSep) pw.println();
11382            needSep = true;
11383            pw.println("  OOM levels:");
11384            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11385            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11386            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11387            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11388            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11389            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11390            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11391            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11392            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11393            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11394            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11395            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11396            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11397
11398            if (needSep) pw.println();
11399            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11400                    pw.print(" total, non-act at ");
11401                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11402                    pw.print(", non-svc at ");
11403                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11404                    pw.println("):");
11405            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11406            needSep = true;
11407        }
11408
11409        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11410
11411        pw.println();
11412        pw.println("  mHomeProcess: " + mHomeProcess);
11413        pw.println("  mPreviousProcess: " + mPreviousProcess);
11414        if (mHeavyWeightProcess != null) {
11415            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11416        }
11417
11418        return true;
11419    }
11420
11421    /**
11422     * There are three ways to call this:
11423     *  - no provider specified: dump all the providers
11424     *  - a flattened component name that matched an existing provider was specified as the
11425     *    first arg: dump that one provider
11426     *  - the first arg isn't the flattened component name of an existing provider:
11427     *    dump all providers whose component contains the first arg as a substring
11428     */
11429    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11430            int opti, boolean dumpAll) {
11431        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11432    }
11433
11434    static class ItemMatcher {
11435        ArrayList<ComponentName> components;
11436        ArrayList<String> strings;
11437        ArrayList<Integer> objects;
11438        boolean all;
11439
11440        ItemMatcher() {
11441            all = true;
11442        }
11443
11444        void build(String name) {
11445            ComponentName componentName = ComponentName.unflattenFromString(name);
11446            if (componentName != null) {
11447                if (components == null) {
11448                    components = new ArrayList<ComponentName>();
11449                }
11450                components.add(componentName);
11451                all = false;
11452            } else {
11453                int objectId = 0;
11454                // Not a '/' separated full component name; maybe an object ID?
11455                try {
11456                    objectId = Integer.parseInt(name, 16);
11457                    if (objects == null) {
11458                        objects = new ArrayList<Integer>();
11459                    }
11460                    objects.add(objectId);
11461                    all = false;
11462                } catch (RuntimeException e) {
11463                    // Not an integer; just do string match.
11464                    if (strings == null) {
11465                        strings = new ArrayList<String>();
11466                    }
11467                    strings.add(name);
11468                    all = false;
11469                }
11470            }
11471        }
11472
11473        int build(String[] args, int opti) {
11474            for (; opti<args.length; opti++) {
11475                String name = args[opti];
11476                if ("--".equals(name)) {
11477                    return opti+1;
11478                }
11479                build(name);
11480            }
11481            return opti;
11482        }
11483
11484        boolean match(Object object, ComponentName comp) {
11485            if (all) {
11486                return true;
11487            }
11488            if (components != null) {
11489                for (int i=0; i<components.size(); i++) {
11490                    if (components.get(i).equals(comp)) {
11491                        return true;
11492                    }
11493                }
11494            }
11495            if (objects != null) {
11496                for (int i=0; i<objects.size(); i++) {
11497                    if (System.identityHashCode(object) == objects.get(i)) {
11498                        return true;
11499                    }
11500                }
11501            }
11502            if (strings != null) {
11503                String flat = comp.flattenToString();
11504                for (int i=0; i<strings.size(); i++) {
11505                    if (flat.contains(strings.get(i))) {
11506                        return true;
11507                    }
11508                }
11509            }
11510            return false;
11511        }
11512    }
11513
11514    /**
11515     * There are three things that cmd can be:
11516     *  - a flattened component name that matches an existing activity
11517     *  - the cmd arg isn't the flattened component name of an existing activity:
11518     *    dump all activity whose component contains the cmd as a substring
11519     *  - A hex number of the ActivityRecord object instance.
11520     */
11521    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11522            int opti, boolean dumpAll) {
11523        ArrayList<ActivityRecord> activities;
11524
11525        synchronized (this) {
11526            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11527        }
11528
11529        if (activities.size() <= 0) {
11530            return false;
11531        }
11532
11533        String[] newArgs = new String[args.length - opti];
11534        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11535
11536        TaskRecord lastTask = null;
11537        boolean needSep = false;
11538        for (int i=activities.size()-1; i>=0; i--) {
11539            ActivityRecord r = activities.get(i);
11540            if (needSep) {
11541                pw.println();
11542            }
11543            needSep = true;
11544            synchronized (this) {
11545                if (lastTask != r.task) {
11546                    lastTask = r.task;
11547                    pw.print("TASK "); pw.print(lastTask.affinity);
11548                            pw.print(" id="); pw.println(lastTask.taskId);
11549                    if (dumpAll) {
11550                        lastTask.dump(pw, "  ");
11551                    }
11552                }
11553            }
11554            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11555        }
11556        return true;
11557    }
11558
11559    /**
11560     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11561     * there is a thread associated with the activity.
11562     */
11563    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11564            final ActivityRecord r, String[] args, boolean dumpAll) {
11565        String innerPrefix = prefix + "  ";
11566        synchronized (this) {
11567            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11568                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11569                    pw.print(" pid=");
11570                    if (r.app != null) pw.println(r.app.pid);
11571                    else pw.println("(not running)");
11572            if (dumpAll) {
11573                r.dump(pw, innerPrefix);
11574            }
11575        }
11576        if (r.app != null && r.app.thread != null) {
11577            // flush anything that is already in the PrintWriter since the thread is going
11578            // to write to the file descriptor directly
11579            pw.flush();
11580            try {
11581                TransferPipe tp = new TransferPipe();
11582                try {
11583                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11584                            r.appToken, innerPrefix, args);
11585                    tp.go(fd);
11586                } finally {
11587                    tp.kill();
11588                }
11589            } catch (IOException e) {
11590                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11591            } catch (RemoteException e) {
11592                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11593            }
11594        }
11595    }
11596
11597    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11598            int opti, boolean dumpAll, String dumpPackage) {
11599        boolean needSep = false;
11600        boolean onlyHistory = false;
11601        boolean printedAnything = false;
11602
11603        if ("history".equals(dumpPackage)) {
11604            if (opti < args.length && "-s".equals(args[opti])) {
11605                dumpAll = false;
11606            }
11607            onlyHistory = true;
11608            dumpPackage = null;
11609        }
11610
11611        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11612        if (!onlyHistory && dumpAll) {
11613            if (mRegisteredReceivers.size() > 0) {
11614                boolean printed = false;
11615                Iterator it = mRegisteredReceivers.values().iterator();
11616                while (it.hasNext()) {
11617                    ReceiverList r = (ReceiverList)it.next();
11618                    if (dumpPackage != null && (r.app == null ||
11619                            !dumpPackage.equals(r.app.info.packageName))) {
11620                        continue;
11621                    }
11622                    if (!printed) {
11623                        pw.println("  Registered Receivers:");
11624                        needSep = true;
11625                        printed = true;
11626                        printedAnything = true;
11627                    }
11628                    pw.print("  * "); pw.println(r);
11629                    r.dump(pw, "    ");
11630                }
11631            }
11632
11633            if (mReceiverResolver.dump(pw, needSep ?
11634                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11635                    "    ", dumpPackage, false)) {
11636                needSep = true;
11637                printedAnything = true;
11638            }
11639        }
11640
11641        for (BroadcastQueue q : mBroadcastQueues) {
11642            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11643            printedAnything |= needSep;
11644        }
11645
11646        needSep = true;
11647
11648        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11649            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11650                if (needSep) {
11651                    pw.println();
11652                }
11653                needSep = true;
11654                printedAnything = true;
11655                pw.print("  Sticky broadcasts for user ");
11656                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11657                StringBuilder sb = new StringBuilder(128);
11658                for (Map.Entry<String, ArrayList<Intent>> ent
11659                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11660                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11661                    if (dumpAll) {
11662                        pw.println(":");
11663                        ArrayList<Intent> intents = ent.getValue();
11664                        final int N = intents.size();
11665                        for (int i=0; i<N; i++) {
11666                            sb.setLength(0);
11667                            sb.append("    Intent: ");
11668                            intents.get(i).toShortString(sb, false, true, false, false);
11669                            pw.println(sb.toString());
11670                            Bundle bundle = intents.get(i).getExtras();
11671                            if (bundle != null) {
11672                                pw.print("      ");
11673                                pw.println(bundle.toString());
11674                            }
11675                        }
11676                    } else {
11677                        pw.println("");
11678                    }
11679                }
11680            }
11681        }
11682
11683        if (!onlyHistory && dumpAll) {
11684            pw.println();
11685            for (BroadcastQueue queue : mBroadcastQueues) {
11686                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11687                        + queue.mBroadcastsScheduled);
11688            }
11689            pw.println("  mHandler:");
11690            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11691            needSep = true;
11692            printedAnything = true;
11693        }
11694
11695        if (!printedAnything) {
11696            pw.println("  (nothing)");
11697        }
11698    }
11699
11700    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11701            int opti, boolean dumpAll, String dumpPackage) {
11702        boolean needSep;
11703        boolean printedAnything = false;
11704
11705        ItemMatcher matcher = new ItemMatcher();
11706        matcher.build(args, opti);
11707
11708        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11709
11710        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11711        printedAnything |= needSep;
11712
11713        if (mLaunchingProviders.size() > 0) {
11714            boolean printed = false;
11715            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11716                ContentProviderRecord r = mLaunchingProviders.get(i);
11717                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11718                    continue;
11719                }
11720                if (!printed) {
11721                    if (needSep) pw.println();
11722                    needSep = true;
11723                    pw.println("  Launching content providers:");
11724                    printed = true;
11725                    printedAnything = true;
11726                }
11727                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11728                        pw.println(r);
11729            }
11730        }
11731
11732        if (mGrantedUriPermissions.size() > 0) {
11733            boolean printed = false;
11734            int dumpUid = -2;
11735            if (dumpPackage != null) {
11736                try {
11737                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11738                } catch (NameNotFoundException e) {
11739                    dumpUid = -1;
11740                }
11741            }
11742            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11743                int uid = mGrantedUriPermissions.keyAt(i);
11744                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11745                    continue;
11746                }
11747                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11748                if (!printed) {
11749                    if (needSep) pw.println();
11750                    needSep = true;
11751                    pw.println("  Granted Uri Permissions:");
11752                    printed = true;
11753                    printedAnything = true;
11754                }
11755                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11756                for (UriPermission perm : perms.values()) {
11757                    pw.print("    "); pw.println(perm);
11758                    if (dumpAll) {
11759                        perm.dump(pw, "      ");
11760                    }
11761                }
11762            }
11763        }
11764
11765        if (!printedAnything) {
11766            pw.println("  (nothing)");
11767        }
11768    }
11769
11770    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11771            int opti, boolean dumpAll, String dumpPackage) {
11772        boolean printed = false;
11773
11774        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11775
11776        if (mIntentSenderRecords.size() > 0) {
11777            Iterator<WeakReference<PendingIntentRecord>> it
11778                    = mIntentSenderRecords.values().iterator();
11779            while (it.hasNext()) {
11780                WeakReference<PendingIntentRecord> ref = it.next();
11781                PendingIntentRecord rec = ref != null ? ref.get(): null;
11782                if (dumpPackage != null && (rec == null
11783                        || !dumpPackage.equals(rec.key.packageName))) {
11784                    continue;
11785                }
11786                printed = true;
11787                if (rec != null) {
11788                    pw.print("  * "); pw.println(rec);
11789                    if (dumpAll) {
11790                        rec.dump(pw, "    ");
11791                    }
11792                } else {
11793                    pw.print("  * "); pw.println(ref);
11794                }
11795            }
11796        }
11797
11798        if (!printed) {
11799            pw.println("  (nothing)");
11800        }
11801    }
11802
11803    private static final int dumpProcessList(PrintWriter pw,
11804            ActivityManagerService service, List list,
11805            String prefix, String normalLabel, String persistentLabel,
11806            String dumpPackage) {
11807        int numPers = 0;
11808        final int N = list.size()-1;
11809        for (int i=N; i>=0; i--) {
11810            ProcessRecord r = (ProcessRecord)list.get(i);
11811            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11812                continue;
11813            }
11814            pw.println(String.format("%s%s #%2d: %s",
11815                    prefix, (r.persistent ? persistentLabel : normalLabel),
11816                    i, r.toString()));
11817            if (r.persistent) {
11818                numPers++;
11819            }
11820        }
11821        return numPers;
11822    }
11823
11824    private static final boolean dumpProcessOomList(PrintWriter pw,
11825            ActivityManagerService service, List<ProcessRecord> origList,
11826            String prefix, String normalLabel, String persistentLabel,
11827            boolean inclDetails, String dumpPackage) {
11828
11829        ArrayList<Pair<ProcessRecord, Integer>> list
11830                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11831        for (int i=0; i<origList.size(); i++) {
11832            ProcessRecord r = origList.get(i);
11833            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11834                continue;
11835            }
11836            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11837        }
11838
11839        if (list.size() <= 0) {
11840            return false;
11841        }
11842
11843        Comparator<Pair<ProcessRecord, Integer>> comparator
11844                = new Comparator<Pair<ProcessRecord, Integer>>() {
11845            @Override
11846            public int compare(Pair<ProcessRecord, Integer> object1,
11847                    Pair<ProcessRecord, Integer> object2) {
11848                if (object1.first.setAdj != object2.first.setAdj) {
11849                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11850                }
11851                if (object1.second.intValue() != object2.second.intValue()) {
11852                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11853                }
11854                return 0;
11855            }
11856        };
11857
11858        Collections.sort(list, comparator);
11859
11860        final long curRealtime = SystemClock.elapsedRealtime();
11861        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11862        final long curUptime = SystemClock.uptimeMillis();
11863        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11864
11865        for (int i=list.size()-1; i>=0; i--) {
11866            ProcessRecord r = list.get(i).first;
11867            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11868            char schedGroup;
11869            switch (r.setSchedGroup) {
11870                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11871                    schedGroup = 'B';
11872                    break;
11873                case Process.THREAD_GROUP_DEFAULT:
11874                    schedGroup = 'F';
11875                    break;
11876                default:
11877                    schedGroup = '?';
11878                    break;
11879            }
11880            char foreground;
11881            if (r.foregroundActivities) {
11882                foreground = 'A';
11883            } else if (r.foregroundServices) {
11884                foreground = 'S';
11885            } else {
11886                foreground = ' ';
11887            }
11888            String procState = ProcessList.makeProcStateString(r.curProcState);
11889            pw.print(prefix);
11890            pw.print(r.persistent ? persistentLabel : normalLabel);
11891            pw.print(" #");
11892            int num = (origList.size()-1)-list.get(i).second;
11893            if (num < 10) pw.print(' ');
11894            pw.print(num);
11895            pw.print(": ");
11896            pw.print(oomAdj);
11897            pw.print(' ');
11898            pw.print(schedGroup);
11899            pw.print('/');
11900            pw.print(foreground);
11901            pw.print('/');
11902            pw.print(procState);
11903            pw.print(" trm:");
11904            if (r.trimMemoryLevel < 10) pw.print(' ');
11905            pw.print(r.trimMemoryLevel);
11906            pw.print(' ');
11907            pw.print(r.toShortString());
11908            pw.print(" (");
11909            pw.print(r.adjType);
11910            pw.println(')');
11911            if (r.adjSource != null || r.adjTarget != null) {
11912                pw.print(prefix);
11913                pw.print("    ");
11914                if (r.adjTarget instanceof ComponentName) {
11915                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11916                } else if (r.adjTarget != null) {
11917                    pw.print(r.adjTarget.toString());
11918                } else {
11919                    pw.print("{null}");
11920                }
11921                pw.print("<=");
11922                if (r.adjSource instanceof ProcessRecord) {
11923                    pw.print("Proc{");
11924                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11925                    pw.println("}");
11926                } else if (r.adjSource != null) {
11927                    pw.println(r.adjSource.toString());
11928                } else {
11929                    pw.println("{null}");
11930                }
11931            }
11932            if (inclDetails) {
11933                pw.print(prefix);
11934                pw.print("    ");
11935                pw.print("oom: max="); pw.print(r.maxAdj);
11936                pw.print(" curRaw="); pw.print(r.curRawAdj);
11937                pw.print(" setRaw="); pw.print(r.setRawAdj);
11938                pw.print(" cur="); pw.print(r.curAdj);
11939                pw.print(" set="); pw.println(r.setAdj);
11940                pw.print(prefix);
11941                pw.print("    ");
11942                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11943                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11944                pw.print(" lastPss="); pw.print(r.lastPss);
11945                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11946                pw.print(prefix);
11947                pw.print("    ");
11948                pw.print("keeping="); pw.print(r.keeping);
11949                pw.print(" cached="); pw.print(r.cached);
11950                pw.print(" empty="); pw.print(r.empty);
11951                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11952
11953                if (!r.keeping) {
11954                    if (r.lastWakeTime != 0) {
11955                        long wtime;
11956                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11957                        synchronized (stats) {
11958                            wtime = stats.getProcessWakeTime(r.info.uid,
11959                                    r.pid, curRealtime);
11960                        }
11961                        long timeUsed = wtime - r.lastWakeTime;
11962                        pw.print(prefix);
11963                        pw.print("    ");
11964                        pw.print("keep awake over ");
11965                        TimeUtils.formatDuration(realtimeSince, pw);
11966                        pw.print(" used ");
11967                        TimeUtils.formatDuration(timeUsed, pw);
11968                        pw.print(" (");
11969                        pw.print((timeUsed*100)/realtimeSince);
11970                        pw.println("%)");
11971                    }
11972                    if (r.lastCpuTime != 0) {
11973                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11974                        pw.print(prefix);
11975                        pw.print("    ");
11976                        pw.print("run cpu over ");
11977                        TimeUtils.formatDuration(uptimeSince, pw);
11978                        pw.print(" used ");
11979                        TimeUtils.formatDuration(timeUsed, pw);
11980                        pw.print(" (");
11981                        pw.print((timeUsed*100)/uptimeSince);
11982                        pw.println("%)");
11983                    }
11984                }
11985            }
11986        }
11987        return true;
11988    }
11989
11990    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11991        ArrayList<ProcessRecord> procs;
11992        synchronized (this) {
11993            if (args != null && args.length > start
11994                    && args[start].charAt(0) != '-') {
11995                procs = new ArrayList<ProcessRecord>();
11996                int pid = -1;
11997                try {
11998                    pid = Integer.parseInt(args[start]);
11999                } catch (NumberFormatException e) {
12000                }
12001                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12002                    ProcessRecord proc = mLruProcesses.get(i);
12003                    if (proc.pid == pid) {
12004                        procs.add(proc);
12005                    } else if (proc.processName.equals(args[start])) {
12006                        procs.add(proc);
12007                    }
12008                }
12009                if (procs.size() <= 0) {
12010                    return null;
12011                }
12012            } else {
12013                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12014            }
12015        }
12016        return procs;
12017    }
12018
12019    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12020            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        long uptime = SystemClock.uptimeMillis();
12028        long realtime = SystemClock.elapsedRealtime();
12029        pw.println("Applications Graphics Acceleration Info:");
12030        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12031
12032        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12033            ProcessRecord r = procs.get(i);
12034            if (r.thread != null) {
12035                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12036                pw.flush();
12037                try {
12038                    TransferPipe tp = new TransferPipe();
12039                    try {
12040                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12041                        tp.go(fd);
12042                    } finally {
12043                        tp.kill();
12044                    }
12045                } catch (IOException e) {
12046                    pw.println("Failure while dumping the app: " + r);
12047                    pw.flush();
12048                } catch (RemoteException e) {
12049                    pw.println("Got a RemoteException while dumping the app " + r);
12050                    pw.flush();
12051                }
12052            }
12053        }
12054    }
12055
12056    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12057        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12058        if (procs == null) {
12059            pw.println("No process found for: " + args[0]);
12060            return;
12061        }
12062
12063        pw.println("Applications Database Info:");
12064
12065        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12066            ProcessRecord r = procs.get(i);
12067            if (r.thread != null) {
12068                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12069                pw.flush();
12070                try {
12071                    TransferPipe tp = new TransferPipe();
12072                    try {
12073                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12074                        tp.go(fd);
12075                    } finally {
12076                        tp.kill();
12077                    }
12078                } catch (IOException e) {
12079                    pw.println("Failure while dumping the app: " + r);
12080                    pw.flush();
12081                } catch (RemoteException e) {
12082                    pw.println("Got a RemoteException while dumping the app " + r);
12083                    pw.flush();
12084                }
12085            }
12086        }
12087    }
12088
12089    final static class MemItem {
12090        final boolean isProc;
12091        final String label;
12092        final String shortLabel;
12093        final long pss;
12094        final int id;
12095        final boolean hasActivities;
12096        ArrayList<MemItem> subitems;
12097
12098        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12099                boolean _hasActivities) {
12100            isProc = true;
12101            label = _label;
12102            shortLabel = _shortLabel;
12103            pss = _pss;
12104            id = _id;
12105            hasActivities = _hasActivities;
12106        }
12107
12108        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12109            isProc = false;
12110            label = _label;
12111            shortLabel = _shortLabel;
12112            pss = _pss;
12113            id = _id;
12114            hasActivities = false;
12115        }
12116    }
12117
12118    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12119            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12120        if (sort && !isCompact) {
12121            Collections.sort(items, new Comparator<MemItem>() {
12122                @Override
12123                public int compare(MemItem lhs, MemItem rhs) {
12124                    if (lhs.pss < rhs.pss) {
12125                        return 1;
12126                    } else if (lhs.pss > rhs.pss) {
12127                        return -1;
12128                    }
12129                    return 0;
12130                }
12131            });
12132        }
12133
12134        for (int i=0; i<items.size(); i++) {
12135            MemItem mi = items.get(i);
12136            if (!isCompact) {
12137                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12138            } else if (mi.isProc) {
12139                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12140                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12141                pw.println(mi.hasActivities ? ",a" : ",e");
12142            } else {
12143                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12144                pw.println(mi.pss);
12145            }
12146            if (mi.subitems != null) {
12147                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12148                        true, isCompact);
12149            }
12150        }
12151    }
12152
12153    // These are in KB.
12154    static final long[] DUMP_MEM_BUCKETS = new long[] {
12155        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12156        120*1024, 160*1024, 200*1024,
12157        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12158        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12159    };
12160
12161    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12162            boolean stackLike) {
12163        int start = label.lastIndexOf('.');
12164        if (start >= 0) start++;
12165        else start = 0;
12166        int end = label.length();
12167        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12168            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12169                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12170                out.append(bucket);
12171                out.append(stackLike ? "MB." : "MB ");
12172                out.append(label, start, end);
12173                return;
12174            }
12175        }
12176        out.append(memKB/1024);
12177        out.append(stackLike ? "MB." : "MB ");
12178        out.append(label, start, end);
12179    }
12180
12181    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12182            ProcessList.NATIVE_ADJ,
12183            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12184            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12185            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12186            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12187            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12188    };
12189    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12190            "Native",
12191            "System", "Persistent", "Foreground",
12192            "Visible", "Perceptible",
12193            "Heavy Weight", "Backup",
12194            "A Services", "Home",
12195            "Previous", "B Services", "Cached"
12196    };
12197    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12198            "native",
12199            "sys", "pers", "fore",
12200            "vis", "percept",
12201            "heavy", "backup",
12202            "servicea", "home",
12203            "prev", "serviceb", "cached"
12204    };
12205
12206    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12207            long realtime, boolean isCheckinRequest, boolean isCompact) {
12208        if (isCheckinRequest || isCompact) {
12209            // short checkin version
12210            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12211        } else {
12212            pw.println("Applications Memory Usage (kB):");
12213            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12214        }
12215    }
12216
12217    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12218            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12219        boolean dumpDetails = false;
12220        boolean dumpFullDetails = false;
12221        boolean dumpDalvik = false;
12222        boolean oomOnly = false;
12223        boolean isCompact = false;
12224        boolean localOnly = false;
12225
12226        int opti = 0;
12227        while (opti < args.length) {
12228            String opt = args[opti];
12229            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12230                break;
12231            }
12232            opti++;
12233            if ("-a".equals(opt)) {
12234                dumpDetails = true;
12235                dumpFullDetails = true;
12236                dumpDalvik = true;
12237            } else if ("-d".equals(opt)) {
12238                dumpDalvik = true;
12239            } else if ("-c".equals(opt)) {
12240                isCompact = true;
12241            } else if ("--oom".equals(opt)) {
12242                oomOnly = true;
12243            } else if ("--local".equals(opt)) {
12244                localOnly = true;
12245            } else if ("-h".equals(opt)) {
12246                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12247                pw.println("  -a: include all available information for each process.");
12248                pw.println("  -d: include dalvik details when dumping process details.");
12249                pw.println("  -c: dump in a compact machine-parseable representation.");
12250                pw.println("  --oom: only show processes organized by oom adj.");
12251                pw.println("  --local: only collect details locally, don't call process.");
12252                pw.println("If [process] is specified it can be the name or ");
12253                pw.println("pid of a specific process to dump.");
12254                return;
12255            } else {
12256                pw.println("Unknown argument: " + opt + "; use -h for help");
12257            }
12258        }
12259
12260        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12261        long uptime = SystemClock.uptimeMillis();
12262        long realtime = SystemClock.elapsedRealtime();
12263        final long[] tmpLong = new long[1];
12264
12265        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12266        if (procs == null) {
12267            // No Java processes.  Maybe they want to print a native process.
12268            if (args != null && args.length > opti
12269                    && args[opti].charAt(0) != '-') {
12270                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12271                        = new ArrayList<ProcessCpuTracker.Stats>();
12272                updateCpuStatsNow();
12273                int findPid = -1;
12274                try {
12275                    findPid = Integer.parseInt(args[opti]);
12276                } catch (NumberFormatException e) {
12277                }
12278                synchronized (mProcessCpuThread) {
12279                    final int N = mProcessCpuTracker.countStats();
12280                    for (int i=0; i<N; i++) {
12281                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12282                        if (st.pid == findPid || (st.baseName != null
12283                                && st.baseName.equals(args[opti]))) {
12284                            nativeProcs.add(st);
12285                        }
12286                    }
12287                }
12288                if (nativeProcs.size() > 0) {
12289                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12290                            isCompact);
12291                    Debug.MemoryInfo mi = null;
12292                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12293                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12294                        final int pid = r.pid;
12295                        if (!isCheckinRequest && dumpDetails) {
12296                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12297                        }
12298                        if (mi == null) {
12299                            mi = new Debug.MemoryInfo();
12300                        }
12301                        if (dumpDetails || (!brief && !oomOnly)) {
12302                            Debug.getMemoryInfo(pid, mi);
12303                        } else {
12304                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12305                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12306                        }
12307                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12308                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12309                        if (isCheckinRequest) {
12310                            pw.println();
12311                        }
12312                    }
12313                    return;
12314                }
12315            }
12316            pw.println("No process found for: " + args[opti]);
12317            return;
12318        }
12319
12320        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12321            dumpDetails = true;
12322        }
12323
12324        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12325
12326        String[] innerArgs = new String[args.length-opti];
12327        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12328
12329        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12330        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12331        long nativePss=0, dalvikPss=0, otherPss=0;
12332        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12333
12334        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12335        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12336                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12337
12338        long totalPss = 0;
12339        long cachedPss = 0;
12340
12341        Debug.MemoryInfo mi = null;
12342        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12343            final ProcessRecord r = procs.get(i);
12344            final IApplicationThread thread;
12345            final int pid;
12346            final int oomAdj;
12347            final boolean hasActivities;
12348            synchronized (this) {
12349                thread = r.thread;
12350                pid = r.pid;
12351                oomAdj = r.getSetAdjWithServices();
12352                hasActivities = r.activities.size() > 0;
12353            }
12354            if (thread != null) {
12355                if (!isCheckinRequest && dumpDetails) {
12356                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12357                }
12358                if (mi == null) {
12359                    mi = new Debug.MemoryInfo();
12360                }
12361                if (dumpDetails || (!brief && !oomOnly)) {
12362                    Debug.getMemoryInfo(pid, mi);
12363                } else {
12364                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12365                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12366                }
12367                if (dumpDetails) {
12368                    if (localOnly) {
12369                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12370                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12371                        if (isCheckinRequest) {
12372                            pw.println();
12373                        }
12374                    } else {
12375                        try {
12376                            pw.flush();
12377                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12378                                    dumpDalvik, innerArgs);
12379                        } catch (RemoteException e) {
12380                            if (!isCheckinRequest) {
12381                                pw.println("Got RemoteException!");
12382                                pw.flush();
12383                            }
12384                        }
12385                    }
12386                }
12387
12388                final long myTotalPss = mi.getTotalPss();
12389                final long myTotalUss = mi.getTotalUss();
12390
12391                synchronized (this) {
12392                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12393                        // Record this for posterity if the process has been stable.
12394                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12395                    }
12396                }
12397
12398                if (!isCheckinRequest && mi != null) {
12399                    totalPss += myTotalPss;
12400                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12401                            (hasActivities ? " / activities)" : ")"),
12402                            r.processName, myTotalPss, pid, hasActivities);
12403                    procMems.add(pssItem);
12404                    procMemsMap.put(pid, pssItem);
12405
12406                    nativePss += mi.nativePss;
12407                    dalvikPss += mi.dalvikPss;
12408                    otherPss += mi.otherPss;
12409                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12410                        long mem = mi.getOtherPss(j);
12411                        miscPss[j] += mem;
12412                        otherPss -= mem;
12413                    }
12414
12415                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12416                        cachedPss += myTotalPss;
12417                    }
12418
12419                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12420                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12421                                || oomIndex == (oomPss.length-1)) {
12422                            oomPss[oomIndex] += myTotalPss;
12423                            if (oomProcs[oomIndex] == null) {
12424                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12425                            }
12426                            oomProcs[oomIndex].add(pssItem);
12427                            break;
12428                        }
12429                    }
12430                }
12431            }
12432        }
12433
12434        if (!isCheckinRequest && procs.size() > 1) {
12435            // If we are showing aggregations, also look for native processes to
12436            // include so that our aggregations are more accurate.
12437            updateCpuStatsNow();
12438            synchronized (mProcessCpuThread) {
12439                final int N = mProcessCpuTracker.countStats();
12440                for (int i=0; i<N; i++) {
12441                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12442                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12443                        if (mi == null) {
12444                            mi = new Debug.MemoryInfo();
12445                        }
12446                        if (!brief && !oomOnly) {
12447                            Debug.getMemoryInfo(st.pid, mi);
12448                        } else {
12449                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12450                            mi.nativePrivateDirty = (int)tmpLong[0];
12451                        }
12452
12453                        final long myTotalPss = mi.getTotalPss();
12454                        totalPss += myTotalPss;
12455
12456                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12457                                st.name, myTotalPss, st.pid, false);
12458                        procMems.add(pssItem);
12459
12460                        nativePss += mi.nativePss;
12461                        dalvikPss += mi.dalvikPss;
12462                        otherPss += mi.otherPss;
12463                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12464                            long mem = mi.getOtherPss(j);
12465                            miscPss[j] += mem;
12466                            otherPss -= mem;
12467                        }
12468                        oomPss[0] += myTotalPss;
12469                        if (oomProcs[0] == null) {
12470                            oomProcs[0] = new ArrayList<MemItem>();
12471                        }
12472                        oomProcs[0].add(pssItem);
12473                    }
12474                }
12475            }
12476
12477            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12478
12479            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12480            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12481            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12482            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12483                String label = Debug.MemoryInfo.getOtherLabel(j);
12484                catMems.add(new MemItem(label, label, miscPss[j], j));
12485            }
12486
12487            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12488            for (int j=0; j<oomPss.length; j++) {
12489                if (oomPss[j] != 0) {
12490                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12491                            : DUMP_MEM_OOM_LABEL[j];
12492                    MemItem item = new MemItem(label, label, oomPss[j],
12493                            DUMP_MEM_OOM_ADJ[j]);
12494                    item.subitems = oomProcs[j];
12495                    oomMems.add(item);
12496                }
12497            }
12498
12499            if (!brief && !oomOnly && !isCompact) {
12500                pw.println();
12501                pw.println("Total PSS by process:");
12502                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12503                pw.println();
12504            }
12505            if (!isCompact) {
12506                pw.println("Total PSS by OOM adjustment:");
12507            }
12508            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12509            if (!brief && !oomOnly) {
12510                PrintWriter out = categoryPw != null ? categoryPw : pw;
12511                if (!isCompact) {
12512                    out.println();
12513                    out.println("Total PSS by category:");
12514                }
12515                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12516            }
12517            if (!isCompact) {
12518                pw.println();
12519            }
12520            MemInfoReader memInfo = new MemInfoReader();
12521            memInfo.readMemInfo();
12522            if (!brief) {
12523                if (!isCompact) {
12524                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12525                    pw.print(" kB (status ");
12526                    switch (mLastMemoryLevel) {
12527                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12528                            pw.println("normal)");
12529                            break;
12530                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12531                            pw.println("moderate)");
12532                            break;
12533                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12534                            pw.println("low)");
12535                            break;
12536                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12537                            pw.println("critical)");
12538                            break;
12539                        default:
12540                            pw.print(mLastMemoryLevel);
12541                            pw.println(")");
12542                            break;
12543                    }
12544                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12545                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12546                            pw.print(cachedPss); pw.print(" cached pss + ");
12547                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12548                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12549                } else {
12550                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12551                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12552                            + memInfo.getFreeSizeKb()); pw.print(",");
12553                    pw.println(totalPss - cachedPss);
12554                }
12555            }
12556            if (!isCompact) {
12557                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12558                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12559                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12560                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12561                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12562                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12563                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12564                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12565                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12566                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12567                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12568            }
12569            if (!brief) {
12570                if (memInfo.getZramTotalSizeKb() != 0) {
12571                    if (!isCompact) {
12572                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12573                                pw.print(" kB physical used for ");
12574                                pw.print(memInfo.getSwapTotalSizeKb()
12575                                        - memInfo.getSwapFreeSizeKb());
12576                                pw.print(" kB in swap (");
12577                                pw.print(memInfo.getSwapTotalSizeKb());
12578                                pw.println(" kB total swap)");
12579                    } else {
12580                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12581                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12582                                pw.println(memInfo.getSwapFreeSizeKb());
12583                    }
12584                }
12585                final int[] SINGLE_LONG_FORMAT = new int[] {
12586                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12587                };
12588                long[] longOut = new long[1];
12589                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12590                        SINGLE_LONG_FORMAT, null, longOut, null);
12591                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12592                longOut[0] = 0;
12593                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12594                        SINGLE_LONG_FORMAT, null, longOut, null);
12595                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12596                longOut[0] = 0;
12597                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12598                        SINGLE_LONG_FORMAT, null, longOut, null);
12599                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12600                longOut[0] = 0;
12601                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12602                        SINGLE_LONG_FORMAT, null, longOut, null);
12603                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12604                if (!isCompact) {
12605                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12606                        pw.print("      KSM: "); pw.print(sharing);
12607                                pw.print(" kB saved from shared ");
12608                                pw.print(shared); pw.println(" kB");
12609                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12610                                pw.print(voltile); pw.println(" kB volatile");
12611                    }
12612                    pw.print("   Tuning: ");
12613                    pw.print(ActivityManager.staticGetMemoryClass());
12614                    pw.print(" (large ");
12615                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12616                    pw.print("), oom ");
12617                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12618                    pw.print(" kB");
12619                    pw.print(", restore limit ");
12620                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12621                    pw.print(" kB");
12622                    if (ActivityManager.isLowRamDeviceStatic()) {
12623                        pw.print(" (low-ram)");
12624                    }
12625                    if (ActivityManager.isHighEndGfx()) {
12626                        pw.print(" (high-end-gfx)");
12627                    }
12628                    pw.println();
12629                } else {
12630                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12631                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12632                    pw.println(voltile);
12633                    pw.print("tuning,");
12634                    pw.print(ActivityManager.staticGetMemoryClass());
12635                    pw.print(',');
12636                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12637                    pw.print(',');
12638                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12639                    if (ActivityManager.isLowRamDeviceStatic()) {
12640                        pw.print(",low-ram");
12641                    }
12642                    if (ActivityManager.isHighEndGfx()) {
12643                        pw.print(",high-end-gfx");
12644                    }
12645                    pw.println();
12646                }
12647            }
12648        }
12649    }
12650
12651    /**
12652     * Searches array of arguments for the specified string
12653     * @param args array of argument strings
12654     * @param value value to search for
12655     * @return true if the value is contained in the array
12656     */
12657    private static boolean scanArgs(String[] args, String value) {
12658        if (args != null) {
12659            for (String arg : args) {
12660                if (value.equals(arg)) {
12661                    return true;
12662                }
12663            }
12664        }
12665        return false;
12666    }
12667
12668    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12669            ContentProviderRecord cpr, boolean always) {
12670        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12671
12672        if (!inLaunching || always) {
12673            synchronized (cpr) {
12674                cpr.launchingApp = null;
12675                cpr.notifyAll();
12676            }
12677            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12678            String names[] = cpr.info.authority.split(";");
12679            for (int j = 0; j < names.length; j++) {
12680                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12681            }
12682        }
12683
12684        for (int i=0; i<cpr.connections.size(); i++) {
12685            ContentProviderConnection conn = cpr.connections.get(i);
12686            if (conn.waiting) {
12687                // If this connection is waiting for the provider, then we don't
12688                // need to mess with its process unless we are always removing
12689                // or for some reason the provider is not currently launching.
12690                if (inLaunching && !always) {
12691                    continue;
12692                }
12693            }
12694            ProcessRecord capp = conn.client;
12695            conn.dead = true;
12696            if (conn.stableCount > 0) {
12697                if (!capp.persistent && capp.thread != null
12698                        && capp.pid != 0
12699                        && capp.pid != MY_PID) {
12700                    killUnneededProcessLocked(capp, "depends on provider "
12701                            + cpr.name.flattenToShortString()
12702                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12703                }
12704            } else if (capp.thread != null && conn.provider.provider != null) {
12705                try {
12706                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12707                } catch (RemoteException e) {
12708                }
12709                // In the protocol here, we don't expect the client to correctly
12710                // clean up this connection, we'll just remove it.
12711                cpr.connections.remove(i);
12712                conn.client.conProviders.remove(conn);
12713            }
12714        }
12715
12716        if (inLaunching && always) {
12717            mLaunchingProviders.remove(cpr);
12718        }
12719        return inLaunching;
12720    }
12721
12722    /**
12723     * Main code for cleaning up a process when it has gone away.  This is
12724     * called both as a result of the process dying, or directly when stopping
12725     * a process when running in single process mode.
12726     */
12727    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12728            boolean restarting, boolean allowRestart, int index) {
12729        if (index >= 0) {
12730            removeLruProcessLocked(app);
12731            ProcessList.remove(app.pid);
12732        }
12733
12734        mProcessesToGc.remove(app);
12735        mPendingPssProcesses.remove(app);
12736
12737        // Dismiss any open dialogs.
12738        if (app.crashDialog != null && !app.forceCrashReport) {
12739            app.crashDialog.dismiss();
12740            app.crashDialog = null;
12741        }
12742        if (app.anrDialog != null) {
12743            app.anrDialog.dismiss();
12744            app.anrDialog = null;
12745        }
12746        if (app.waitDialog != null) {
12747            app.waitDialog.dismiss();
12748            app.waitDialog = null;
12749        }
12750
12751        app.crashing = false;
12752        app.notResponding = false;
12753
12754        app.resetPackageList(mProcessStats);
12755        app.unlinkDeathRecipient();
12756        app.makeInactive(mProcessStats);
12757        app.forcingToForeground = null;
12758        updateProcessForegroundLocked(app, false, false);
12759        app.foregroundActivities = false;
12760        app.hasShownUi = false;
12761        app.treatLikeActivity = false;
12762        app.hasAboveClient = false;
12763        app.hasClientActivities = false;
12764
12765        mServices.killServicesLocked(app, allowRestart);
12766
12767        boolean restart = false;
12768
12769        // Remove published content providers.
12770        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12771            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12772            final boolean always = app.bad || !allowRestart;
12773            if (removeDyingProviderLocked(app, cpr, always) || always) {
12774                // We left the provider in the launching list, need to
12775                // restart it.
12776                restart = true;
12777            }
12778
12779            cpr.provider = null;
12780            cpr.proc = null;
12781        }
12782        app.pubProviders.clear();
12783
12784        // Take care of any launching providers waiting for this process.
12785        if (checkAppInLaunchingProvidersLocked(app, false)) {
12786            restart = true;
12787        }
12788
12789        // Unregister from connected content providers.
12790        if (!app.conProviders.isEmpty()) {
12791            for (int i=0; i<app.conProviders.size(); i++) {
12792                ContentProviderConnection conn = app.conProviders.get(i);
12793                conn.provider.connections.remove(conn);
12794            }
12795            app.conProviders.clear();
12796        }
12797
12798        // At this point there may be remaining entries in mLaunchingProviders
12799        // where we were the only one waiting, so they are no longer of use.
12800        // Look for these and clean up if found.
12801        // XXX Commented out for now.  Trying to figure out a way to reproduce
12802        // the actual situation to identify what is actually going on.
12803        if (false) {
12804            for (int i=0; i<mLaunchingProviders.size(); i++) {
12805                ContentProviderRecord cpr = (ContentProviderRecord)
12806                        mLaunchingProviders.get(i);
12807                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12808                    synchronized (cpr) {
12809                        cpr.launchingApp = null;
12810                        cpr.notifyAll();
12811                    }
12812                }
12813            }
12814        }
12815
12816        skipCurrentReceiverLocked(app);
12817
12818        // Unregister any receivers.
12819        for (int i=app.receivers.size()-1; i>=0; i--) {
12820            removeReceiverLocked(app.receivers.valueAt(i));
12821        }
12822        app.receivers.clear();
12823
12824        // If the app is undergoing backup, tell the backup manager about it
12825        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12826            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12827                    + mBackupTarget.appInfo + " died during backup");
12828            try {
12829                IBackupManager bm = IBackupManager.Stub.asInterface(
12830                        ServiceManager.getService(Context.BACKUP_SERVICE));
12831                bm.agentDisconnected(app.info.packageName);
12832            } catch (RemoteException e) {
12833                // can't happen; backup manager is local
12834            }
12835        }
12836
12837        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12838            ProcessChangeItem item = mPendingProcessChanges.get(i);
12839            if (item.pid == app.pid) {
12840                mPendingProcessChanges.remove(i);
12841                mAvailProcessChanges.add(item);
12842            }
12843        }
12844        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12845
12846        // If the caller is restarting this app, then leave it in its
12847        // current lists and let the caller take care of it.
12848        if (restarting) {
12849            return;
12850        }
12851
12852        if (!app.persistent || app.isolated) {
12853            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12854                    "Removing non-persistent process during cleanup: " + app);
12855            mProcessNames.remove(app.processName, app.uid);
12856            mIsolatedProcesses.remove(app.uid);
12857            if (mHeavyWeightProcess == app) {
12858                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12859                        mHeavyWeightProcess.userId, 0));
12860                mHeavyWeightProcess = null;
12861            }
12862        } else if (!app.removed) {
12863            // This app is persistent, so we need to keep its record around.
12864            // If it is not already on the pending app list, add it there
12865            // and start a new process for it.
12866            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12867                mPersistentStartingProcesses.add(app);
12868                restart = true;
12869            }
12870        }
12871        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12872                "Clean-up removing on hold: " + app);
12873        mProcessesOnHold.remove(app);
12874
12875        if (app == mHomeProcess) {
12876            mHomeProcess = null;
12877        }
12878        if (app == mPreviousProcess) {
12879            mPreviousProcess = null;
12880        }
12881
12882        if (restart && !app.isolated) {
12883            // We have components that still need to be running in the
12884            // process, so re-launch it.
12885            mProcessNames.put(app.processName, app.uid, app);
12886            startProcessLocked(app, "restart", app.processName);
12887        } else if (app.pid > 0 && app.pid != MY_PID) {
12888            // Goodbye!
12889            boolean removed;
12890            synchronized (mPidsSelfLocked) {
12891                mPidsSelfLocked.remove(app.pid);
12892                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12893            }
12894            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12895                    app.processName, app.info.uid);
12896            if (app.isolated) {
12897                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12898            }
12899            app.setPid(0);
12900        }
12901    }
12902
12903    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12904        // Look through the content providers we are waiting to have launched,
12905        // and if any run in this process then either schedule a restart of
12906        // the process or kill the client waiting for it if this process has
12907        // gone bad.
12908        int NL = mLaunchingProviders.size();
12909        boolean restart = false;
12910        for (int i=0; i<NL; i++) {
12911            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12912            if (cpr.launchingApp == app) {
12913                if (!alwaysBad && !app.bad) {
12914                    restart = true;
12915                } else {
12916                    removeDyingProviderLocked(app, cpr, true);
12917                    // cpr should have been removed from mLaunchingProviders
12918                    NL = mLaunchingProviders.size();
12919                    i--;
12920                }
12921            }
12922        }
12923        return restart;
12924    }
12925
12926    // =========================================================
12927    // SERVICES
12928    // =========================================================
12929
12930    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12931            int flags) {
12932        enforceNotIsolatedCaller("getServices");
12933        synchronized (this) {
12934            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12935        }
12936    }
12937
12938    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12939        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12940        synchronized (this) {
12941            return mServices.getRunningServiceControlPanelLocked(name);
12942        }
12943    }
12944
12945    public ComponentName startService(IApplicationThread caller, Intent service,
12946            String resolvedType, int userId) {
12947        enforceNotIsolatedCaller("startService");
12948        // Refuse possible leaked file descriptors
12949        if (service != null && service.hasFileDescriptors() == true) {
12950            throw new IllegalArgumentException("File descriptors passed in Intent");
12951        }
12952
12953        if (DEBUG_SERVICE)
12954            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12955        synchronized(this) {
12956            final int callingPid = Binder.getCallingPid();
12957            final int callingUid = Binder.getCallingUid();
12958            final long origId = Binder.clearCallingIdentity();
12959            ComponentName res = mServices.startServiceLocked(caller, service,
12960                    resolvedType, callingPid, callingUid, userId);
12961            Binder.restoreCallingIdentity(origId);
12962            return res;
12963        }
12964    }
12965
12966    ComponentName startServiceInPackage(int uid,
12967            Intent service, String resolvedType, int userId) {
12968        synchronized(this) {
12969            if (DEBUG_SERVICE)
12970                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12971            final long origId = Binder.clearCallingIdentity();
12972            ComponentName res = mServices.startServiceLocked(null, service,
12973                    resolvedType, -1, uid, userId);
12974            Binder.restoreCallingIdentity(origId);
12975            return res;
12976        }
12977    }
12978
12979    public int stopService(IApplicationThread caller, Intent service,
12980            String resolvedType, int userId) {
12981        enforceNotIsolatedCaller("stopService");
12982        // Refuse possible leaked file descriptors
12983        if (service != null && service.hasFileDescriptors() == true) {
12984            throw new IllegalArgumentException("File descriptors passed in Intent");
12985        }
12986
12987        synchronized(this) {
12988            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12989        }
12990    }
12991
12992    public IBinder peekService(Intent service, String resolvedType) {
12993        enforceNotIsolatedCaller("peekService");
12994        // Refuse possible leaked file descriptors
12995        if (service != null && service.hasFileDescriptors() == true) {
12996            throw new IllegalArgumentException("File descriptors passed in Intent");
12997        }
12998        synchronized(this) {
12999            return mServices.peekServiceLocked(service, resolvedType);
13000        }
13001    }
13002
13003    public boolean stopServiceToken(ComponentName className, IBinder token,
13004            int startId) {
13005        synchronized(this) {
13006            return mServices.stopServiceTokenLocked(className, token, startId);
13007        }
13008    }
13009
13010    public void setServiceForeground(ComponentName className, IBinder token,
13011            int id, Notification notification, boolean removeNotification) {
13012        synchronized(this) {
13013            mServices.setServiceForegroundLocked(className, token, id, notification,
13014                    removeNotification);
13015        }
13016    }
13017
13018    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13019            boolean requireFull, String name, String callerPackage) {
13020        final int callingUserId = UserHandle.getUserId(callingUid);
13021        if (callingUserId != userId) {
13022            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13023                if ((requireFull || checkComponentPermission(
13024                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13025                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13026                        && checkComponentPermission(
13027                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13028                                callingPid, callingUid, -1, true)
13029                                != PackageManager.PERMISSION_GRANTED) {
13030                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13031                        // In this case, they would like to just execute as their
13032                        // owner user instead of failing.
13033                        userId = callingUserId;
13034                    } else {
13035                        StringBuilder builder = new StringBuilder(128);
13036                        builder.append("Permission Denial: ");
13037                        builder.append(name);
13038                        if (callerPackage != null) {
13039                            builder.append(" from ");
13040                            builder.append(callerPackage);
13041                        }
13042                        builder.append(" asks to run as user ");
13043                        builder.append(userId);
13044                        builder.append(" but is calling from user ");
13045                        builder.append(UserHandle.getUserId(callingUid));
13046                        builder.append("; this requires ");
13047                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13048                        if (!requireFull) {
13049                            builder.append(" or ");
13050                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13051                        }
13052                        String msg = builder.toString();
13053                        Slog.w(TAG, msg);
13054                        throw new SecurityException(msg);
13055                    }
13056                }
13057            }
13058            if (userId == UserHandle.USER_CURRENT
13059                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13060                // Note that we may be accessing this outside of a lock...
13061                // shouldn't be a big deal, if this is being called outside
13062                // of a locked context there is intrinsically a race with
13063                // the value the caller will receive and someone else changing it.
13064                userId = mCurrentUserId;
13065            }
13066            if (!allowAll && userId < 0) {
13067                throw new IllegalArgumentException(
13068                        "Call does not support special user #" + userId);
13069            }
13070        }
13071        return userId;
13072    }
13073
13074    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13075            String className, int flags) {
13076        boolean result = false;
13077        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13078            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13079                if (ActivityManager.checkUidPermission(
13080                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13081                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13082                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13083                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13084                            + " requests FLAG_SINGLE_USER, but app does not hold "
13085                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13086                    Slog.w(TAG, msg);
13087                    throw new SecurityException(msg);
13088                }
13089                result = true;
13090            }
13091        } else if (componentProcessName == aInfo.packageName) {
13092            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13093        } else if ("system".equals(componentProcessName)) {
13094            result = true;
13095        }
13096        if (DEBUG_MU) {
13097            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13098                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13099        }
13100        return result;
13101    }
13102
13103    public int bindService(IApplicationThread caller, IBinder token,
13104            Intent service, String resolvedType,
13105            IServiceConnection connection, int flags, int userId) {
13106        enforceNotIsolatedCaller("bindService");
13107        // Refuse possible leaked file descriptors
13108        if (service != null && service.hasFileDescriptors() == true) {
13109            throw new IllegalArgumentException("File descriptors passed in Intent");
13110        }
13111
13112        synchronized(this) {
13113            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13114                    connection, flags, userId);
13115        }
13116    }
13117
13118    public boolean unbindService(IServiceConnection connection) {
13119        synchronized (this) {
13120            return mServices.unbindServiceLocked(connection);
13121        }
13122    }
13123
13124    public void publishService(IBinder token, Intent intent, IBinder service) {
13125        // Refuse possible leaked file descriptors
13126        if (intent != null && intent.hasFileDescriptors() == true) {
13127            throw new IllegalArgumentException("File descriptors passed in Intent");
13128        }
13129
13130        synchronized(this) {
13131            if (!(token instanceof ServiceRecord)) {
13132                throw new IllegalArgumentException("Invalid service token");
13133            }
13134            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13135        }
13136    }
13137
13138    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13139        // Refuse possible leaked file descriptors
13140        if (intent != null && intent.hasFileDescriptors() == true) {
13141            throw new IllegalArgumentException("File descriptors passed in Intent");
13142        }
13143
13144        synchronized(this) {
13145            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13146        }
13147    }
13148
13149    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13150        synchronized(this) {
13151            if (!(token instanceof ServiceRecord)) {
13152                throw new IllegalArgumentException("Invalid service token");
13153            }
13154            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13155        }
13156    }
13157
13158    // =========================================================
13159    // BACKUP AND RESTORE
13160    // =========================================================
13161
13162    // Cause the target app to be launched if necessary and its backup agent
13163    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13164    // activity manager to announce its creation.
13165    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13166        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13167        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13168
13169        synchronized(this) {
13170            // !!! TODO: currently no check here that we're already bound
13171            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13172            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13173            synchronized (stats) {
13174                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13175            }
13176
13177            // Backup agent is now in use, its package can't be stopped.
13178            try {
13179                AppGlobals.getPackageManager().setPackageStoppedState(
13180                        app.packageName, false, UserHandle.getUserId(app.uid));
13181            } catch (RemoteException e) {
13182            } catch (IllegalArgumentException e) {
13183                Slog.w(TAG, "Failed trying to unstop package "
13184                        + app.packageName + ": " + e);
13185            }
13186
13187            BackupRecord r = new BackupRecord(ss, app, backupMode);
13188            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13189                    ? new ComponentName(app.packageName, app.backupAgentName)
13190                    : new ComponentName("android", "FullBackupAgent");
13191            // startProcessLocked() returns existing proc's record if it's already running
13192            ProcessRecord proc = startProcessLocked(app.processName, app,
13193                    false, 0, "backup", hostingName, false, false, false);
13194            if (proc == null) {
13195                Slog.e(TAG, "Unable to start backup agent process " + r);
13196                return false;
13197            }
13198
13199            r.app = proc;
13200            mBackupTarget = r;
13201            mBackupAppName = app.packageName;
13202
13203            // Try not to kill the process during backup
13204            updateOomAdjLocked(proc);
13205
13206            // If the process is already attached, schedule the creation of the backup agent now.
13207            // If it is not yet live, this will be done when it attaches to the framework.
13208            if (proc.thread != null) {
13209                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13210                try {
13211                    proc.thread.scheduleCreateBackupAgent(app,
13212                            compatibilityInfoForPackageLocked(app), backupMode);
13213                } catch (RemoteException e) {
13214                    // Will time out on the backup manager side
13215                }
13216            } else {
13217                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13218            }
13219            // Invariants: at this point, the target app process exists and the application
13220            // is either already running or in the process of coming up.  mBackupTarget and
13221            // mBackupAppName describe the app, so that when it binds back to the AM we
13222            // know that it's scheduled for a backup-agent operation.
13223        }
13224
13225        return true;
13226    }
13227
13228    @Override
13229    public void clearPendingBackup() {
13230        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13231        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13232
13233        synchronized (this) {
13234            mBackupTarget = null;
13235            mBackupAppName = null;
13236        }
13237    }
13238
13239    // A backup agent has just come up
13240    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13241        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13242                + " = " + agent);
13243
13244        synchronized(this) {
13245            if (!agentPackageName.equals(mBackupAppName)) {
13246                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13247                return;
13248            }
13249        }
13250
13251        long oldIdent = Binder.clearCallingIdentity();
13252        try {
13253            IBackupManager bm = IBackupManager.Stub.asInterface(
13254                    ServiceManager.getService(Context.BACKUP_SERVICE));
13255            bm.agentConnected(agentPackageName, agent);
13256        } catch (RemoteException e) {
13257            // can't happen; the backup manager service is local
13258        } catch (Exception e) {
13259            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13260            e.printStackTrace();
13261        } finally {
13262            Binder.restoreCallingIdentity(oldIdent);
13263        }
13264    }
13265
13266    // done with this agent
13267    public void unbindBackupAgent(ApplicationInfo appInfo) {
13268        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13269        if (appInfo == null) {
13270            Slog.w(TAG, "unbind backup agent for null app");
13271            return;
13272        }
13273
13274        synchronized(this) {
13275            try {
13276                if (mBackupAppName == null) {
13277                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13278                    return;
13279                }
13280
13281                if (!mBackupAppName.equals(appInfo.packageName)) {
13282                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13283                    return;
13284                }
13285
13286                // Not backing this app up any more; reset its OOM adjustment
13287                final ProcessRecord proc = mBackupTarget.app;
13288                updateOomAdjLocked(proc);
13289
13290                // If the app crashed during backup, 'thread' will be null here
13291                if (proc.thread != null) {
13292                    try {
13293                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13294                                compatibilityInfoForPackageLocked(appInfo));
13295                    } catch (Exception e) {
13296                        Slog.e(TAG, "Exception when unbinding backup agent:");
13297                        e.printStackTrace();
13298                    }
13299                }
13300            } finally {
13301                mBackupTarget = null;
13302                mBackupAppName = null;
13303            }
13304        }
13305    }
13306    // =========================================================
13307    // BROADCASTS
13308    // =========================================================
13309
13310    private final List getStickiesLocked(String action, IntentFilter filter,
13311            List cur, int userId) {
13312        final ContentResolver resolver = mContext.getContentResolver();
13313        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13314        if (stickies == null) {
13315            return cur;
13316        }
13317        final ArrayList<Intent> list = stickies.get(action);
13318        if (list == null) {
13319            return cur;
13320        }
13321        int N = list.size();
13322        for (int i=0; i<N; i++) {
13323            Intent intent = list.get(i);
13324            if (filter.match(resolver, intent, true, TAG) >= 0) {
13325                if (cur == null) {
13326                    cur = new ArrayList<Intent>();
13327                }
13328                cur.add(intent);
13329            }
13330        }
13331        return cur;
13332    }
13333
13334    boolean isPendingBroadcastProcessLocked(int pid) {
13335        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13336                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13337    }
13338
13339    void skipPendingBroadcastLocked(int pid) {
13340            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13341            for (BroadcastQueue queue : mBroadcastQueues) {
13342                queue.skipPendingBroadcastLocked(pid);
13343            }
13344    }
13345
13346    // The app just attached; send any pending broadcasts that it should receive
13347    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13348        boolean didSomething = false;
13349        for (BroadcastQueue queue : mBroadcastQueues) {
13350            didSomething |= queue.sendPendingBroadcastsLocked(app);
13351        }
13352        return didSomething;
13353    }
13354
13355    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13356            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13357        enforceNotIsolatedCaller("registerReceiver");
13358        int callingUid;
13359        int callingPid;
13360        synchronized(this) {
13361            ProcessRecord callerApp = null;
13362            if (caller != null) {
13363                callerApp = getRecordForAppLocked(caller);
13364                if (callerApp == null) {
13365                    throw new SecurityException(
13366                            "Unable to find app for caller " + caller
13367                            + " (pid=" + Binder.getCallingPid()
13368                            + ") when registering receiver " + receiver);
13369                }
13370                if (callerApp.info.uid != Process.SYSTEM_UID &&
13371                        !callerApp.pkgList.containsKey(callerPackage) &&
13372                        !"android".equals(callerPackage)) {
13373                    throw new SecurityException("Given caller package " + callerPackage
13374                            + " is not running in process " + callerApp);
13375                }
13376                callingUid = callerApp.info.uid;
13377                callingPid = callerApp.pid;
13378            } else {
13379                callerPackage = null;
13380                callingUid = Binder.getCallingUid();
13381                callingPid = Binder.getCallingPid();
13382            }
13383
13384            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13385                    true, true, "registerReceiver", callerPackage);
13386
13387            List allSticky = null;
13388
13389            // Look for any matching sticky broadcasts...
13390            Iterator actions = filter.actionsIterator();
13391            if (actions != null) {
13392                while (actions.hasNext()) {
13393                    String action = (String)actions.next();
13394                    allSticky = getStickiesLocked(action, filter, allSticky,
13395                            UserHandle.USER_ALL);
13396                    allSticky = getStickiesLocked(action, filter, allSticky,
13397                            UserHandle.getUserId(callingUid));
13398                }
13399            } else {
13400                allSticky = getStickiesLocked(null, filter, allSticky,
13401                        UserHandle.USER_ALL);
13402                allSticky = getStickiesLocked(null, filter, allSticky,
13403                        UserHandle.getUserId(callingUid));
13404            }
13405
13406            // The first sticky in the list is returned directly back to
13407            // the client.
13408            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13409
13410            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13411                    + ": " + sticky);
13412
13413            if (receiver == null) {
13414                return sticky;
13415            }
13416
13417            ReceiverList rl
13418                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13419            if (rl == null) {
13420                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13421                        userId, receiver);
13422                if (rl.app != null) {
13423                    rl.app.receivers.add(rl);
13424                } else {
13425                    try {
13426                        receiver.asBinder().linkToDeath(rl, 0);
13427                    } catch (RemoteException e) {
13428                        return sticky;
13429                    }
13430                    rl.linkedToDeath = true;
13431                }
13432                mRegisteredReceivers.put(receiver.asBinder(), rl);
13433            } else if (rl.uid != callingUid) {
13434                throw new IllegalArgumentException(
13435                        "Receiver requested to register for uid " + callingUid
13436                        + " was previously registered for uid " + rl.uid);
13437            } else if (rl.pid != callingPid) {
13438                throw new IllegalArgumentException(
13439                        "Receiver requested to register for pid " + callingPid
13440                        + " was previously registered for pid " + rl.pid);
13441            } else if (rl.userId != userId) {
13442                throw new IllegalArgumentException(
13443                        "Receiver requested to register for user " + userId
13444                        + " was previously registered for user " + rl.userId);
13445            }
13446            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13447                    permission, callingUid, userId);
13448            rl.add(bf);
13449            if (!bf.debugCheck()) {
13450                Slog.w(TAG, "==> For Dynamic broadast");
13451            }
13452            mReceiverResolver.addFilter(bf);
13453
13454            // Enqueue broadcasts for all existing stickies that match
13455            // this filter.
13456            if (allSticky != null) {
13457                ArrayList receivers = new ArrayList();
13458                receivers.add(bf);
13459
13460                int N = allSticky.size();
13461                for (int i=0; i<N; i++) {
13462                    Intent intent = (Intent)allSticky.get(i);
13463                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13464                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13465                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13466                            null, null, false, true, true, -1);
13467                    queue.enqueueParallelBroadcastLocked(r);
13468                    queue.scheduleBroadcastsLocked();
13469                }
13470            }
13471
13472            return sticky;
13473        }
13474    }
13475
13476    public void unregisterReceiver(IIntentReceiver receiver) {
13477        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13478
13479        final long origId = Binder.clearCallingIdentity();
13480        try {
13481            boolean doTrim = false;
13482
13483            synchronized(this) {
13484                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13485                if (rl != null) {
13486                    if (rl.curBroadcast != null) {
13487                        BroadcastRecord r = rl.curBroadcast;
13488                        final boolean doNext = finishReceiverLocked(
13489                                receiver.asBinder(), r.resultCode, r.resultData,
13490                                r.resultExtras, r.resultAbort);
13491                        if (doNext) {
13492                            doTrim = true;
13493                            r.queue.processNextBroadcast(false);
13494                        }
13495                    }
13496
13497                    if (rl.app != null) {
13498                        rl.app.receivers.remove(rl);
13499                    }
13500                    removeReceiverLocked(rl);
13501                    if (rl.linkedToDeath) {
13502                        rl.linkedToDeath = false;
13503                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13504                    }
13505                }
13506            }
13507
13508            // If we actually concluded any broadcasts, we might now be able
13509            // to trim the recipients' apps from our working set
13510            if (doTrim) {
13511                trimApplications();
13512                return;
13513            }
13514
13515        } finally {
13516            Binder.restoreCallingIdentity(origId);
13517        }
13518    }
13519
13520    void removeReceiverLocked(ReceiverList rl) {
13521        mRegisteredReceivers.remove(rl.receiver.asBinder());
13522        int N = rl.size();
13523        for (int i=0; i<N; i++) {
13524            mReceiverResolver.removeFilter(rl.get(i));
13525        }
13526    }
13527
13528    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13529        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13530            ProcessRecord r = mLruProcesses.get(i);
13531            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13532                try {
13533                    r.thread.dispatchPackageBroadcast(cmd, packages);
13534                } catch (RemoteException ex) {
13535                }
13536            }
13537        }
13538    }
13539
13540    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13541            int[] users) {
13542        List<ResolveInfo> receivers = null;
13543        try {
13544            HashSet<ComponentName> singleUserReceivers = null;
13545            boolean scannedFirstReceivers = false;
13546            for (int user : users) {
13547                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13548                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13549                if (user != 0 && newReceivers != null) {
13550                    // If this is not the primary user, we need to check for
13551                    // any receivers that should be filtered out.
13552                    for (int i=0; i<newReceivers.size(); i++) {
13553                        ResolveInfo ri = newReceivers.get(i);
13554                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13555                            newReceivers.remove(i);
13556                            i--;
13557                        }
13558                    }
13559                }
13560                if (newReceivers != null && newReceivers.size() == 0) {
13561                    newReceivers = null;
13562                }
13563                if (receivers == null) {
13564                    receivers = newReceivers;
13565                } else if (newReceivers != null) {
13566                    // We need to concatenate the additional receivers
13567                    // found with what we have do far.  This would be easy,
13568                    // but we also need to de-dup any receivers that are
13569                    // singleUser.
13570                    if (!scannedFirstReceivers) {
13571                        // Collect any single user receivers we had already retrieved.
13572                        scannedFirstReceivers = true;
13573                        for (int i=0; i<receivers.size(); i++) {
13574                            ResolveInfo ri = receivers.get(i);
13575                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13576                                ComponentName cn = new ComponentName(
13577                                        ri.activityInfo.packageName, ri.activityInfo.name);
13578                                if (singleUserReceivers == null) {
13579                                    singleUserReceivers = new HashSet<ComponentName>();
13580                                }
13581                                singleUserReceivers.add(cn);
13582                            }
13583                        }
13584                    }
13585                    // Add the new results to the existing results, tracking
13586                    // and de-dupping single user receivers.
13587                    for (int i=0; i<newReceivers.size(); i++) {
13588                        ResolveInfo ri = newReceivers.get(i);
13589                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13590                            ComponentName cn = new ComponentName(
13591                                    ri.activityInfo.packageName, ri.activityInfo.name);
13592                            if (singleUserReceivers == null) {
13593                                singleUserReceivers = new HashSet<ComponentName>();
13594                            }
13595                            if (!singleUserReceivers.contains(cn)) {
13596                                singleUserReceivers.add(cn);
13597                                receivers.add(ri);
13598                            }
13599                        } else {
13600                            receivers.add(ri);
13601                        }
13602                    }
13603                }
13604            }
13605        } catch (RemoteException ex) {
13606            // pm is in same process, this will never happen.
13607        }
13608        return receivers;
13609    }
13610
13611    private final int broadcastIntentLocked(ProcessRecord callerApp,
13612            String callerPackage, Intent intent, String resolvedType,
13613            IIntentReceiver resultTo, int resultCode, String resultData,
13614            Bundle map, String requiredPermission, int appOp,
13615            boolean ordered, boolean sticky, int callingPid, int callingUid,
13616            int userId) {
13617        intent = new Intent(intent);
13618
13619        // By default broadcasts do not go to stopped apps.
13620        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13621
13622        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13623            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13624            + " ordered=" + ordered + " userid=" + userId);
13625        if ((resultTo != null) && !ordered) {
13626            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13627        }
13628
13629        userId = handleIncomingUser(callingPid, callingUid, userId,
13630                true, false, "broadcast", callerPackage);
13631
13632        // Make sure that the user who is receiving this broadcast is started.
13633        // If not, we will just skip it.
13634        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13635            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13636                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13637                Slog.w(TAG, "Skipping broadcast of " + intent
13638                        + ": user " + userId + " is stopped");
13639                return ActivityManager.BROADCAST_SUCCESS;
13640            }
13641        }
13642
13643        /*
13644         * Prevent non-system code (defined here to be non-persistent
13645         * processes) from sending protected broadcasts.
13646         */
13647        int callingAppId = UserHandle.getAppId(callingUid);
13648        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13649            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13650            callingUid == 0) {
13651            // Always okay.
13652        } else if (callerApp == null || !callerApp.persistent) {
13653            try {
13654                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13655                        intent.getAction())) {
13656                    String msg = "Permission Denial: not allowed to send broadcast "
13657                            + intent.getAction() + " from pid="
13658                            + callingPid + ", uid=" + callingUid;
13659                    Slog.w(TAG, msg);
13660                    throw new SecurityException(msg);
13661                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13662                    // Special case for compatibility: we don't want apps to send this,
13663                    // but historically it has not been protected and apps may be using it
13664                    // to poke their own app widget.  So, instead of making it protected,
13665                    // just limit it to the caller.
13666                    if (callerApp == null) {
13667                        String msg = "Permission Denial: not allowed to send broadcast "
13668                                + intent.getAction() + " from unknown caller.";
13669                        Slog.w(TAG, msg);
13670                        throw new SecurityException(msg);
13671                    } else if (intent.getComponent() != null) {
13672                        // They are good enough to send to an explicit component...  verify
13673                        // it is being sent to the calling app.
13674                        if (!intent.getComponent().getPackageName().equals(
13675                                callerApp.info.packageName)) {
13676                            String msg = "Permission Denial: not allowed to send broadcast "
13677                                    + intent.getAction() + " to "
13678                                    + intent.getComponent().getPackageName() + " from "
13679                                    + callerApp.info.packageName;
13680                            Slog.w(TAG, msg);
13681                            throw new SecurityException(msg);
13682                        }
13683                    } else {
13684                        // Limit broadcast to their own package.
13685                        intent.setPackage(callerApp.info.packageName);
13686                    }
13687                }
13688            } catch (RemoteException e) {
13689                Slog.w(TAG, "Remote exception", e);
13690                return ActivityManager.BROADCAST_SUCCESS;
13691            }
13692        }
13693
13694        // Handle special intents: if this broadcast is from the package
13695        // manager about a package being removed, we need to remove all of
13696        // its activities from the history stack.
13697        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13698                intent.getAction());
13699        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13700                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13701                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13702                || uidRemoved) {
13703            if (checkComponentPermission(
13704                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13705                    callingPid, callingUid, -1, true)
13706                    == PackageManager.PERMISSION_GRANTED) {
13707                if (uidRemoved) {
13708                    final Bundle intentExtras = intent.getExtras();
13709                    final int uid = intentExtras != null
13710                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13711                    if (uid >= 0) {
13712                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13713                        synchronized (bs) {
13714                            bs.removeUidStatsLocked(uid);
13715                        }
13716                        mAppOpsService.uidRemoved(uid);
13717                    }
13718                } else {
13719                    // If resources are unavailable just force stop all
13720                    // those packages and flush the attribute cache as well.
13721                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13722                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13723                        if (list != null && (list.length > 0)) {
13724                            for (String pkg : list) {
13725                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13726                                        "storage unmount");
13727                            }
13728                            sendPackageBroadcastLocked(
13729                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13730                        }
13731                    } else {
13732                        Uri data = intent.getData();
13733                        String ssp;
13734                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13735                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13736                                    intent.getAction());
13737                            boolean fullUninstall = removed &&
13738                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13739                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13740                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13741                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13742                                        false, fullUninstall, userId,
13743                                        removed ? "pkg removed" : "pkg changed");
13744                            }
13745                            if (removed) {
13746                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13747                                        new String[] {ssp}, userId);
13748                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13749                                    mAppOpsService.packageRemoved(
13750                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13751
13752                                    // Remove all permissions granted from/to this package
13753                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13754                                }
13755                            }
13756                        }
13757                    }
13758                }
13759            } else {
13760                String msg = "Permission Denial: " + intent.getAction()
13761                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13762                        + ", uid=" + callingUid + ")"
13763                        + " requires "
13764                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13765                Slog.w(TAG, msg);
13766                throw new SecurityException(msg);
13767            }
13768
13769        // Special case for adding a package: by default turn on compatibility
13770        // mode.
13771        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13772            Uri data = intent.getData();
13773            String ssp;
13774            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13775                mCompatModePackages.handlePackageAddedLocked(ssp,
13776                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13777            }
13778        }
13779
13780        /*
13781         * If this is the time zone changed action, queue up a message that will reset the timezone
13782         * of all currently running processes. This message will get queued up before the broadcast
13783         * happens.
13784         */
13785        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13786            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13787        }
13788
13789        /*
13790         * If the user set the time, let all running processes know.
13791         */
13792        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13793            final int is24Hour = intent.getBooleanExtra(
13794                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13795            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13796        }
13797
13798        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13799            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13800        }
13801
13802        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13803            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13804            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13805        }
13806
13807        // Add to the sticky list if requested.
13808        if (sticky) {
13809            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13810                    callingPid, callingUid)
13811                    != PackageManager.PERMISSION_GRANTED) {
13812                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13813                        + callingPid + ", uid=" + callingUid
13814                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13815                Slog.w(TAG, msg);
13816                throw new SecurityException(msg);
13817            }
13818            if (requiredPermission != null) {
13819                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13820                        + " and enforce permission " + requiredPermission);
13821                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13822            }
13823            if (intent.getComponent() != null) {
13824                throw new SecurityException(
13825                        "Sticky broadcasts can't target a specific component");
13826            }
13827            // We use userId directly here, since the "all" target is maintained
13828            // as a separate set of sticky broadcasts.
13829            if (userId != UserHandle.USER_ALL) {
13830                // But first, if this is not a broadcast to all users, then
13831                // make sure it doesn't conflict with an existing broadcast to
13832                // all users.
13833                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13834                        UserHandle.USER_ALL);
13835                if (stickies != null) {
13836                    ArrayList<Intent> list = stickies.get(intent.getAction());
13837                    if (list != null) {
13838                        int N = list.size();
13839                        int i;
13840                        for (i=0; i<N; i++) {
13841                            if (intent.filterEquals(list.get(i))) {
13842                                throw new IllegalArgumentException(
13843                                        "Sticky broadcast " + intent + " for user "
13844                                        + userId + " conflicts with existing global broadcast");
13845                            }
13846                        }
13847                    }
13848                }
13849            }
13850            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13851            if (stickies == null) {
13852                stickies = new ArrayMap<String, ArrayList<Intent>>();
13853                mStickyBroadcasts.put(userId, stickies);
13854            }
13855            ArrayList<Intent> list = stickies.get(intent.getAction());
13856            if (list == null) {
13857                list = new ArrayList<Intent>();
13858                stickies.put(intent.getAction(), list);
13859            }
13860            int N = list.size();
13861            int i;
13862            for (i=0; i<N; i++) {
13863                if (intent.filterEquals(list.get(i))) {
13864                    // This sticky already exists, replace it.
13865                    list.set(i, new Intent(intent));
13866                    break;
13867                }
13868            }
13869            if (i >= N) {
13870                list.add(new Intent(intent));
13871            }
13872        }
13873
13874        int[] users;
13875        if (userId == UserHandle.USER_ALL) {
13876            // Caller wants broadcast to go to all started users.
13877            users = mStartedUserArray;
13878        } else {
13879            // Caller wants broadcast to go to one specific user.
13880            users = new int[] {userId};
13881        }
13882
13883        // Figure out who all will receive this broadcast.
13884        List receivers = null;
13885        List<BroadcastFilter> registeredReceivers = null;
13886        // Need to resolve the intent to interested receivers...
13887        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13888                 == 0) {
13889            receivers = collectReceiverComponents(intent, resolvedType, users);
13890        }
13891        if (intent.getComponent() == null) {
13892            registeredReceivers = mReceiverResolver.queryIntent(intent,
13893                    resolvedType, false, userId);
13894        }
13895
13896        final boolean replacePending =
13897                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13898
13899        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13900                + " replacePending=" + replacePending);
13901
13902        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13903        if (!ordered && NR > 0) {
13904            // If we are not serializing this broadcast, then send the
13905            // registered receivers separately so they don't wait for the
13906            // components to be launched.
13907            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13908            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13909                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13910                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13911                    ordered, sticky, false, userId);
13912            if (DEBUG_BROADCAST) Slog.v(
13913                    TAG, "Enqueueing parallel broadcast " + r);
13914            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13915            if (!replaced) {
13916                queue.enqueueParallelBroadcastLocked(r);
13917                queue.scheduleBroadcastsLocked();
13918            }
13919            registeredReceivers = null;
13920            NR = 0;
13921        }
13922
13923        // Merge into one list.
13924        int ir = 0;
13925        if (receivers != null) {
13926            // A special case for PACKAGE_ADDED: do not allow the package
13927            // being added to see this broadcast.  This prevents them from
13928            // using this as a back door to get run as soon as they are
13929            // installed.  Maybe in the future we want to have a special install
13930            // broadcast or such for apps, but we'd like to deliberately make
13931            // this decision.
13932            String skipPackages[] = null;
13933            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13934                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13935                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13936                Uri data = intent.getData();
13937                if (data != null) {
13938                    String pkgName = data.getSchemeSpecificPart();
13939                    if (pkgName != null) {
13940                        skipPackages = new String[] { pkgName };
13941                    }
13942                }
13943            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13944                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13945            }
13946            if (skipPackages != null && (skipPackages.length > 0)) {
13947                for (String skipPackage : skipPackages) {
13948                    if (skipPackage != null) {
13949                        int NT = receivers.size();
13950                        for (int it=0; it<NT; it++) {
13951                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13952                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13953                                receivers.remove(it);
13954                                it--;
13955                                NT--;
13956                            }
13957                        }
13958                    }
13959                }
13960            }
13961
13962            int NT = receivers != null ? receivers.size() : 0;
13963            int it = 0;
13964            ResolveInfo curt = null;
13965            BroadcastFilter curr = null;
13966            while (it < NT && ir < NR) {
13967                if (curt == null) {
13968                    curt = (ResolveInfo)receivers.get(it);
13969                }
13970                if (curr == null) {
13971                    curr = registeredReceivers.get(ir);
13972                }
13973                if (curr.getPriority() >= curt.priority) {
13974                    // Insert this broadcast record into the final list.
13975                    receivers.add(it, curr);
13976                    ir++;
13977                    curr = null;
13978                    it++;
13979                    NT++;
13980                } else {
13981                    // Skip to the next ResolveInfo in the final list.
13982                    it++;
13983                    curt = null;
13984                }
13985            }
13986        }
13987        while (ir < NR) {
13988            if (receivers == null) {
13989                receivers = new ArrayList();
13990            }
13991            receivers.add(registeredReceivers.get(ir));
13992            ir++;
13993        }
13994
13995        if ((receivers != null && receivers.size() > 0)
13996                || resultTo != null) {
13997            BroadcastQueue queue = broadcastQueueForIntent(intent);
13998            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13999                    callerPackage, callingPid, callingUid, resolvedType,
14000                    requiredPermission, appOp, receivers, resultTo, resultCode,
14001                    resultData, map, ordered, sticky, false, userId);
14002            if (DEBUG_BROADCAST) Slog.v(
14003                    TAG, "Enqueueing ordered broadcast " + r
14004                    + ": prev had " + queue.mOrderedBroadcasts.size());
14005            if (DEBUG_BROADCAST) {
14006                int seq = r.intent.getIntExtra("seq", -1);
14007                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14008            }
14009            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14010            if (!replaced) {
14011                queue.enqueueOrderedBroadcastLocked(r);
14012                queue.scheduleBroadcastsLocked();
14013            }
14014        }
14015
14016        return ActivityManager.BROADCAST_SUCCESS;
14017    }
14018
14019    final Intent verifyBroadcastLocked(Intent intent) {
14020        // Refuse possible leaked file descriptors
14021        if (intent != null && intent.hasFileDescriptors() == true) {
14022            throw new IllegalArgumentException("File descriptors passed in Intent");
14023        }
14024
14025        int flags = intent.getFlags();
14026
14027        if (!mProcessesReady) {
14028            // if the caller really truly claims to know what they're doing, go
14029            // ahead and allow the broadcast without launching any receivers
14030            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14031                intent = new Intent(intent);
14032                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14033            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14034                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14035                        + " before boot completion");
14036                throw new IllegalStateException("Cannot broadcast before boot completed");
14037            }
14038        }
14039
14040        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14041            throw new IllegalArgumentException(
14042                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14043        }
14044
14045        return intent;
14046    }
14047
14048    public final int broadcastIntent(IApplicationThread caller,
14049            Intent intent, String resolvedType, IIntentReceiver resultTo,
14050            int resultCode, String resultData, Bundle map,
14051            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14052        enforceNotIsolatedCaller("broadcastIntent");
14053        synchronized(this) {
14054            intent = verifyBroadcastLocked(intent);
14055
14056            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14057            final int callingPid = Binder.getCallingPid();
14058            final int callingUid = Binder.getCallingUid();
14059            final long origId = Binder.clearCallingIdentity();
14060            int res = broadcastIntentLocked(callerApp,
14061                    callerApp != null ? callerApp.info.packageName : null,
14062                    intent, resolvedType, resultTo,
14063                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14064                    callingPid, callingUid, userId);
14065            Binder.restoreCallingIdentity(origId);
14066            return res;
14067        }
14068    }
14069
14070    int broadcastIntentInPackage(String packageName, int uid,
14071            Intent intent, String resolvedType, IIntentReceiver resultTo,
14072            int resultCode, String resultData, Bundle map,
14073            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14074        synchronized(this) {
14075            intent = verifyBroadcastLocked(intent);
14076
14077            final long origId = Binder.clearCallingIdentity();
14078            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14079                    resultTo, resultCode, resultData, map, requiredPermission,
14080                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14081            Binder.restoreCallingIdentity(origId);
14082            return res;
14083        }
14084    }
14085
14086    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14087        // Refuse possible leaked file descriptors
14088        if (intent != null && intent.hasFileDescriptors() == true) {
14089            throw new IllegalArgumentException("File descriptors passed in Intent");
14090        }
14091
14092        userId = handleIncomingUser(Binder.getCallingPid(),
14093                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14094
14095        synchronized(this) {
14096            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14097                    != PackageManager.PERMISSION_GRANTED) {
14098                String msg = "Permission Denial: unbroadcastIntent() from pid="
14099                        + Binder.getCallingPid()
14100                        + ", uid=" + Binder.getCallingUid()
14101                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14102                Slog.w(TAG, msg);
14103                throw new SecurityException(msg);
14104            }
14105            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14106            if (stickies != null) {
14107                ArrayList<Intent> list = stickies.get(intent.getAction());
14108                if (list != null) {
14109                    int N = list.size();
14110                    int i;
14111                    for (i=0; i<N; i++) {
14112                        if (intent.filterEquals(list.get(i))) {
14113                            list.remove(i);
14114                            break;
14115                        }
14116                    }
14117                    if (list.size() <= 0) {
14118                        stickies.remove(intent.getAction());
14119                    }
14120                }
14121                if (stickies.size() <= 0) {
14122                    mStickyBroadcasts.remove(userId);
14123                }
14124            }
14125        }
14126    }
14127
14128    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14129            String resultData, Bundle resultExtras, boolean resultAbort) {
14130        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14131        if (r == null) {
14132            Slog.w(TAG, "finishReceiver called but not found on queue");
14133            return false;
14134        }
14135
14136        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14137    }
14138
14139    void backgroundServicesFinishedLocked(int userId) {
14140        for (BroadcastQueue queue : mBroadcastQueues) {
14141            queue.backgroundServicesFinishedLocked(userId);
14142        }
14143    }
14144
14145    public void finishReceiver(IBinder who, int resultCode, String resultData,
14146            Bundle resultExtras, boolean resultAbort) {
14147        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14148
14149        // Refuse possible leaked file descriptors
14150        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14151            throw new IllegalArgumentException("File descriptors passed in Bundle");
14152        }
14153
14154        final long origId = Binder.clearCallingIdentity();
14155        try {
14156            boolean doNext = false;
14157            BroadcastRecord r;
14158
14159            synchronized(this) {
14160                r = broadcastRecordForReceiverLocked(who);
14161                if (r != null) {
14162                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14163                        resultData, resultExtras, resultAbort, true);
14164                }
14165            }
14166
14167            if (doNext) {
14168                r.queue.processNextBroadcast(false);
14169            }
14170            trimApplications();
14171        } finally {
14172            Binder.restoreCallingIdentity(origId);
14173        }
14174    }
14175
14176    // =========================================================
14177    // INSTRUMENTATION
14178    // =========================================================
14179
14180    public boolean startInstrumentation(ComponentName className,
14181            String profileFile, int flags, Bundle arguments,
14182            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14183            int userId) {
14184        enforceNotIsolatedCaller("startInstrumentation");
14185        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14186                userId, false, true, "startInstrumentation", null);
14187        // Refuse possible leaked file descriptors
14188        if (arguments != null && arguments.hasFileDescriptors()) {
14189            throw new IllegalArgumentException("File descriptors passed in Bundle");
14190        }
14191
14192        synchronized(this) {
14193            InstrumentationInfo ii = null;
14194            ApplicationInfo ai = null;
14195            try {
14196                ii = mContext.getPackageManager().getInstrumentationInfo(
14197                    className, STOCK_PM_FLAGS);
14198                ai = AppGlobals.getPackageManager().getApplicationInfo(
14199                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14200            } catch (PackageManager.NameNotFoundException e) {
14201            } catch (RemoteException e) {
14202            }
14203            if (ii == null) {
14204                reportStartInstrumentationFailure(watcher, className,
14205                        "Unable to find instrumentation info for: " + className);
14206                return false;
14207            }
14208            if (ai == null) {
14209                reportStartInstrumentationFailure(watcher, className,
14210                        "Unable to find instrumentation target package: " + ii.targetPackage);
14211                return false;
14212            }
14213
14214            int match = mContext.getPackageManager().checkSignatures(
14215                    ii.targetPackage, ii.packageName);
14216            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14217                String msg = "Permission Denial: starting instrumentation "
14218                        + className + " from pid="
14219                        + Binder.getCallingPid()
14220                        + ", uid=" + Binder.getCallingPid()
14221                        + " not allowed because package " + ii.packageName
14222                        + " does not have a signature matching the target "
14223                        + ii.targetPackage;
14224                reportStartInstrumentationFailure(watcher, className, msg);
14225                throw new SecurityException(msg);
14226            }
14227
14228            final long origId = Binder.clearCallingIdentity();
14229            // Instrumentation can kill and relaunch even persistent processes
14230            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14231                    "start instr");
14232            ProcessRecord app = addAppLocked(ai, false);
14233            app.instrumentationClass = className;
14234            app.instrumentationInfo = ai;
14235            app.instrumentationProfileFile = profileFile;
14236            app.instrumentationArguments = arguments;
14237            app.instrumentationWatcher = watcher;
14238            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14239            app.instrumentationResultClass = className;
14240            Binder.restoreCallingIdentity(origId);
14241        }
14242
14243        return true;
14244    }
14245
14246    /**
14247     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14248     * error to the logs, but if somebody is watching, send the report there too.  This enables
14249     * the "am" command to report errors with more information.
14250     *
14251     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14252     * @param cn The component name of the instrumentation.
14253     * @param report The error report.
14254     */
14255    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14256            ComponentName cn, String report) {
14257        Slog.w(TAG, report);
14258        try {
14259            if (watcher != null) {
14260                Bundle results = new Bundle();
14261                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14262                results.putString("Error", report);
14263                watcher.instrumentationStatus(cn, -1, results);
14264            }
14265        } catch (RemoteException e) {
14266            Slog.w(TAG, e);
14267        }
14268    }
14269
14270    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14271        if (app.instrumentationWatcher != null) {
14272            try {
14273                // NOTE:  IInstrumentationWatcher *must* be oneway here
14274                app.instrumentationWatcher.instrumentationFinished(
14275                    app.instrumentationClass,
14276                    resultCode,
14277                    results);
14278            } catch (RemoteException e) {
14279            }
14280        }
14281        if (app.instrumentationUiAutomationConnection != null) {
14282            try {
14283                app.instrumentationUiAutomationConnection.shutdown();
14284            } catch (RemoteException re) {
14285                /* ignore */
14286            }
14287            // Only a UiAutomation can set this flag and now that
14288            // it is finished we make sure it is reset to its default.
14289            mUserIsMonkey = false;
14290        }
14291        app.instrumentationWatcher = null;
14292        app.instrumentationUiAutomationConnection = null;
14293        app.instrumentationClass = null;
14294        app.instrumentationInfo = null;
14295        app.instrumentationProfileFile = null;
14296        app.instrumentationArguments = null;
14297
14298        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14299                "finished inst");
14300    }
14301
14302    public void finishInstrumentation(IApplicationThread target,
14303            int resultCode, Bundle results) {
14304        int userId = UserHandle.getCallingUserId();
14305        // Refuse possible leaked file descriptors
14306        if (results != null && results.hasFileDescriptors()) {
14307            throw new IllegalArgumentException("File descriptors passed in Intent");
14308        }
14309
14310        synchronized(this) {
14311            ProcessRecord app = getRecordForAppLocked(target);
14312            if (app == null) {
14313                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14314                return;
14315            }
14316            final long origId = Binder.clearCallingIdentity();
14317            finishInstrumentationLocked(app, resultCode, results);
14318            Binder.restoreCallingIdentity(origId);
14319        }
14320    }
14321
14322    // =========================================================
14323    // CONFIGURATION
14324    // =========================================================
14325
14326    public ConfigurationInfo getDeviceConfigurationInfo() {
14327        ConfigurationInfo config = new ConfigurationInfo();
14328        synchronized (this) {
14329            config.reqTouchScreen = mConfiguration.touchscreen;
14330            config.reqKeyboardType = mConfiguration.keyboard;
14331            config.reqNavigation = mConfiguration.navigation;
14332            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14333                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14334                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14335            }
14336            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14337                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14338                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14339            }
14340            config.reqGlEsVersion = GL_ES_VERSION;
14341        }
14342        return config;
14343    }
14344
14345    ActivityStack getFocusedStack() {
14346        return mStackSupervisor.getFocusedStack();
14347    }
14348
14349    public Configuration getConfiguration() {
14350        Configuration ci;
14351        synchronized(this) {
14352            ci = new Configuration(mConfiguration);
14353        }
14354        return ci;
14355    }
14356
14357    public void updatePersistentConfiguration(Configuration values) {
14358        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14359                "updateConfiguration()");
14360        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14361                "updateConfiguration()");
14362        if (values == null) {
14363            throw new NullPointerException("Configuration must not be null");
14364        }
14365
14366        synchronized(this) {
14367            final long origId = Binder.clearCallingIdentity();
14368            updateConfigurationLocked(values, null, true, false);
14369            Binder.restoreCallingIdentity(origId);
14370        }
14371    }
14372
14373    public void updateConfiguration(Configuration values) {
14374        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14375                "updateConfiguration()");
14376
14377        synchronized(this) {
14378            if (values == null && mWindowManager != null) {
14379                // sentinel: fetch the current configuration from the window manager
14380                values = mWindowManager.computeNewConfiguration();
14381            }
14382
14383            if (mWindowManager != null) {
14384                mProcessList.applyDisplaySize(mWindowManager);
14385            }
14386
14387            final long origId = Binder.clearCallingIdentity();
14388            if (values != null) {
14389                Settings.System.clearConfiguration(values);
14390            }
14391            updateConfigurationLocked(values, null, false, false);
14392            Binder.restoreCallingIdentity(origId);
14393        }
14394    }
14395
14396    /**
14397     * Do either or both things: (1) change the current configuration, and (2)
14398     * make sure the given activity is running with the (now) current
14399     * configuration.  Returns true if the activity has been left running, or
14400     * false if <var>starting</var> is being destroyed to match the new
14401     * configuration.
14402     * @param persistent TODO
14403     */
14404    boolean updateConfigurationLocked(Configuration values,
14405            ActivityRecord starting, boolean persistent, boolean initLocale) {
14406        int changes = 0;
14407
14408        if (values != null) {
14409            Configuration newConfig = new Configuration(mConfiguration);
14410            changes = newConfig.updateFrom(values);
14411            if (changes != 0) {
14412                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14413                    Slog.i(TAG, "Updating configuration to: " + values);
14414                }
14415
14416                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14417
14418                if (values.locale != null && !initLocale) {
14419                    saveLocaleLocked(values.locale,
14420                                     !values.locale.equals(mConfiguration.locale),
14421                                     values.userSetLocale);
14422                }
14423
14424                mConfigurationSeq++;
14425                if (mConfigurationSeq <= 0) {
14426                    mConfigurationSeq = 1;
14427                }
14428                newConfig.seq = mConfigurationSeq;
14429                mConfiguration = newConfig;
14430                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14431
14432                final Configuration configCopy = new Configuration(mConfiguration);
14433
14434                // TODO: If our config changes, should we auto dismiss any currently
14435                // showing dialogs?
14436                mShowDialogs = shouldShowDialogs(newConfig);
14437
14438                AttributeCache ac = AttributeCache.instance();
14439                if (ac != null) {
14440                    ac.updateConfiguration(configCopy);
14441                }
14442
14443                // Make sure all resources in our process are updated
14444                // right now, so that anyone who is going to retrieve
14445                // resource values after we return will be sure to get
14446                // the new ones.  This is especially important during
14447                // boot, where the first config change needs to guarantee
14448                // all resources have that config before following boot
14449                // code is executed.
14450                mSystemThread.applyConfigurationToResources(configCopy);
14451
14452                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14453                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14454                    msg.obj = new Configuration(configCopy);
14455                    mHandler.sendMessage(msg);
14456                }
14457
14458                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14459                    ProcessRecord app = mLruProcesses.get(i);
14460                    try {
14461                        if (app.thread != null) {
14462                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14463                                    + app.processName + " new config " + mConfiguration);
14464                            app.thread.scheduleConfigurationChanged(configCopy);
14465                        }
14466                    } catch (Exception e) {
14467                    }
14468                }
14469                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14470                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14471                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14472                        | Intent.FLAG_RECEIVER_FOREGROUND);
14473                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14474                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14475                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14476                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14477                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14478                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14479                    broadcastIntentLocked(null, null, intent,
14480                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14481                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14482                }
14483            }
14484        }
14485
14486        boolean kept = true;
14487        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14488        // mainStack is null during startup.
14489        if (mainStack != null) {
14490            if (changes != 0 && starting == null) {
14491                // If the configuration changed, and the caller is not already
14492                // in the process of starting an activity, then find the top
14493                // activity to check if its configuration needs to change.
14494                starting = mainStack.topRunningActivityLocked(null);
14495            }
14496
14497            if (starting != null) {
14498                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14499                // And we need to make sure at this point that all other activities
14500                // are made visible with the correct configuration.
14501                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14502            }
14503        }
14504
14505        if (values != null && mWindowManager != null) {
14506            mWindowManager.setNewConfiguration(mConfiguration);
14507        }
14508
14509        return kept;
14510    }
14511
14512    /**
14513     * Decide based on the configuration whether we should shouw the ANR,
14514     * crash, etc dialogs.  The idea is that if there is no affordnace to
14515     * press the on-screen buttons, we shouldn't show the dialog.
14516     *
14517     * A thought: SystemUI might also want to get told about this, the Power
14518     * dialog / global actions also might want different behaviors.
14519     */
14520    private static final boolean shouldShowDialogs(Configuration config) {
14521        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14522                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14523    }
14524
14525    /**
14526     * Save the locale.  You must be inside a synchronized (this) block.
14527     */
14528    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14529        if(isDiff) {
14530            SystemProperties.set("user.language", l.getLanguage());
14531            SystemProperties.set("user.region", l.getCountry());
14532        }
14533
14534        if(isPersist) {
14535            SystemProperties.set("persist.sys.language", l.getLanguage());
14536            SystemProperties.set("persist.sys.country", l.getCountry());
14537            SystemProperties.set("persist.sys.localevar", l.getVariant());
14538        }
14539    }
14540
14541    @Override
14542    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14543        ActivityRecord srec = ActivityRecord.forToken(token);
14544        return srec != null && srec.task.affinity != null &&
14545                srec.task.affinity.equals(destAffinity);
14546    }
14547
14548    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14549            Intent resultData) {
14550
14551        synchronized (this) {
14552            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14553            if (stack != null) {
14554                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14555            }
14556            return false;
14557        }
14558    }
14559
14560    public int getLaunchedFromUid(IBinder activityToken) {
14561        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14562        if (srec == null) {
14563            return -1;
14564        }
14565        return srec.launchedFromUid;
14566    }
14567
14568    public String getLaunchedFromPackage(IBinder activityToken) {
14569        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14570        if (srec == null) {
14571            return null;
14572        }
14573        return srec.launchedFromPackage;
14574    }
14575
14576    // =========================================================
14577    // LIFETIME MANAGEMENT
14578    // =========================================================
14579
14580    // Returns which broadcast queue the app is the current [or imminent] receiver
14581    // on, or 'null' if the app is not an active broadcast recipient.
14582    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14583        BroadcastRecord r = app.curReceiver;
14584        if (r != null) {
14585            return r.queue;
14586        }
14587
14588        // It's not the current receiver, but it might be starting up to become one
14589        synchronized (this) {
14590            for (BroadcastQueue queue : mBroadcastQueues) {
14591                r = queue.mPendingBroadcast;
14592                if (r != null && r.curApp == app) {
14593                    // found it; report which queue it's in
14594                    return queue;
14595                }
14596            }
14597        }
14598
14599        return null;
14600    }
14601
14602    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14603            boolean doingAll, long now) {
14604        if (mAdjSeq == app.adjSeq) {
14605            // This adjustment has already been computed.
14606            return app.curRawAdj;
14607        }
14608
14609        if (app.thread == null) {
14610            app.adjSeq = mAdjSeq;
14611            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14612            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14613            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14614        }
14615
14616        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14617        app.adjSource = null;
14618        app.adjTarget = null;
14619        app.empty = false;
14620        app.cached = false;
14621
14622        final int activitiesSize = app.activities.size();
14623
14624        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14625            // The max adjustment doesn't allow this app to be anything
14626            // below foreground, so it is not worth doing work for it.
14627            app.adjType = "fixed";
14628            app.adjSeq = mAdjSeq;
14629            app.curRawAdj = app.maxAdj;
14630            app.foregroundActivities = false;
14631            app.keeping = true;
14632            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14633            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14634            // System process can do UI, and when they do we want to have
14635            // them trim their memory after the user leaves the UI.  To
14636            // facilitate this, here we need to determine whether or not it
14637            // is currently showing UI.
14638            app.systemNoUi = true;
14639            if (app == TOP_APP) {
14640                app.systemNoUi = false;
14641            } else if (activitiesSize > 0) {
14642                for (int j = 0; j < activitiesSize; j++) {
14643                    final ActivityRecord r = app.activities.get(j);
14644                    if (r.visible) {
14645                        app.systemNoUi = false;
14646                    }
14647                }
14648            }
14649            if (!app.systemNoUi) {
14650                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14651            }
14652            return (app.curAdj=app.maxAdj);
14653        }
14654
14655        app.keeping = false;
14656        app.systemNoUi = false;
14657
14658        // Determine the importance of the process, starting with most
14659        // important to least, and assign an appropriate OOM adjustment.
14660        int adj;
14661        int schedGroup;
14662        int procState;
14663        boolean foregroundActivities = false;
14664        boolean interesting = false;
14665        BroadcastQueue queue;
14666        if (app == TOP_APP) {
14667            // The last app on the list is the foreground app.
14668            adj = ProcessList.FOREGROUND_APP_ADJ;
14669            schedGroup = Process.THREAD_GROUP_DEFAULT;
14670            app.adjType = "top-activity";
14671            foregroundActivities = true;
14672            interesting = true;
14673            procState = ActivityManager.PROCESS_STATE_TOP;
14674        } else if (app.instrumentationClass != null) {
14675            // Don't want to kill running instrumentation.
14676            adj = ProcessList.FOREGROUND_APP_ADJ;
14677            schedGroup = Process.THREAD_GROUP_DEFAULT;
14678            app.adjType = "instrumentation";
14679            interesting = true;
14680            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14681        } else if ((queue = isReceivingBroadcast(app)) != null) {
14682            // An app that is currently receiving a broadcast also
14683            // counts as being in the foreground for OOM killer purposes.
14684            // It's placed in a sched group based on the nature of the
14685            // broadcast as reflected by which queue it's active in.
14686            adj = ProcessList.FOREGROUND_APP_ADJ;
14687            schedGroup = (queue == mFgBroadcastQueue)
14688                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14689            app.adjType = "broadcast";
14690            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14691        } else if (app.executingServices.size() > 0) {
14692            // An app that is currently executing a service callback also
14693            // counts as being in the foreground.
14694            adj = ProcessList.FOREGROUND_APP_ADJ;
14695            schedGroup = app.execServicesFg ?
14696                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14697            app.adjType = "exec-service";
14698            procState = ActivityManager.PROCESS_STATE_SERVICE;
14699            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14700        } else {
14701            // As far as we know the process is empty.  We may change our mind later.
14702            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14703            // At this point we don't actually know the adjustment.  Use the cached adj
14704            // value that the caller wants us to.
14705            adj = cachedAdj;
14706            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14707            app.cached = true;
14708            app.empty = true;
14709            app.adjType = "cch-empty";
14710        }
14711
14712        // Examine all activities if not already foreground.
14713        if (!foregroundActivities && activitiesSize > 0) {
14714            for (int j = 0; j < activitiesSize; j++) {
14715                final ActivityRecord r = app.activities.get(j);
14716                if (r.app != app) {
14717                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14718                            + app + "?!?");
14719                    continue;
14720                }
14721                if (r.visible) {
14722                    // App has a visible activity; only upgrade adjustment.
14723                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14724                        adj = ProcessList.VISIBLE_APP_ADJ;
14725                        app.adjType = "visible";
14726                    }
14727                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14728                        procState = ActivityManager.PROCESS_STATE_TOP;
14729                    }
14730                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14731                    app.cached = false;
14732                    app.empty = false;
14733                    foregroundActivities = true;
14734                    break;
14735                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14736                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14737                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14738                        app.adjType = "pausing";
14739                    }
14740                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14741                        procState = ActivityManager.PROCESS_STATE_TOP;
14742                    }
14743                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14744                    app.cached = false;
14745                    app.empty = false;
14746                    foregroundActivities = true;
14747                } else if (r.state == ActivityState.STOPPING) {
14748                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14749                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14750                        app.adjType = "stopping";
14751                    }
14752                    // For the process state, we will at this point consider the
14753                    // process to be cached.  It will be cached either as an activity
14754                    // or empty depending on whether the activity is finishing.  We do
14755                    // this so that we can treat the process as cached for purposes of
14756                    // memory trimming (determing current memory level, trim command to
14757                    // send to process) since there can be an arbitrary number of stopping
14758                    // processes and they should soon all go into the cached state.
14759                    if (!r.finishing) {
14760                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14761                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14762                        }
14763                    }
14764                    app.cached = false;
14765                    app.empty = false;
14766                    foregroundActivities = true;
14767                } else {
14768                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14769                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14770                        app.adjType = "cch-act";
14771                    }
14772                }
14773            }
14774        }
14775
14776        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14777            if (app.foregroundServices) {
14778                // The user is aware of this app, so make it visible.
14779                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14780                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14781                app.cached = false;
14782                app.adjType = "fg-service";
14783                schedGroup = Process.THREAD_GROUP_DEFAULT;
14784            } else if (app.forcingToForeground != null) {
14785                // The user is aware of this app, so make it visible.
14786                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14787                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14788                app.cached = false;
14789                app.adjType = "force-fg";
14790                app.adjSource = app.forcingToForeground;
14791                schedGroup = Process.THREAD_GROUP_DEFAULT;
14792            }
14793        }
14794
14795        if (app.foregroundServices) {
14796            interesting = true;
14797        }
14798
14799        if (app == mHeavyWeightProcess) {
14800            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14801                // We don't want to kill the current heavy-weight process.
14802                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14803                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14804                app.cached = false;
14805                app.adjType = "heavy";
14806            }
14807            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14808                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14809            }
14810        }
14811
14812        if (app == mHomeProcess) {
14813            if (adj > ProcessList.HOME_APP_ADJ) {
14814                // This process is hosting what we currently consider to be the
14815                // home app, so we don't want to let it go into the background.
14816                adj = ProcessList.HOME_APP_ADJ;
14817                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14818                app.cached = false;
14819                app.adjType = "home";
14820            }
14821            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14822                procState = ActivityManager.PROCESS_STATE_HOME;
14823            }
14824        }
14825
14826        if (app == mPreviousProcess && app.activities.size() > 0) {
14827            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14828                // This was the previous process that showed UI to the user.
14829                // We want to try to keep it around more aggressively, to give
14830                // a good experience around switching between two apps.
14831                adj = ProcessList.PREVIOUS_APP_ADJ;
14832                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14833                app.cached = false;
14834                app.adjType = "previous";
14835            }
14836            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14837                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14838            }
14839        }
14840
14841        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14842                + " reason=" + app.adjType);
14843
14844        // By default, we use the computed adjustment.  It may be changed if
14845        // there are applications dependent on our services or providers, but
14846        // this gives us a baseline and makes sure we don't get into an
14847        // infinite recursion.
14848        app.adjSeq = mAdjSeq;
14849        app.curRawAdj = adj;
14850        app.hasStartedServices = false;
14851
14852        if (mBackupTarget != null && app == mBackupTarget.app) {
14853            // If possible we want to avoid killing apps while they're being backed up
14854            if (adj > ProcessList.BACKUP_APP_ADJ) {
14855                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14856                adj = ProcessList.BACKUP_APP_ADJ;
14857                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14858                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14859                }
14860                app.adjType = "backup";
14861                app.cached = false;
14862            }
14863            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14864                procState = ActivityManager.PROCESS_STATE_BACKUP;
14865            }
14866        }
14867
14868        boolean mayBeTop = false;
14869
14870        for (int is = app.services.size()-1;
14871                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14872                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14873                        || procState > ActivityManager.PROCESS_STATE_TOP);
14874                is--) {
14875            ServiceRecord s = app.services.valueAt(is);
14876            if (s.startRequested) {
14877                app.hasStartedServices = true;
14878                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14879                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14880                }
14881                if (app.hasShownUi && app != mHomeProcess) {
14882                    // If this process has shown some UI, let it immediately
14883                    // go to the LRU list because it may be pretty heavy with
14884                    // UI stuff.  We'll tag it with a label just to help
14885                    // debug and understand what is going on.
14886                    if (adj > ProcessList.SERVICE_ADJ) {
14887                        app.adjType = "cch-started-ui-services";
14888                    }
14889                } else {
14890                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14891                        // This service has seen some activity within
14892                        // recent memory, so we will keep its process ahead
14893                        // of the background processes.
14894                        if (adj > ProcessList.SERVICE_ADJ) {
14895                            adj = ProcessList.SERVICE_ADJ;
14896                            app.adjType = "started-services";
14897                            app.cached = false;
14898                        }
14899                    }
14900                    // If we have let the service slide into the background
14901                    // state, still have some text describing what it is doing
14902                    // even though the service no longer has an impact.
14903                    if (adj > ProcessList.SERVICE_ADJ) {
14904                        app.adjType = "cch-started-services";
14905                    }
14906                }
14907                // Don't kill this process because it is doing work; it
14908                // has said it is doing work.
14909                app.keeping = true;
14910            }
14911            for (int conni = s.connections.size()-1;
14912                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14913                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14914                            || procState > ActivityManager.PROCESS_STATE_TOP);
14915                    conni--) {
14916                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14917                for (int i = 0;
14918                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14919                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14920                                || procState > ActivityManager.PROCESS_STATE_TOP);
14921                        i++) {
14922                    // XXX should compute this based on the max of
14923                    // all connected clients.
14924                    ConnectionRecord cr = clist.get(i);
14925                    if (cr.binding.client == app) {
14926                        // Binding to ourself is not interesting.
14927                        continue;
14928                    }
14929                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14930                        ProcessRecord client = cr.binding.client;
14931                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14932                                TOP_APP, doingAll, now);
14933                        int clientProcState = client.curProcState;
14934                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14935                            // If the other app is cached for any reason, for purposes here
14936                            // we are going to consider it empty.  The specific cached state
14937                            // doesn't propagate except under certain conditions.
14938                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14939                        }
14940                        String adjType = null;
14941                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14942                            // Not doing bind OOM management, so treat
14943                            // this guy more like a started service.
14944                            if (app.hasShownUi && app != mHomeProcess) {
14945                                // If this process has shown some UI, let it immediately
14946                                // go to the LRU list because it may be pretty heavy with
14947                                // UI stuff.  We'll tag it with a label just to help
14948                                // debug and understand what is going on.
14949                                if (adj > clientAdj) {
14950                                    adjType = "cch-bound-ui-services";
14951                                }
14952                                app.cached = false;
14953                                clientAdj = adj;
14954                                clientProcState = procState;
14955                            } else {
14956                                if (now >= (s.lastActivity
14957                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14958                                    // This service has not seen activity within
14959                                    // recent memory, so allow it to drop to the
14960                                    // LRU list if there is no other reason to keep
14961                                    // it around.  We'll also tag it with a label just
14962                                    // to help debug and undertand what is going on.
14963                                    if (adj > clientAdj) {
14964                                        adjType = "cch-bound-services";
14965                                    }
14966                                    clientAdj = adj;
14967                                }
14968                            }
14969                        }
14970                        if (adj > clientAdj) {
14971                            // If this process has recently shown UI, and
14972                            // the process that is binding to it is less
14973                            // important than being visible, then we don't
14974                            // care about the binding as much as we care
14975                            // about letting this process get into the LRU
14976                            // list to be killed and restarted if needed for
14977                            // memory.
14978                            if (app.hasShownUi && app != mHomeProcess
14979                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14980                                adjType = "cch-bound-ui-services";
14981                            } else {
14982                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14983                                        |Context.BIND_IMPORTANT)) != 0) {
14984                                    adj = clientAdj;
14985                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14986                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14987                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14988                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14989                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14990                                    adj = clientAdj;
14991                                } else {
14992                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14993                                        adj = ProcessList.VISIBLE_APP_ADJ;
14994                                    }
14995                                }
14996                                if (!client.cached) {
14997                                    app.cached = false;
14998                                }
14999                                if (client.keeping) {
15000                                    app.keeping = true;
15001                                }
15002                                adjType = "service";
15003                            }
15004                        }
15005                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15006                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15007                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15008                            }
15009                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15010                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15011                                    // Special handling of clients who are in the top state.
15012                                    // We *may* want to consider this process to be in the
15013                                    // top state as well, but only if there is not another
15014                                    // reason for it to be running.  Being on the top is a
15015                                    // special state, meaning you are specifically running
15016                                    // for the current top app.  If the process is already
15017                                    // running in the background for some other reason, it
15018                                    // is more important to continue considering it to be
15019                                    // in the background state.
15020                                    mayBeTop = true;
15021                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15022                                } else {
15023                                    // Special handling for above-top states (persistent
15024                                    // processes).  These should not bring the current process
15025                                    // into the top state, since they are not on top.  Instead
15026                                    // give them the best state after that.
15027                                    clientProcState =
15028                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15029                                }
15030                            }
15031                        } else {
15032                            if (clientProcState <
15033                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15034                                clientProcState =
15035                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15036                            }
15037                        }
15038                        if (procState > clientProcState) {
15039                            procState = clientProcState;
15040                        }
15041                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15042                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15043                            app.pendingUiClean = true;
15044                        }
15045                        if (adjType != null) {
15046                            app.adjType = adjType;
15047                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15048                                    .REASON_SERVICE_IN_USE;
15049                            app.adjSource = cr.binding.client;
15050                            app.adjSourceOom = clientAdj;
15051                            app.adjTarget = s.name;
15052                        }
15053                    }
15054                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15055                        app.treatLikeActivity = true;
15056                    }
15057                    final ActivityRecord a = cr.activity;
15058                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15059                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15060                                (a.visible || a.state == ActivityState.RESUMED
15061                                 || a.state == ActivityState.PAUSING)) {
15062                            adj = ProcessList.FOREGROUND_APP_ADJ;
15063                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15064                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15065                            }
15066                            app.cached = false;
15067                            app.adjType = "service";
15068                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15069                                    .REASON_SERVICE_IN_USE;
15070                            app.adjSource = a;
15071                            app.adjSourceOom = adj;
15072                            app.adjTarget = s.name;
15073                        }
15074                    }
15075                }
15076            }
15077        }
15078
15079        for (int provi = app.pubProviders.size()-1;
15080                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15081                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15082                        || procState > ActivityManager.PROCESS_STATE_TOP);
15083                provi--) {
15084            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15085            for (int i = cpr.connections.size()-1;
15086                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15087                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15088                            || procState > ActivityManager.PROCESS_STATE_TOP);
15089                    i--) {
15090                ContentProviderConnection conn = cpr.connections.get(i);
15091                ProcessRecord client = conn.client;
15092                if (client == app) {
15093                    // Being our own client is not interesting.
15094                    continue;
15095                }
15096                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15097                int clientProcState = client.curProcState;
15098                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15099                    // If the other app is cached for any reason, for purposes here
15100                    // we are going to consider it empty.
15101                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15102                }
15103                if (adj > clientAdj) {
15104                    if (app.hasShownUi && app != mHomeProcess
15105                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15106                        app.adjType = "cch-ui-provider";
15107                    } else {
15108                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15109                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15110                        app.adjType = "provider";
15111                    }
15112                    app.cached &= client.cached;
15113                    app.keeping |= client.keeping;
15114                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15115                            .REASON_PROVIDER_IN_USE;
15116                    app.adjSource = client;
15117                    app.adjSourceOom = clientAdj;
15118                    app.adjTarget = cpr.name;
15119                }
15120                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15121                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15122                        // Special handling of clients who are in the top state.
15123                        // We *may* want to consider this process to be in the
15124                        // top state as well, but only if there is not another
15125                        // reason for it to be running.  Being on the top is a
15126                        // special state, meaning you are specifically running
15127                        // for the current top app.  If the process is already
15128                        // running in the background for some other reason, it
15129                        // is more important to continue considering it to be
15130                        // in the background state.
15131                        mayBeTop = true;
15132                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15133                    } else {
15134                        // Special handling for above-top states (persistent
15135                        // processes).  These should not bring the current process
15136                        // into the top state, since they are not on top.  Instead
15137                        // give them the best state after that.
15138                        clientProcState =
15139                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15140                    }
15141                }
15142                if (procState > clientProcState) {
15143                    procState = clientProcState;
15144                }
15145                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15146                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15147                }
15148            }
15149            // If the provider has external (non-framework) process
15150            // dependencies, ensure that its adjustment is at least
15151            // FOREGROUND_APP_ADJ.
15152            if (cpr.hasExternalProcessHandles()) {
15153                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15154                    adj = ProcessList.FOREGROUND_APP_ADJ;
15155                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15156                    app.cached = false;
15157                    app.keeping = true;
15158                    app.adjType = "provider";
15159                    app.adjTarget = cpr.name;
15160                }
15161                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15162                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15163                }
15164            }
15165        }
15166
15167        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15168            // A client of one of our services or providers is in the top state.  We
15169            // *may* want to be in the top state, but not if we are already running in
15170            // the background for some other reason.  For the decision here, we are going
15171            // to pick out a few specific states that we want to remain in when a client
15172            // is top (states that tend to be longer-term) and otherwise allow it to go
15173            // to the top state.
15174            switch (procState) {
15175                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15176                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15177                case ActivityManager.PROCESS_STATE_SERVICE:
15178                    // These all are longer-term states, so pull them up to the top
15179                    // of the background states, but not all the way to the top state.
15180                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15181                    break;
15182                default:
15183                    // Otherwise, top is a better choice, so take it.
15184                    procState = ActivityManager.PROCESS_STATE_TOP;
15185                    break;
15186            }
15187        }
15188
15189        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15190            if (app.hasClientActivities) {
15191                // This is a cached process, but with client activities.  Mark it so.
15192                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15193                app.adjType = "cch-client-act";
15194            } else if (app.treatLikeActivity) {
15195                // This is a cached process, but somebody wants us to treat it like it has
15196                // an activity, okay!
15197                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15198                app.adjType = "cch-as-act";
15199            }
15200        }
15201
15202        if (adj == ProcessList.SERVICE_ADJ) {
15203            if (doingAll) {
15204                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15205                mNewNumServiceProcs++;
15206                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15207                if (!app.serviceb) {
15208                    // This service isn't far enough down on the LRU list to
15209                    // normally be a B service, but if we are low on RAM and it
15210                    // is large we want to force it down since we would prefer to
15211                    // keep launcher over it.
15212                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15213                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15214                        app.serviceHighRam = true;
15215                        app.serviceb = true;
15216                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15217                    } else {
15218                        mNewNumAServiceProcs++;
15219                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15220                    }
15221                } else {
15222                    app.serviceHighRam = false;
15223                }
15224            }
15225            if (app.serviceb) {
15226                adj = ProcessList.SERVICE_B_ADJ;
15227            }
15228        }
15229
15230        app.curRawAdj = adj;
15231
15232        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15233        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15234        if (adj > app.maxAdj) {
15235            adj = app.maxAdj;
15236            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15237                schedGroup = Process.THREAD_GROUP_DEFAULT;
15238            }
15239        }
15240        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15241            app.keeping = true;
15242        }
15243
15244        // Do final modification to adj.  Everything we do between here and applying
15245        // the final setAdj must be done in this function, because we will also use
15246        // it when computing the final cached adj later.  Note that we don't need to
15247        // worry about this for max adj above, since max adj will always be used to
15248        // keep it out of the cached vaues.
15249        adj = app.modifyRawOomAdj(adj);
15250
15251        app.curProcState = procState;
15252
15253        int importance = app.memImportance;
15254        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15255            app.curAdj = adj;
15256            app.curSchedGroup = schedGroup;
15257            if (!interesting) {
15258                // For this reporting, if there is not something explicitly
15259                // interesting in this process then we will push it to the
15260                // background importance.
15261                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15262            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15263                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15264            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15265                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15266            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15267                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15268            } else if (adj >= ProcessList.SERVICE_ADJ) {
15269                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15270            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15271                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15272            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15273                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15274            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15275                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15276            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15277                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15278            } else {
15279                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15280            }
15281        }
15282
15283        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15284        if (foregroundActivities != app.foregroundActivities) {
15285            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15286        }
15287        if (changes != 0) {
15288            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15289            app.memImportance = importance;
15290            app.foregroundActivities = foregroundActivities;
15291            int i = mPendingProcessChanges.size()-1;
15292            ProcessChangeItem item = null;
15293            while (i >= 0) {
15294                item = mPendingProcessChanges.get(i);
15295                if (item.pid == app.pid) {
15296                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15297                    break;
15298                }
15299                i--;
15300            }
15301            if (i < 0) {
15302                // No existing item in pending changes; need a new one.
15303                final int NA = mAvailProcessChanges.size();
15304                if (NA > 0) {
15305                    item = mAvailProcessChanges.remove(NA-1);
15306                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15307                } else {
15308                    item = new ProcessChangeItem();
15309                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15310                }
15311                item.changes = 0;
15312                item.pid = app.pid;
15313                item.uid = app.info.uid;
15314                if (mPendingProcessChanges.size() == 0) {
15315                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15316                            "*** Enqueueing dispatch processes changed!");
15317                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15318                }
15319                mPendingProcessChanges.add(item);
15320            }
15321            item.changes |= changes;
15322            item.importance = importance;
15323            item.foregroundActivities = foregroundActivities;
15324            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15325                    + Integer.toHexString(System.identityHashCode(item))
15326                    + " " + app.toShortString() + ": changes=" + item.changes
15327                    + " importance=" + item.importance
15328                    + " foreground=" + item.foregroundActivities
15329                    + " type=" + app.adjType + " source=" + app.adjSource
15330                    + " target=" + app.adjTarget);
15331        }
15332
15333        return app.curRawAdj;
15334    }
15335
15336    /**
15337     * Schedule PSS collection of a process.
15338     */
15339    void requestPssLocked(ProcessRecord proc, int procState) {
15340        if (mPendingPssProcesses.contains(proc)) {
15341            return;
15342        }
15343        if (mPendingPssProcesses.size() == 0) {
15344            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15345        }
15346        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15347        proc.pssProcState = procState;
15348        mPendingPssProcesses.add(proc);
15349    }
15350
15351    /**
15352     * Schedule PSS collection of all processes.
15353     */
15354    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15355        if (!always) {
15356            if (now < (mLastFullPssTime +
15357                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15358                return;
15359            }
15360        }
15361        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15362        mLastFullPssTime = now;
15363        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15364        mPendingPssProcesses.clear();
15365        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15366            ProcessRecord app = mLruProcesses.get(i);
15367            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15368                app.pssProcState = app.setProcState;
15369                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15370                        isSleeping(), now);
15371                mPendingPssProcesses.add(app);
15372            }
15373        }
15374        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15375    }
15376
15377    /**
15378     * Ask a given process to GC right now.
15379     */
15380    final void performAppGcLocked(ProcessRecord app) {
15381        try {
15382            app.lastRequestedGc = SystemClock.uptimeMillis();
15383            if (app.thread != null) {
15384                if (app.reportLowMemory) {
15385                    app.reportLowMemory = false;
15386                    app.thread.scheduleLowMemory();
15387                } else {
15388                    app.thread.processInBackground();
15389                }
15390            }
15391        } catch (Exception e) {
15392            // whatever.
15393        }
15394    }
15395
15396    /**
15397     * Returns true if things are idle enough to perform GCs.
15398     */
15399    private final boolean canGcNowLocked() {
15400        boolean processingBroadcasts = false;
15401        for (BroadcastQueue q : mBroadcastQueues) {
15402            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15403                processingBroadcasts = true;
15404            }
15405        }
15406        return !processingBroadcasts
15407                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15408    }
15409
15410    /**
15411     * Perform GCs on all processes that are waiting for it, but only
15412     * if things are idle.
15413     */
15414    final void performAppGcsLocked() {
15415        final int N = mProcessesToGc.size();
15416        if (N <= 0) {
15417            return;
15418        }
15419        if (canGcNowLocked()) {
15420            while (mProcessesToGc.size() > 0) {
15421                ProcessRecord proc = mProcessesToGc.remove(0);
15422                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15423                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15424                            <= SystemClock.uptimeMillis()) {
15425                        // To avoid spamming the system, we will GC processes one
15426                        // at a time, waiting a few seconds between each.
15427                        performAppGcLocked(proc);
15428                        scheduleAppGcsLocked();
15429                        return;
15430                    } else {
15431                        // It hasn't been long enough since we last GCed this
15432                        // process...  put it in the list to wait for its time.
15433                        addProcessToGcListLocked(proc);
15434                        break;
15435                    }
15436                }
15437            }
15438
15439            scheduleAppGcsLocked();
15440        }
15441    }
15442
15443    /**
15444     * If all looks good, perform GCs on all processes waiting for them.
15445     */
15446    final void performAppGcsIfAppropriateLocked() {
15447        if (canGcNowLocked()) {
15448            performAppGcsLocked();
15449            return;
15450        }
15451        // Still not idle, wait some more.
15452        scheduleAppGcsLocked();
15453    }
15454
15455    /**
15456     * Schedule the execution of all pending app GCs.
15457     */
15458    final void scheduleAppGcsLocked() {
15459        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15460
15461        if (mProcessesToGc.size() > 0) {
15462            // Schedule a GC for the time to the next process.
15463            ProcessRecord proc = mProcessesToGc.get(0);
15464            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15465
15466            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15467            long now = SystemClock.uptimeMillis();
15468            if (when < (now+GC_TIMEOUT)) {
15469                when = now + GC_TIMEOUT;
15470            }
15471            mHandler.sendMessageAtTime(msg, when);
15472        }
15473    }
15474
15475    /**
15476     * Add a process to the array of processes waiting to be GCed.  Keeps the
15477     * list in sorted order by the last GC time.  The process can't already be
15478     * on the list.
15479     */
15480    final void addProcessToGcListLocked(ProcessRecord proc) {
15481        boolean added = false;
15482        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15483            if (mProcessesToGc.get(i).lastRequestedGc <
15484                    proc.lastRequestedGc) {
15485                added = true;
15486                mProcessesToGc.add(i+1, proc);
15487                break;
15488            }
15489        }
15490        if (!added) {
15491            mProcessesToGc.add(0, proc);
15492        }
15493    }
15494
15495    /**
15496     * Set up to ask a process to GC itself.  This will either do it
15497     * immediately, or put it on the list of processes to gc the next
15498     * time things are idle.
15499     */
15500    final void scheduleAppGcLocked(ProcessRecord app) {
15501        long now = SystemClock.uptimeMillis();
15502        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15503            return;
15504        }
15505        if (!mProcessesToGc.contains(app)) {
15506            addProcessToGcListLocked(app);
15507            scheduleAppGcsLocked();
15508        }
15509    }
15510
15511    final void checkExcessivePowerUsageLocked(boolean doKills) {
15512        updateCpuStatsNow();
15513
15514        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15515        boolean doWakeKills = doKills;
15516        boolean doCpuKills = doKills;
15517        if (mLastPowerCheckRealtime == 0) {
15518            doWakeKills = false;
15519        }
15520        if (mLastPowerCheckUptime == 0) {
15521            doCpuKills = false;
15522        }
15523        if (stats.isScreenOn()) {
15524            doWakeKills = false;
15525        }
15526        final long curRealtime = SystemClock.elapsedRealtime();
15527        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15528        final long curUptime = SystemClock.uptimeMillis();
15529        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15530        mLastPowerCheckRealtime = curRealtime;
15531        mLastPowerCheckUptime = curUptime;
15532        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15533            doWakeKills = false;
15534        }
15535        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15536            doCpuKills = false;
15537        }
15538        int i = mLruProcesses.size();
15539        while (i > 0) {
15540            i--;
15541            ProcessRecord app = mLruProcesses.get(i);
15542            if (!app.keeping) {
15543                long wtime;
15544                synchronized (stats) {
15545                    wtime = stats.getProcessWakeTime(app.info.uid,
15546                            app.pid, curRealtime);
15547                }
15548                long wtimeUsed = wtime - app.lastWakeTime;
15549                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15550                if (DEBUG_POWER) {
15551                    StringBuilder sb = new StringBuilder(128);
15552                    sb.append("Wake for ");
15553                    app.toShortString(sb);
15554                    sb.append(": over ");
15555                    TimeUtils.formatDuration(realtimeSince, sb);
15556                    sb.append(" used ");
15557                    TimeUtils.formatDuration(wtimeUsed, sb);
15558                    sb.append(" (");
15559                    sb.append((wtimeUsed*100)/realtimeSince);
15560                    sb.append("%)");
15561                    Slog.i(TAG, sb.toString());
15562                    sb.setLength(0);
15563                    sb.append("CPU for ");
15564                    app.toShortString(sb);
15565                    sb.append(": over ");
15566                    TimeUtils.formatDuration(uptimeSince, sb);
15567                    sb.append(" used ");
15568                    TimeUtils.formatDuration(cputimeUsed, sb);
15569                    sb.append(" (");
15570                    sb.append((cputimeUsed*100)/uptimeSince);
15571                    sb.append("%)");
15572                    Slog.i(TAG, sb.toString());
15573                }
15574                // If a process has held a wake lock for more
15575                // than 50% of the time during this period,
15576                // that sounds bad.  Kill!
15577                if (doWakeKills && realtimeSince > 0
15578                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15579                    synchronized (stats) {
15580                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15581                                realtimeSince, wtimeUsed);
15582                    }
15583                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15584                            + " during " + realtimeSince);
15585                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15586                } else if (doCpuKills && uptimeSince > 0
15587                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15588                    synchronized (stats) {
15589                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15590                                uptimeSince, cputimeUsed);
15591                    }
15592                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15593                            + " during " + uptimeSince);
15594                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15595                } else {
15596                    app.lastWakeTime = wtime;
15597                    app.lastCpuTime = app.curCpuTime;
15598                }
15599            }
15600        }
15601    }
15602
15603    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15604            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15605        boolean success = true;
15606
15607        if (app.curRawAdj != app.setRawAdj) {
15608            if (wasKeeping && !app.keeping) {
15609                // This app is no longer something we want to keep.  Note
15610                // its current wake lock time to later know to kill it if
15611                // it is not behaving well.
15612                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15613                synchronized (stats) {
15614                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15615                            app.pid, SystemClock.elapsedRealtime());
15616                }
15617                app.lastCpuTime = app.curCpuTime;
15618            }
15619
15620            app.setRawAdj = app.curRawAdj;
15621        }
15622
15623        if (app.curAdj != app.setAdj) {
15624            ProcessList.setOomAdj(app.pid, app.curAdj);
15625            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15626                TAG, "Set " + app.pid + " " + app.processName +
15627                " adj " + app.curAdj + ": " + app.adjType);
15628            app.setAdj = app.curAdj;
15629        }
15630
15631        if (app.setSchedGroup != app.curSchedGroup) {
15632            app.setSchedGroup = app.curSchedGroup;
15633            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15634                    "Setting process group of " + app.processName
15635                    + " to " + app.curSchedGroup);
15636            if (app.waitingToKill != null &&
15637                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15638                killUnneededProcessLocked(app, app.waitingToKill);
15639                success = false;
15640            } else {
15641                if (true) {
15642                    long oldId = Binder.clearCallingIdentity();
15643                    try {
15644                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15645                    } catch (Exception e) {
15646                        Slog.w(TAG, "Failed setting process group of " + app.pid
15647                                + " to " + app.curSchedGroup);
15648                        e.printStackTrace();
15649                    } finally {
15650                        Binder.restoreCallingIdentity(oldId);
15651                    }
15652                } else {
15653                    if (app.thread != null) {
15654                        try {
15655                            app.thread.setSchedulingGroup(app.curSchedGroup);
15656                        } catch (RemoteException e) {
15657                        }
15658                    }
15659                }
15660                Process.setSwappiness(app.pid,
15661                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15662            }
15663        }
15664        if (app.repProcState != app.curProcState) {
15665            app.repProcState = app.curProcState;
15666            if (!reportingProcessState && app.thread != null) {
15667                try {
15668                    if (false) {
15669                        //RuntimeException h = new RuntimeException("here");
15670                        Slog.i(TAG, "Sending new process state " + app.repProcState
15671                                + " to " + app /*, h*/);
15672                    }
15673                    app.thread.setProcessState(app.repProcState);
15674                } catch (RemoteException e) {
15675                }
15676            }
15677        }
15678        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15679                app.setProcState)) {
15680            app.lastStateTime = now;
15681            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15682                    isSleeping(), now);
15683            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15684                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15685                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15686                    + (app.nextPssTime-now) + ": " + app);
15687        } else {
15688            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15689                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15690                requestPssLocked(app, app.setProcState);
15691                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15692                        isSleeping(), now);
15693            } else if (false && DEBUG_PSS) {
15694                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15695            }
15696        }
15697        if (app.setProcState != app.curProcState) {
15698            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15699                    "Proc state change of " + app.processName
15700                    + " to " + app.curProcState);
15701            app.setProcState = app.curProcState;
15702            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15703                app.notCachedSinceIdle = false;
15704            }
15705            if (!doingAll) {
15706                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15707            } else {
15708                app.procStateChanged = true;
15709            }
15710        }
15711        return success;
15712    }
15713
15714    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15715        if (proc.thread != null && proc.baseProcessTracker != null) {
15716            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15717        }
15718    }
15719
15720    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15721            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15722        if (app.thread == null) {
15723            return false;
15724        }
15725
15726        final boolean wasKeeping = app.keeping;
15727
15728        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15729
15730        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15731                reportingProcessState, now);
15732    }
15733
15734    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15735            boolean oomAdj) {
15736        if (isForeground != proc.foregroundServices) {
15737            proc.foregroundServices = isForeground;
15738            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15739                    proc.info.uid);
15740            if (isForeground) {
15741                if (curProcs == null) {
15742                    curProcs = new ArrayList<ProcessRecord>();
15743                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15744                }
15745                if (!curProcs.contains(proc)) {
15746                    curProcs.add(proc);
15747                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15748                            proc.info.packageName, proc.info.uid);
15749                }
15750            } else {
15751                if (curProcs != null) {
15752                    if (curProcs.remove(proc)) {
15753                        mBatteryStatsService.noteEvent(
15754                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15755                                proc.info.packageName, proc.info.uid);
15756                        if (curProcs.size() <= 0) {
15757                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15758                        }
15759                    }
15760                }
15761            }
15762            if (oomAdj) {
15763                updateOomAdjLocked();
15764            }
15765        }
15766    }
15767
15768    private final ActivityRecord resumedAppLocked() {
15769        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15770        String pkg;
15771        int uid;
15772        if (act != null && !act.sleeping) {
15773            pkg = act.packageName;
15774            uid = act.info.applicationInfo.uid;
15775        } else {
15776            pkg = null;
15777            uid = -1;
15778        }
15779        // Has the UID or resumed package name changed?
15780        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15781                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15782            if (mCurResumedPackage != null) {
15783                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15784                        mCurResumedPackage, mCurResumedUid);
15785            }
15786            mCurResumedPackage = pkg;
15787            mCurResumedUid = uid;
15788            if (mCurResumedPackage != null) {
15789                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15790                        mCurResumedPackage, mCurResumedUid);
15791            }
15792        }
15793        return act;
15794    }
15795
15796    final boolean updateOomAdjLocked(ProcessRecord app) {
15797        return updateOomAdjLocked(app, false);
15798    }
15799
15800    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15801        final ActivityRecord TOP_ACT = resumedAppLocked();
15802        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15803        final boolean wasCached = app.cached;
15804
15805        mAdjSeq++;
15806
15807        // This is the desired cached adjusment we want to tell it to use.
15808        // If our app is currently cached, we know it, and that is it.  Otherwise,
15809        // we don't know it yet, and it needs to now be cached we will then
15810        // need to do a complete oom adj.
15811        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15812                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15813        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15814                SystemClock.uptimeMillis());
15815        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15816            // Changed to/from cached state, so apps after it in the LRU
15817            // list may also be changed.
15818            updateOomAdjLocked();
15819        }
15820        return success;
15821    }
15822
15823    final void updateOomAdjLocked() {
15824        final ActivityRecord TOP_ACT = resumedAppLocked();
15825        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15826        final long now = SystemClock.uptimeMillis();
15827        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15828        final int N = mLruProcesses.size();
15829
15830        if (false) {
15831            RuntimeException e = new RuntimeException();
15832            e.fillInStackTrace();
15833            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15834        }
15835
15836        mAdjSeq++;
15837        mNewNumServiceProcs = 0;
15838        mNewNumAServiceProcs = 0;
15839
15840        final int emptyProcessLimit;
15841        final int cachedProcessLimit;
15842        if (mProcessLimit <= 0) {
15843            emptyProcessLimit = cachedProcessLimit = 0;
15844        } else if (mProcessLimit == 1) {
15845            emptyProcessLimit = 1;
15846            cachedProcessLimit = 0;
15847        } else {
15848            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15849            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15850        }
15851
15852        // Let's determine how many processes we have running vs.
15853        // how many slots we have for background processes; we may want
15854        // to put multiple processes in a slot of there are enough of
15855        // them.
15856        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15857                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15858        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15859        if (numEmptyProcs > cachedProcessLimit) {
15860            // If there are more empty processes than our limit on cached
15861            // processes, then use the cached process limit for the factor.
15862            // This ensures that the really old empty processes get pushed
15863            // down to the bottom, so if we are running low on memory we will
15864            // have a better chance at keeping around more cached processes
15865            // instead of a gazillion empty processes.
15866            numEmptyProcs = cachedProcessLimit;
15867        }
15868        int emptyFactor = numEmptyProcs/numSlots;
15869        if (emptyFactor < 1) emptyFactor = 1;
15870        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15871        if (cachedFactor < 1) cachedFactor = 1;
15872        int stepCached = 0;
15873        int stepEmpty = 0;
15874        int numCached = 0;
15875        int numEmpty = 0;
15876        int numTrimming = 0;
15877
15878        mNumNonCachedProcs = 0;
15879        mNumCachedHiddenProcs = 0;
15880
15881        // First update the OOM adjustment for each of the
15882        // application processes based on their current state.
15883        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15884        int nextCachedAdj = curCachedAdj+1;
15885        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15886        int nextEmptyAdj = curEmptyAdj+2;
15887        for (int i=N-1; i>=0; i--) {
15888            ProcessRecord app = mLruProcesses.get(i);
15889            if (!app.killedByAm && app.thread != null) {
15890                app.procStateChanged = false;
15891                final boolean wasKeeping = app.keeping;
15892                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15893
15894                // If we haven't yet assigned the final cached adj
15895                // to the process, do that now.
15896                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15897                    switch (app.curProcState) {
15898                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15899                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15900                            // This process is a cached process holding activities...
15901                            // assign it the next cached value for that type, and then
15902                            // step that cached level.
15903                            app.curRawAdj = curCachedAdj;
15904                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15905                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15906                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15907                                    + ")");
15908                            if (curCachedAdj != nextCachedAdj) {
15909                                stepCached++;
15910                                if (stepCached >= cachedFactor) {
15911                                    stepCached = 0;
15912                                    curCachedAdj = nextCachedAdj;
15913                                    nextCachedAdj += 2;
15914                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15915                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15916                                    }
15917                                }
15918                            }
15919                            break;
15920                        default:
15921                            // For everything else, assign next empty cached process
15922                            // level and bump that up.  Note that this means that
15923                            // long-running services that have dropped down to the
15924                            // cached level will be treated as empty (since their process
15925                            // state is still as a service), which is what we want.
15926                            app.curRawAdj = curEmptyAdj;
15927                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15928                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15929                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15930                                    + ")");
15931                            if (curEmptyAdj != nextEmptyAdj) {
15932                                stepEmpty++;
15933                                if (stepEmpty >= emptyFactor) {
15934                                    stepEmpty = 0;
15935                                    curEmptyAdj = nextEmptyAdj;
15936                                    nextEmptyAdj += 2;
15937                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15938                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15939                                    }
15940                                }
15941                            }
15942                            break;
15943                    }
15944                }
15945
15946                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15947
15948                // Count the number of process types.
15949                switch (app.curProcState) {
15950                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15951                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15952                        mNumCachedHiddenProcs++;
15953                        numCached++;
15954                        if (numCached > cachedProcessLimit) {
15955                            killUnneededProcessLocked(app, "cached #" + numCached);
15956                        }
15957                        break;
15958                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15959                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15960                                && app.lastActivityTime < oldTime) {
15961                            killUnneededProcessLocked(app, "empty for "
15962                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15963                                    / 1000) + "s");
15964                        } else {
15965                            numEmpty++;
15966                            if (numEmpty > emptyProcessLimit) {
15967                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15968                            }
15969                        }
15970                        break;
15971                    default:
15972                        mNumNonCachedProcs++;
15973                        break;
15974                }
15975
15976                if (app.isolated && app.services.size() <= 0) {
15977                    // If this is an isolated process, and there are no
15978                    // services running in it, then the process is no longer
15979                    // needed.  We agressively kill these because we can by
15980                    // definition not re-use the same process again, and it is
15981                    // good to avoid having whatever code was running in them
15982                    // left sitting around after no longer needed.
15983                    killUnneededProcessLocked(app, "isolated not needed");
15984                }
15985
15986                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15987                        && !app.killedByAm) {
15988                    numTrimming++;
15989                }
15990            }
15991        }
15992
15993        mNumServiceProcs = mNewNumServiceProcs;
15994
15995        // Now determine the memory trimming level of background processes.
15996        // Unfortunately we need to start at the back of the list to do this
15997        // properly.  We only do this if the number of background apps we
15998        // are managing to keep around is less than half the maximum we desire;
15999        // if we are keeping a good number around, we'll let them use whatever
16000        // memory they want.
16001        final int numCachedAndEmpty = numCached + numEmpty;
16002        int memFactor;
16003        if (numCached <= ProcessList.TRIM_CACHED_APPS
16004                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16005            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16006                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16007            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16008                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16009            } else {
16010                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16011            }
16012        } else {
16013            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16014        }
16015        // We always allow the memory level to go up (better).  We only allow it to go
16016        // down if we are in a state where that is allowed, *and* the total number of processes
16017        // has gone down since last time.
16018        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16019                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16020                + " last=" + mLastNumProcesses);
16021        if (memFactor > mLastMemoryLevel) {
16022            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16023                memFactor = mLastMemoryLevel;
16024                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16025            }
16026        }
16027        mLastMemoryLevel = memFactor;
16028        mLastNumProcesses = mLruProcesses.size();
16029        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16030        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16031        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16032            if (mLowRamStartTime == 0) {
16033                mLowRamStartTime = now;
16034            }
16035            int step = 0;
16036            int fgTrimLevel;
16037            switch (memFactor) {
16038                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16039                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16040                    break;
16041                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16042                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16043                    break;
16044                default:
16045                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16046                    break;
16047            }
16048            int factor = numTrimming/3;
16049            int minFactor = 2;
16050            if (mHomeProcess != null) minFactor++;
16051            if (mPreviousProcess != null) minFactor++;
16052            if (factor < minFactor) factor = minFactor;
16053            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16054            for (int i=N-1; i>=0; i--) {
16055                ProcessRecord app = mLruProcesses.get(i);
16056                if (allChanged || app.procStateChanged) {
16057                    setProcessTrackerState(app, trackerMemFactor, now);
16058                    app.procStateChanged = false;
16059                }
16060                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16061                        && !app.killedByAm) {
16062                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16063                        try {
16064                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16065                                    "Trimming memory of " + app.processName
16066                                    + " to " + curLevel);
16067                            app.thread.scheduleTrimMemory(curLevel);
16068                        } catch (RemoteException e) {
16069                        }
16070                        if (false) {
16071                            // For now we won't do this; our memory trimming seems
16072                            // to be good enough at this point that destroying
16073                            // activities causes more harm than good.
16074                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16075                                    && app != mHomeProcess && app != mPreviousProcess) {
16076                                // Need to do this on its own message because the stack may not
16077                                // be in a consistent state at this point.
16078                                // For these apps we will also finish their activities
16079                                // to help them free memory.
16080                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16081                            }
16082                        }
16083                    }
16084                    app.trimMemoryLevel = curLevel;
16085                    step++;
16086                    if (step >= factor) {
16087                        step = 0;
16088                        switch (curLevel) {
16089                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16090                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16091                                break;
16092                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16093                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16094                                break;
16095                        }
16096                    }
16097                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16098                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16099                            && app.thread != null) {
16100                        try {
16101                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16102                                    "Trimming memory of heavy-weight " + app.processName
16103                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16104                            app.thread.scheduleTrimMemory(
16105                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16106                        } catch (RemoteException e) {
16107                        }
16108                    }
16109                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16110                } else {
16111                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16112                            || app.systemNoUi) && app.pendingUiClean) {
16113                        // If this application is now in the background and it
16114                        // had done UI, then give it the special trim level to
16115                        // have it free UI resources.
16116                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16117                        if (app.trimMemoryLevel < level && app.thread != null) {
16118                            try {
16119                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16120                                        "Trimming memory of bg-ui " + app.processName
16121                                        + " to " + level);
16122                                app.thread.scheduleTrimMemory(level);
16123                            } catch (RemoteException e) {
16124                            }
16125                        }
16126                        app.pendingUiClean = false;
16127                    }
16128                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16129                        try {
16130                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16131                                    "Trimming memory of fg " + app.processName
16132                                    + " to " + fgTrimLevel);
16133                            app.thread.scheduleTrimMemory(fgTrimLevel);
16134                        } catch (RemoteException e) {
16135                        }
16136                    }
16137                    app.trimMemoryLevel = fgTrimLevel;
16138                }
16139            }
16140        } else {
16141            if (mLowRamStartTime != 0) {
16142                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16143                mLowRamStartTime = 0;
16144            }
16145            for (int i=N-1; i>=0; i--) {
16146                ProcessRecord app = mLruProcesses.get(i);
16147                if (allChanged || app.procStateChanged) {
16148                    setProcessTrackerState(app, trackerMemFactor, now);
16149                    app.procStateChanged = false;
16150                }
16151                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16152                        || app.systemNoUi) && app.pendingUiClean) {
16153                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16154                            && app.thread != null) {
16155                        try {
16156                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16157                                    "Trimming memory of ui hidden " + app.processName
16158                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16159                            app.thread.scheduleTrimMemory(
16160                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16161                        } catch (RemoteException e) {
16162                        }
16163                    }
16164                    app.pendingUiClean = false;
16165                }
16166                app.trimMemoryLevel = 0;
16167            }
16168        }
16169
16170        if (mAlwaysFinishActivities) {
16171            // Need to do this on its own message because the stack may not
16172            // be in a consistent state at this point.
16173            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16174        }
16175
16176        if (allChanged) {
16177            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16178        }
16179
16180        if (mProcessStats.shouldWriteNowLocked(now)) {
16181            mHandler.post(new Runnable() {
16182                @Override public void run() {
16183                    synchronized (ActivityManagerService.this) {
16184                        mProcessStats.writeStateAsyncLocked();
16185                    }
16186                }
16187            });
16188        }
16189
16190        if (DEBUG_OOM_ADJ) {
16191            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16192        }
16193    }
16194
16195    final void trimApplications() {
16196        synchronized (this) {
16197            int i;
16198
16199            // First remove any unused application processes whose package
16200            // has been removed.
16201            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16202                final ProcessRecord app = mRemovedProcesses.get(i);
16203                if (app.activities.size() == 0
16204                        && app.curReceiver == null && app.services.size() == 0) {
16205                    Slog.i(
16206                        TAG, "Exiting empty application process "
16207                        + app.processName + " ("
16208                        + (app.thread != null ? app.thread.asBinder() : null)
16209                        + ")\n");
16210                    if (app.pid > 0 && app.pid != MY_PID) {
16211                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16212                                app.processName, app.setAdj, "empty");
16213                        app.killedByAm = true;
16214                        Process.killProcessQuiet(app.pid);
16215                    } else {
16216                        try {
16217                            app.thread.scheduleExit();
16218                        } catch (Exception e) {
16219                            // Ignore exceptions.
16220                        }
16221                    }
16222                    cleanUpApplicationRecordLocked(app, false, true, -1);
16223                    mRemovedProcesses.remove(i);
16224
16225                    if (app.persistent) {
16226                        if (app.persistent) {
16227                            addAppLocked(app.info, false);
16228                        }
16229                    }
16230                }
16231            }
16232
16233            // Now update the oom adj for all processes.
16234            updateOomAdjLocked();
16235        }
16236    }
16237
16238    /** This method sends the specified signal to each of the persistent apps */
16239    public void signalPersistentProcesses(int sig) throws RemoteException {
16240        if (sig != Process.SIGNAL_USR1) {
16241            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16242        }
16243
16244        synchronized (this) {
16245            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16246                    != PackageManager.PERMISSION_GRANTED) {
16247                throw new SecurityException("Requires permission "
16248                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16249            }
16250
16251            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16252                ProcessRecord r = mLruProcesses.get(i);
16253                if (r.thread != null && r.persistent) {
16254                    Process.sendSignal(r.pid, sig);
16255                }
16256            }
16257        }
16258    }
16259
16260    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16261        if (proc == null || proc == mProfileProc) {
16262            proc = mProfileProc;
16263            path = mProfileFile;
16264            profileType = mProfileType;
16265            clearProfilerLocked();
16266        }
16267        if (proc == null) {
16268            return;
16269        }
16270        try {
16271            proc.thread.profilerControl(false, path, null, profileType);
16272        } catch (RemoteException e) {
16273            throw new IllegalStateException("Process disappeared");
16274        }
16275    }
16276
16277    private void clearProfilerLocked() {
16278        if (mProfileFd != null) {
16279            try {
16280                mProfileFd.close();
16281            } catch (IOException e) {
16282            }
16283        }
16284        mProfileApp = null;
16285        mProfileProc = null;
16286        mProfileFile = null;
16287        mProfileType = 0;
16288        mAutoStopProfiler = false;
16289    }
16290
16291    public boolean profileControl(String process, int userId, boolean start,
16292            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16293
16294        try {
16295            synchronized (this) {
16296                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16297                // its own permission.
16298                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16299                        != PackageManager.PERMISSION_GRANTED) {
16300                    throw new SecurityException("Requires permission "
16301                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16302                }
16303
16304                if (start && fd == null) {
16305                    throw new IllegalArgumentException("null fd");
16306                }
16307
16308                ProcessRecord proc = null;
16309                if (process != null) {
16310                    proc = findProcessLocked(process, userId, "profileControl");
16311                }
16312
16313                if (start && (proc == null || proc.thread == null)) {
16314                    throw new IllegalArgumentException("Unknown process: " + process);
16315                }
16316
16317                if (start) {
16318                    stopProfilerLocked(null, null, 0);
16319                    setProfileApp(proc.info, proc.processName, path, fd, false);
16320                    mProfileProc = proc;
16321                    mProfileType = profileType;
16322                    try {
16323                        fd = fd.dup();
16324                    } catch (IOException e) {
16325                        fd = null;
16326                    }
16327                    proc.thread.profilerControl(start, path, fd, profileType);
16328                    fd = null;
16329                    mProfileFd = null;
16330                } else {
16331                    stopProfilerLocked(proc, path, profileType);
16332                    if (fd != null) {
16333                        try {
16334                            fd.close();
16335                        } catch (IOException e) {
16336                        }
16337                    }
16338                }
16339
16340                return true;
16341            }
16342        } catch (RemoteException e) {
16343            throw new IllegalStateException("Process disappeared");
16344        } finally {
16345            if (fd != null) {
16346                try {
16347                    fd.close();
16348                } catch (IOException e) {
16349                }
16350            }
16351        }
16352    }
16353
16354    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16355        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16356                userId, true, true, callName, null);
16357        ProcessRecord proc = null;
16358        try {
16359            int pid = Integer.parseInt(process);
16360            synchronized (mPidsSelfLocked) {
16361                proc = mPidsSelfLocked.get(pid);
16362            }
16363        } catch (NumberFormatException e) {
16364        }
16365
16366        if (proc == null) {
16367            ArrayMap<String, SparseArray<ProcessRecord>> all
16368                    = mProcessNames.getMap();
16369            SparseArray<ProcessRecord> procs = all.get(process);
16370            if (procs != null && procs.size() > 0) {
16371                proc = procs.valueAt(0);
16372                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16373                    for (int i=1; i<procs.size(); i++) {
16374                        ProcessRecord thisProc = procs.valueAt(i);
16375                        if (thisProc.userId == userId) {
16376                            proc = thisProc;
16377                            break;
16378                        }
16379                    }
16380                }
16381            }
16382        }
16383
16384        return proc;
16385    }
16386
16387    public boolean dumpHeap(String process, int userId, boolean managed,
16388            String path, ParcelFileDescriptor fd) throws RemoteException {
16389
16390        try {
16391            synchronized (this) {
16392                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16393                // its own permission (same as profileControl).
16394                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16395                        != PackageManager.PERMISSION_GRANTED) {
16396                    throw new SecurityException("Requires permission "
16397                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16398                }
16399
16400                if (fd == null) {
16401                    throw new IllegalArgumentException("null fd");
16402                }
16403
16404                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16405                if (proc == null || proc.thread == null) {
16406                    throw new IllegalArgumentException("Unknown process: " + process);
16407                }
16408
16409                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16410                if (!isDebuggable) {
16411                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16412                        throw new SecurityException("Process not debuggable: " + proc);
16413                    }
16414                }
16415
16416                proc.thread.dumpHeap(managed, path, fd);
16417                fd = null;
16418                return true;
16419            }
16420        } catch (RemoteException e) {
16421            throw new IllegalStateException("Process disappeared");
16422        } finally {
16423            if (fd != null) {
16424                try {
16425                    fd.close();
16426                } catch (IOException e) {
16427                }
16428            }
16429        }
16430    }
16431
16432    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16433    public void monitor() {
16434        synchronized (this) { }
16435    }
16436
16437    void onCoreSettingsChange(Bundle settings) {
16438        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16439            ProcessRecord processRecord = mLruProcesses.get(i);
16440            try {
16441                if (processRecord.thread != null) {
16442                    processRecord.thread.setCoreSettings(settings);
16443                }
16444            } catch (RemoteException re) {
16445                /* ignore */
16446            }
16447        }
16448    }
16449
16450    // Multi-user methods
16451
16452    /**
16453     * Start user, if its not already running, but don't bring it to foreground.
16454     */
16455    @Override
16456    public boolean startUserInBackground(final int userId) {
16457        return startUser(userId, /* foreground */ false);
16458    }
16459
16460    /**
16461     * Refreshes the list of users related to the current user when either a
16462     * user switch happens or when a new related user is started in the
16463     * background.
16464     */
16465    private void updateCurrentProfileIdsLocked() {
16466        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16467                mCurrentUserId, false /* enabledOnly */);
16468        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16469        for (int i = 0; i < currentProfileIds.length; i++) {
16470            currentProfileIds[i] = profiles.get(i).id;
16471        }
16472        mCurrentProfileIds = currentProfileIds;
16473    }
16474
16475    private Set getProfileIdsLocked(int userId) {
16476        Set userIds = new HashSet<Integer>();
16477        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16478                userId, false /* enabledOnly */);
16479        for (UserInfo user : profiles) {
16480            userIds.add(Integer.valueOf(user.id));
16481        }
16482        return userIds;
16483    }
16484
16485    @Override
16486    public boolean switchUser(final int userId) {
16487        return startUser(userId, /* foregound */ true);
16488    }
16489
16490    private boolean startUser(final int userId, boolean foreground) {
16491        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16492                != PackageManager.PERMISSION_GRANTED) {
16493            String msg = "Permission Denial: switchUser() from pid="
16494                    + Binder.getCallingPid()
16495                    + ", uid=" + Binder.getCallingUid()
16496                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16497            Slog.w(TAG, msg);
16498            throw new SecurityException(msg);
16499        }
16500
16501        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16502
16503        final long ident = Binder.clearCallingIdentity();
16504        try {
16505            synchronized (this) {
16506                final int oldUserId = mCurrentUserId;
16507                if (oldUserId == userId) {
16508                    return true;
16509                }
16510
16511                mStackSupervisor.setLockTaskModeLocked(null);
16512
16513                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16514                if (userInfo == null) {
16515                    Slog.w(TAG, "No user info for user #" + userId);
16516                    return false;
16517                }
16518
16519                if (foreground) {
16520                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16521                            R.anim.screen_user_enter);
16522                }
16523
16524                boolean needStart = false;
16525
16526                // If the user we are switching to is not currently started, then
16527                // we need to start it now.
16528                if (mStartedUsers.get(userId) == null) {
16529                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16530                    updateStartedUserArrayLocked();
16531                    needStart = true;
16532                }
16533
16534                final Integer userIdInt = Integer.valueOf(userId);
16535                mUserLru.remove(userIdInt);
16536                mUserLru.add(userIdInt);
16537
16538                if (foreground) {
16539                    mCurrentUserId = userId;
16540                    updateCurrentProfileIdsLocked();
16541                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16542                    // Once the internal notion of the active user has switched, we lock the device
16543                    // with the option to show the user switcher on the keyguard.
16544                    mWindowManager.lockNow(null);
16545                } else {
16546                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16547                    updateCurrentProfileIdsLocked();
16548                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16549                    mUserLru.remove(currentUserIdInt);
16550                    mUserLru.add(currentUserIdInt);
16551                }
16552
16553                final UserStartedState uss = mStartedUsers.get(userId);
16554
16555                // Make sure user is in the started state.  If it is currently
16556                // stopping, we need to knock that off.
16557                if (uss.mState == UserStartedState.STATE_STOPPING) {
16558                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16559                    // so we can just fairly silently bring the user back from
16560                    // the almost-dead.
16561                    uss.mState = UserStartedState.STATE_RUNNING;
16562                    updateStartedUserArrayLocked();
16563                    needStart = true;
16564                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16565                    // This means ACTION_SHUTDOWN has been sent, so we will
16566                    // need to treat this as a new boot of the user.
16567                    uss.mState = UserStartedState.STATE_BOOTING;
16568                    updateStartedUserArrayLocked();
16569                    needStart = true;
16570                }
16571
16572                if (uss.mState == UserStartedState.STATE_BOOTING) {
16573                    // Booting up a new user, need to tell system services about it.
16574                    // Note that this is on the same handler as scheduling of broadcasts,
16575                    // which is important because it needs to go first.
16576                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16577                }
16578
16579                if (foreground) {
16580                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16581                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16582                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16583                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16584                            oldUserId, userId, uss));
16585                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16586                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16587                }
16588
16589                if (needStart) {
16590                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16591                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16592                            | Intent.FLAG_RECEIVER_FOREGROUND);
16593                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16594                    broadcastIntentLocked(null, null, intent,
16595                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16596                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16597                }
16598
16599                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16600                    if (userId != 0) {
16601                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16602                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16603                        broadcastIntentLocked(null, null, intent, null,
16604                                new IIntentReceiver.Stub() {
16605                                    public void performReceive(Intent intent, int resultCode,
16606                                            String data, Bundle extras, boolean ordered,
16607                                            boolean sticky, int sendingUser) {
16608                                        userInitialized(uss, userId);
16609                                    }
16610                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16611                                true, false, MY_PID, Process.SYSTEM_UID,
16612                                userId);
16613                        uss.initializing = true;
16614                    } else {
16615                        getUserManagerLocked().makeInitialized(userInfo.id);
16616                    }
16617                }
16618
16619                if (foreground) {
16620                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16621                    if (homeInFront) {
16622                        startHomeActivityLocked(userId);
16623                    } else {
16624                        mStackSupervisor.resumeTopActivitiesLocked();
16625                    }
16626                    EventLogTags.writeAmSwitchUser(userId);
16627                    getUserManagerLocked().userForeground(userId);
16628                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16629                }
16630
16631                if (needStart) {
16632                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16633                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16634                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16635                    broadcastIntentLocked(null, null, intent,
16636                            null, new IIntentReceiver.Stub() {
16637                                @Override
16638                                public void performReceive(Intent intent, int resultCode, String data,
16639                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16640                                        throws RemoteException {
16641                                }
16642                            }, 0, null, null,
16643                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16644                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16645                }
16646            }
16647        } finally {
16648            Binder.restoreCallingIdentity(ident);
16649        }
16650
16651        return true;
16652    }
16653
16654    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16655        long ident = Binder.clearCallingIdentity();
16656        try {
16657            Intent intent;
16658            if (oldUserId >= 0) {
16659                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16660                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16661                        | Intent.FLAG_RECEIVER_FOREGROUND);
16662                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16663                broadcastIntentLocked(null, null, intent,
16664                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16665                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16666            }
16667            if (newUserId >= 0) {
16668                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16669                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16670                        | Intent.FLAG_RECEIVER_FOREGROUND);
16671                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16672                broadcastIntentLocked(null, null, intent,
16673                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16674                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16675                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16676                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16677                        | Intent.FLAG_RECEIVER_FOREGROUND);
16678                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16679                broadcastIntentLocked(null, null, intent,
16680                        null, null, 0, null, null,
16681                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16682                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16683            }
16684        } finally {
16685            Binder.restoreCallingIdentity(ident);
16686        }
16687    }
16688
16689    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16690            final int newUserId) {
16691        final int N = mUserSwitchObservers.beginBroadcast();
16692        if (N > 0) {
16693            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16694                int mCount = 0;
16695                @Override
16696                public void sendResult(Bundle data) throws RemoteException {
16697                    synchronized (ActivityManagerService.this) {
16698                        if (mCurUserSwitchCallback == this) {
16699                            mCount++;
16700                            if (mCount == N) {
16701                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16702                            }
16703                        }
16704                    }
16705                }
16706            };
16707            synchronized (this) {
16708                uss.switching = true;
16709                mCurUserSwitchCallback = callback;
16710            }
16711            for (int i=0; i<N; i++) {
16712                try {
16713                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16714                            newUserId, callback);
16715                } catch (RemoteException e) {
16716                }
16717            }
16718        } else {
16719            synchronized (this) {
16720                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16721            }
16722        }
16723        mUserSwitchObservers.finishBroadcast();
16724    }
16725
16726    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16727        synchronized (this) {
16728            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16729            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16730        }
16731    }
16732
16733    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16734        mCurUserSwitchCallback = null;
16735        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16736        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16737                oldUserId, newUserId, uss));
16738    }
16739
16740    void userInitialized(UserStartedState uss, int newUserId) {
16741        completeSwitchAndInitalize(uss, newUserId, true, false);
16742    }
16743
16744    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16745        completeSwitchAndInitalize(uss, newUserId, false, true);
16746    }
16747
16748    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16749            boolean clearInitializing, boolean clearSwitching) {
16750        boolean unfrozen = false;
16751        synchronized (this) {
16752            if (clearInitializing) {
16753                uss.initializing = false;
16754                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16755            }
16756            if (clearSwitching) {
16757                uss.switching = false;
16758            }
16759            if (!uss.switching && !uss.initializing) {
16760                mWindowManager.stopFreezingScreen();
16761                unfrozen = true;
16762            }
16763        }
16764        if (unfrozen) {
16765            final int N = mUserSwitchObservers.beginBroadcast();
16766            for (int i=0; i<N; i++) {
16767                try {
16768                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16769                } catch (RemoteException e) {
16770                }
16771            }
16772            mUserSwitchObservers.finishBroadcast();
16773        }
16774    }
16775
16776    void scheduleStartProfilesLocked() {
16777        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16778            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16779                    DateUtils.SECOND_IN_MILLIS);
16780        }
16781    }
16782
16783    void startProfilesLocked() {
16784        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16785        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16786                mCurrentUserId, false /* enabledOnly */);
16787        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16788        for (UserInfo user : profiles) {
16789            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16790                    && user.id != mCurrentUserId) {
16791                toStart.add(user);
16792            }
16793        }
16794        final int n = toStart.size();
16795        int i = 0;
16796        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16797            startUserInBackground(toStart.get(i).id);
16798        }
16799        if (i < n) {
16800            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16801        }
16802    }
16803
16804    void finishUserSwitch(UserStartedState uss) {
16805        synchronized (this) {
16806            if (uss.mState == UserStartedState.STATE_BOOTING
16807                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16808                uss.mState = UserStartedState.STATE_RUNNING;
16809                final int userId = uss.mHandle.getIdentifier();
16810                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16811                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16812                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16813                broadcastIntentLocked(null, null, intent,
16814                        null, null, 0, null, null,
16815                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16816                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16817            }
16818
16819            startProfilesLocked();
16820
16821            int num = mUserLru.size();
16822            int i = 0;
16823            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16824                Integer oldUserId = mUserLru.get(i);
16825                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16826                if (oldUss == null) {
16827                    // Shouldn't happen, but be sane if it does.
16828                    mUserLru.remove(i);
16829                    num--;
16830                    continue;
16831                }
16832                if (oldUss.mState == UserStartedState.STATE_STOPPING
16833                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16834                    // This user is already stopping, doesn't count.
16835                    num--;
16836                    i++;
16837                    continue;
16838                }
16839                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16840                    // Owner and current can't be stopped, but count as running.
16841                    i++;
16842                    continue;
16843                }
16844                // This is a user to be stopped.
16845                stopUserLocked(oldUserId, null);
16846                num--;
16847                i++;
16848            }
16849        }
16850    }
16851
16852    @Override
16853    public int stopUser(final int userId, final IStopUserCallback callback) {
16854        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16855                != PackageManager.PERMISSION_GRANTED) {
16856            String msg = "Permission Denial: switchUser() from pid="
16857                    + Binder.getCallingPid()
16858                    + ", uid=" + Binder.getCallingUid()
16859                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16860            Slog.w(TAG, msg);
16861            throw new SecurityException(msg);
16862        }
16863        if (userId <= 0) {
16864            throw new IllegalArgumentException("Can't stop primary user " + userId);
16865        }
16866        synchronized (this) {
16867            return stopUserLocked(userId, callback);
16868        }
16869    }
16870
16871    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16872        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16873        if (mCurrentUserId == userId) {
16874            return ActivityManager.USER_OP_IS_CURRENT;
16875        }
16876
16877        final UserStartedState uss = mStartedUsers.get(userId);
16878        if (uss == null) {
16879            // User is not started, nothing to do...  but we do need to
16880            // callback if requested.
16881            if (callback != null) {
16882                mHandler.post(new Runnable() {
16883                    @Override
16884                    public void run() {
16885                        try {
16886                            callback.userStopped(userId);
16887                        } catch (RemoteException e) {
16888                        }
16889                    }
16890                });
16891            }
16892            return ActivityManager.USER_OP_SUCCESS;
16893        }
16894
16895        if (callback != null) {
16896            uss.mStopCallbacks.add(callback);
16897        }
16898
16899        if (uss.mState != UserStartedState.STATE_STOPPING
16900                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16901            uss.mState = UserStartedState.STATE_STOPPING;
16902            updateStartedUserArrayLocked();
16903
16904            long ident = Binder.clearCallingIdentity();
16905            try {
16906                // We are going to broadcast ACTION_USER_STOPPING and then
16907                // once that is done send a final ACTION_SHUTDOWN and then
16908                // stop the user.
16909                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16910                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16911                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16912                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16913                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16914                // This is the result receiver for the final shutdown broadcast.
16915                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16916                    @Override
16917                    public void performReceive(Intent intent, int resultCode, String data,
16918                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16919                        finishUserStop(uss);
16920                    }
16921                };
16922                // This is the result receiver for the initial stopping broadcast.
16923                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16924                    @Override
16925                    public void performReceive(Intent intent, int resultCode, String data,
16926                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16927                        // On to the next.
16928                        synchronized (ActivityManagerService.this) {
16929                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16930                                // Whoops, we are being started back up.  Abort, abort!
16931                                return;
16932                            }
16933                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16934                        }
16935                        mSystemServiceManager.stopUser(userId);
16936                        broadcastIntentLocked(null, null, shutdownIntent,
16937                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16938                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16939                    }
16940                };
16941                // Kick things off.
16942                broadcastIntentLocked(null, null, stoppingIntent,
16943                        null, stoppingReceiver, 0, null, null,
16944                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16945                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16946            } finally {
16947                Binder.restoreCallingIdentity(ident);
16948            }
16949        }
16950
16951        return ActivityManager.USER_OP_SUCCESS;
16952    }
16953
16954    void finishUserStop(UserStartedState uss) {
16955        final int userId = uss.mHandle.getIdentifier();
16956        boolean stopped;
16957        ArrayList<IStopUserCallback> callbacks;
16958        synchronized (this) {
16959            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16960            if (mStartedUsers.get(userId) != uss) {
16961                stopped = false;
16962            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16963                stopped = false;
16964            } else {
16965                stopped = true;
16966                // User can no longer run.
16967                mStartedUsers.remove(userId);
16968                mUserLru.remove(Integer.valueOf(userId));
16969                updateStartedUserArrayLocked();
16970
16971                // Clean up all state and processes associated with the user.
16972                // Kill all the processes for the user.
16973                forceStopUserLocked(userId, "finish user");
16974            }
16975        }
16976
16977        for (int i=0; i<callbacks.size(); i++) {
16978            try {
16979                if (stopped) callbacks.get(i).userStopped(userId);
16980                else callbacks.get(i).userStopAborted(userId);
16981            } catch (RemoteException e) {
16982            }
16983        }
16984
16985        if (stopped) {
16986            mSystemServiceManager.cleanupUser(userId);
16987            synchronized (this) {
16988                mStackSupervisor.removeUserLocked(userId);
16989            }
16990        }
16991    }
16992
16993    @Override
16994    public UserInfo getCurrentUser() {
16995        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16996                != PackageManager.PERMISSION_GRANTED) && (
16997                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16998                != PackageManager.PERMISSION_GRANTED)) {
16999            String msg = "Permission Denial: getCurrentUser() from pid="
17000                    + Binder.getCallingPid()
17001                    + ", uid=" + Binder.getCallingUid()
17002                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17003            Slog.w(TAG, msg);
17004            throw new SecurityException(msg);
17005        }
17006        synchronized (this) {
17007            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17008        }
17009    }
17010
17011    int getCurrentUserIdLocked() {
17012        return mCurrentUserId;
17013    }
17014
17015    @Override
17016    public boolean isUserRunning(int userId, boolean orStopped) {
17017        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17018                != PackageManager.PERMISSION_GRANTED) {
17019            String msg = "Permission Denial: isUserRunning() from pid="
17020                    + Binder.getCallingPid()
17021                    + ", uid=" + Binder.getCallingUid()
17022                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17023            Slog.w(TAG, msg);
17024            throw new SecurityException(msg);
17025        }
17026        synchronized (this) {
17027            return isUserRunningLocked(userId, orStopped);
17028        }
17029    }
17030
17031    boolean isUserRunningLocked(int userId, boolean orStopped) {
17032        UserStartedState state = mStartedUsers.get(userId);
17033        if (state == null) {
17034            return false;
17035        }
17036        if (orStopped) {
17037            return true;
17038        }
17039        return state.mState != UserStartedState.STATE_STOPPING
17040                && state.mState != UserStartedState.STATE_SHUTDOWN;
17041    }
17042
17043    @Override
17044    public int[] getRunningUserIds() {
17045        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17046                != PackageManager.PERMISSION_GRANTED) {
17047            String msg = "Permission Denial: isUserRunning() from pid="
17048                    + Binder.getCallingPid()
17049                    + ", uid=" + Binder.getCallingUid()
17050                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17051            Slog.w(TAG, msg);
17052            throw new SecurityException(msg);
17053        }
17054        synchronized (this) {
17055            return mStartedUserArray;
17056        }
17057    }
17058
17059    private void updateStartedUserArrayLocked() {
17060        int num = 0;
17061        for (int i=0; i<mStartedUsers.size();  i++) {
17062            UserStartedState uss = mStartedUsers.valueAt(i);
17063            // This list does not include stopping users.
17064            if (uss.mState != UserStartedState.STATE_STOPPING
17065                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17066                num++;
17067            }
17068        }
17069        mStartedUserArray = new int[num];
17070        num = 0;
17071        for (int i=0; i<mStartedUsers.size();  i++) {
17072            UserStartedState uss = mStartedUsers.valueAt(i);
17073            if (uss.mState != UserStartedState.STATE_STOPPING
17074                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17075                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17076                num++;
17077            }
17078        }
17079    }
17080
17081    @Override
17082    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17083        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17084                != PackageManager.PERMISSION_GRANTED) {
17085            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17086                    + Binder.getCallingPid()
17087                    + ", uid=" + Binder.getCallingUid()
17088                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17089            Slog.w(TAG, msg);
17090            throw new SecurityException(msg);
17091        }
17092
17093        mUserSwitchObservers.register(observer);
17094    }
17095
17096    @Override
17097    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17098        mUserSwitchObservers.unregister(observer);
17099    }
17100
17101    private boolean userExists(int userId) {
17102        if (userId == 0) {
17103            return true;
17104        }
17105        UserManagerService ums = getUserManagerLocked();
17106        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17107    }
17108
17109    int[] getUsersLocked() {
17110        UserManagerService ums = getUserManagerLocked();
17111        return ums != null ? ums.getUserIds() : new int[] { 0 };
17112    }
17113
17114    UserManagerService getUserManagerLocked() {
17115        if (mUserManager == null) {
17116            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17117            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17118        }
17119        return mUserManager;
17120    }
17121
17122    private int applyUserId(int uid, int userId) {
17123        return UserHandle.getUid(userId, uid);
17124    }
17125
17126    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17127        if (info == null) return null;
17128        ApplicationInfo newInfo = new ApplicationInfo(info);
17129        newInfo.uid = applyUserId(info.uid, userId);
17130        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17131                + info.packageName;
17132        return newInfo;
17133    }
17134
17135    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17136        if (aInfo == null
17137                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17138            return aInfo;
17139        }
17140
17141        ActivityInfo info = new ActivityInfo(aInfo);
17142        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17143        return info;
17144    }
17145
17146    private final class LocalService extends ActivityManagerInternal {
17147        @Override
17148        public void goingToSleep() {
17149            ActivityManagerService.this.goingToSleep();
17150        }
17151
17152        @Override
17153        public void wakingUp() {
17154            ActivityManagerService.this.wakingUp();
17155        }
17156    }
17157}
17158