ActivityManagerService.java revision 8faa342c8a544229b9fc05378a6b33d18d0f8d6b
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.app.AppOpsManager;
32import android.app.IActivityContainer;
33import android.app.IActivityContainerCallback;
34import android.appwidget.AppWidgetManager;
35import android.graphics.Rect;
36import android.os.BatteryStats;
37import android.util.ArrayMap;
38
39import com.android.internal.R;
40import com.android.internal.annotations.GuardedBy;
41import com.android.internal.app.IAppOpsService;
42import com.android.internal.app.ProcessMap;
43import com.android.internal.app.ProcessStats;
44import com.android.internal.content.PackageMonitor;
45import com.android.internal.os.BackgroundThread;
46import com.android.internal.os.BatteryStatsImpl;
47import com.android.internal.os.ProcessCpuTracker;
48import com.android.internal.os.TransferPipe;
49import com.android.internal.os.Zygote;
50import com.android.internal.util.FastPrintWriter;
51import com.android.internal.util.FastXmlSerializer;
52import com.android.internal.util.MemInfoReader;
53import com.android.internal.util.Preconditions;
54import com.android.server.AppOpsService;
55import com.android.server.AttributeCache;
56import com.android.server.IntentResolver;
57import com.android.server.LocalServices;
58import com.android.server.ServiceThread;
59import com.android.server.SystemService;
60import com.android.server.Watchdog;
61import com.android.server.am.ActivityStack.ActivityState;
62import com.android.server.firewall.IntentFirewall;
63import com.android.server.pm.UserManagerService;
64import com.android.server.wm.AppTransition;
65import com.android.server.wm.WindowManagerService;
66import com.google.android.collect.Lists;
67import com.google.android.collect.Maps;
68
69import libcore.io.IoUtils;
70
71import org.xmlpull.v1.XmlPullParser;
72import org.xmlpull.v1.XmlPullParserException;
73import org.xmlpull.v1.XmlSerializer;
74
75import android.app.Activity;
76import android.app.ActivityManager;
77import android.app.ActivityManager.RunningTaskInfo;
78import android.app.ActivityManager.StackInfo;
79import android.app.ActivityManagerInternal;
80import android.app.ActivityManagerNative;
81import android.app.ActivityOptions;
82import android.app.ActivityThread;
83import android.app.AlertDialog;
84import android.app.AppGlobals;
85import android.app.ApplicationErrorReport;
86import android.app.Dialog;
87import android.app.IActivityController;
88import android.app.IApplicationThread;
89import android.app.IInstrumentationWatcher;
90import android.app.INotificationManager;
91import android.app.IProcessObserver;
92import android.app.IServiceConnection;
93import android.app.IStopUserCallback;
94import android.app.IThumbnailReceiver;
95import android.app.IUiAutomationConnection;
96import android.app.IUserSwitchObserver;
97import android.app.Instrumentation;
98import android.app.Notification;
99import android.app.NotificationManager;
100import android.app.PendingIntent;
101import android.app.backup.IBackupManager;
102import android.content.ActivityNotFoundException;
103import android.content.BroadcastReceiver;
104import android.content.ClipData;
105import android.content.ComponentCallbacks2;
106import android.content.ComponentName;
107import android.content.ContentProvider;
108import android.content.ContentResolver;
109import android.content.Context;
110import android.content.DialogInterface;
111import android.content.IContentProvider;
112import android.content.IIntentReceiver;
113import android.content.IIntentSender;
114import android.content.Intent;
115import android.content.IntentFilter;
116import android.content.IntentSender;
117import android.content.pm.ActivityInfo;
118import android.content.pm.ApplicationInfo;
119import android.content.pm.ConfigurationInfo;
120import android.content.pm.IPackageDataObserver;
121import android.content.pm.IPackageManager;
122import android.content.pm.InstrumentationInfo;
123import android.content.pm.PackageInfo;
124import android.content.pm.PackageManager;
125import android.content.pm.ParceledListSlice;
126import android.content.pm.UserInfo;
127import android.content.pm.PackageManager.NameNotFoundException;
128import android.content.pm.PathPermission;
129import android.content.pm.ProviderInfo;
130import android.content.pm.ResolveInfo;
131import android.content.pm.ServiceInfo;
132import android.content.res.CompatibilityInfo;
133import android.content.res.Configuration;
134import android.graphics.Bitmap;
135import android.net.Proxy;
136import android.net.ProxyProperties;
137import android.net.Uri;
138import android.os.Binder;
139import android.os.Build;
140import android.os.Bundle;
141import android.os.Debug;
142import android.os.DropBoxManager;
143import android.os.Environment;
144import android.os.FactoryTest;
145import android.os.FileObserver;
146import android.os.FileUtils;
147import android.os.Handler;
148import android.os.IBinder;
149import android.os.IPermissionController;
150import android.os.IRemoteCallback;
151import android.os.IUserManager;
152import android.os.Looper;
153import android.os.Message;
154import android.os.Parcel;
155import android.os.ParcelFileDescriptor;
156import android.os.Process;
157import android.os.RemoteCallbackList;
158import android.os.RemoteException;
159import android.os.SELinux;
160import android.os.ServiceManager;
161import android.os.StrictMode;
162import android.os.SystemClock;
163import android.os.SystemProperties;
164import android.os.UpdateLock;
165import android.os.UserHandle;
166import android.provider.Settings;
167import android.text.format.DateUtils;
168import android.text.format.Time;
169import android.util.AtomicFile;
170import android.util.EventLog;
171import android.util.Log;
172import android.util.Pair;
173import android.util.PrintWriterPrinter;
174import android.util.Slog;
175import android.util.SparseArray;
176import android.util.TimeUtils;
177import android.util.Xml;
178import android.view.Gravity;
179import android.view.LayoutInflater;
180import android.view.View;
181import android.view.WindowManager;
182
183import java.io.BufferedInputStream;
184import java.io.BufferedOutputStream;
185import java.io.DataInputStream;
186import java.io.DataOutputStream;
187import java.io.File;
188import java.io.FileDescriptor;
189import java.io.FileInputStream;
190import java.io.FileNotFoundException;
191import java.io.FileOutputStream;
192import java.io.IOException;
193import java.io.InputStreamReader;
194import java.io.PrintWriter;
195import java.io.StringWriter;
196import java.lang.ref.WeakReference;
197import java.util.ArrayList;
198import java.util.Arrays;
199import java.util.Collections;
200import java.util.Comparator;
201import java.util.HashMap;
202import java.util.HashSet;
203import java.util.Iterator;
204import java.util.List;
205import java.util.Locale;
206import java.util.Map;
207import java.util.Set;
208import java.util.concurrent.atomic.AtomicBoolean;
209import java.util.concurrent.atomic.AtomicLong;
210
211public final class ActivityManagerService extends ActivityManagerNative
212        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
213    private static final String USER_DATA_DIR = "/data/user/";
214    static final String TAG = "ActivityManager";
215    static final String TAG_MU = "ActivityManagerServiceMU";
216    static final boolean DEBUG = false;
217    static final boolean localLOGV = DEBUG;
218    static final boolean DEBUG_BACKUP = localLOGV || false;
219    static final boolean DEBUG_BROADCAST = localLOGV || false;
220    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
221    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
222    static final boolean DEBUG_CLEANUP = localLOGV || false;
223    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
224    static final boolean DEBUG_FOCUS = false;
225    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
226    static final boolean DEBUG_MU = localLOGV || false;
227    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
228    static final boolean DEBUG_LRU = localLOGV || false;
229    static final boolean DEBUG_PAUSE = localLOGV || false;
230    static final boolean DEBUG_POWER = localLOGV || false;
231    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
232    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
233    static final boolean DEBUG_PROCESSES = localLOGV || false;
234    static final boolean DEBUG_PROVIDER = localLOGV || false;
235    static final boolean DEBUG_RESULTS = localLOGV || false;
236    static final boolean DEBUG_SERVICE = localLOGV || false;
237    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
238    static final boolean DEBUG_STACK = localLOGV || false;
239    static final boolean DEBUG_SWITCH = localLOGV || false;
240    static final boolean DEBUG_TASKS = localLOGV || false;
241    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
242    static final boolean DEBUG_TRANSITION = localLOGV || false;
243    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
244    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
245    static final boolean DEBUG_VISBILITY = localLOGV || false;
246    static final boolean DEBUG_PSS = localLOGV || false;
247    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
248    static final boolean VALIDATE_TOKENS = false;
249    static final boolean SHOW_ACTIVITY_START_TIME = true;
250
251    // Control over CPU and battery monitoring.
252    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
253    static final boolean MONITOR_CPU_USAGE = true;
254    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
255    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
256    static final boolean MONITOR_THREAD_CPU_USAGE = false;
257
258    // The flags that are set for all calls we make to the package manager.
259    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
260
261    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
262
263    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
264
265    // Maximum number of recent tasks that we can remember.
266    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
267
268    // Amount of time after a call to stopAppSwitches() during which we will
269    // prevent further untrusted switches from happening.
270    static final long APP_SWITCH_DELAY_TIME = 5*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real.
274    static final int PROC_START_TIMEOUT = 10*1000;
275
276    // How long we wait for a launched process to attach to the activity manager
277    // before we decide it's never going to come up for real, when the process was
278    // started with a wrapper for instrumentation (such as Valgrind) because it
279    // could take much longer than usual.
280    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
281
282    // How long to wait after going idle before forcing apps to GC.
283    static final int GC_TIMEOUT = 5*1000;
284
285    // The minimum amount of time between successive GC requests for a process.
286    static final int GC_MIN_INTERVAL = 60*1000;
287
288    // The minimum amount of time between successive PSS requests for a process.
289    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
290
291    // The minimum amount of time between successive PSS requests for a process
292    // when the request is due to the memory state being lowered.
293    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
294
295    // The rate at which we check for apps using excessive power -- 15 mins.
296    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on wake locks to start killing things.
300    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // The minimum sample duration we will allow before deciding we have
303    // enough data on CPU usage to start killing things.
304    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
305
306    // How long we allow a receiver to run before giving up on it.
307    static final int BROADCAST_FG_TIMEOUT = 10*1000;
308    static final int BROADCAST_BG_TIMEOUT = 60*1000;
309
310    // How long we wait until we timeout on key dispatching.
311    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
312
313    // How long we wait until we timeout on key dispatching during instrumentation.
314    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
315
316    // Amount of time we wait for observers to handle a user switch before
317    // giving up on them and unfreezing the screen.
318    static final int USER_SWITCH_TIMEOUT = 2*1000;
319
320    // Maximum number of users we allow to be running at a time.
321    static final int MAX_RUNNING_USERS = 3;
322
323    // How long to wait in getAssistContextExtras for the activity and foreground services
324    // to respond with the result.
325    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
326
327    // Maximum number of persisted Uri grants a package is allowed
328    static final int MAX_PERSISTED_URI_GRANTS = 128;
329
330    static final int MY_PID = Process.myPid();
331
332    static final String[] EMPTY_STRING_ARRAY = new String[0];
333
334    // How many bytes to write into the dropbox log before truncating
335    static final int DROPBOX_MAX_SIZE = 256 * 1024;
336
337    /** Run all ActivityStacks through this */
338    ActivityStackSupervisor mStackSupervisor;
339
340    public IntentFirewall mIntentFirewall;
341
342    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
343    // default actuion automatically.  Important for devices without direct input
344    // devices.
345    private boolean mShowDialogs = true;
346
347    /**
348     * Description of a request to start a new activity, which has been held
349     * due to app switches being disabled.
350     */
351    static class PendingActivityLaunch {
352        final ActivityRecord r;
353        final ActivityRecord sourceRecord;
354        final int startFlags;
355        final ActivityStack stack;
356
357        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
358                int _startFlags, ActivityStack _stack) {
359            r = _r;
360            sourceRecord = _sourceRecord;
361            startFlags = _startFlags;
362            stack = _stack;
363        }
364    }
365
366    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
367            = new ArrayList<PendingActivityLaunch>();
368
369    BroadcastQueue mFgBroadcastQueue;
370    BroadcastQueue mBgBroadcastQueue;
371    // Convenient for easy iteration over the queues. Foreground is first
372    // so that dispatch of foreground broadcasts gets precedence.
373    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
374
375    BroadcastQueue broadcastQueueForIntent(Intent intent) {
376        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
377        if (DEBUG_BACKGROUND_BROADCAST) {
378            Slog.i(TAG, "Broadcast intent " + intent + " on "
379                    + (isFg ? "foreground" : "background")
380                    + " queue");
381        }
382        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
383    }
384
385    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
386        for (BroadcastQueue queue : mBroadcastQueues) {
387            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
388            if (r != null) {
389                return r;
390            }
391        }
392        return null;
393    }
394
395    /**
396     * Activity we have told the window manager to have key focus.
397     */
398    ActivityRecord mFocusedActivity = null;
399
400    /**
401     * List of intents that were used to start the most recent tasks.
402     */
403    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
404
405    public class PendingAssistExtras extends Binder implements Runnable {
406        public final ActivityRecord activity;
407        public boolean haveResult = false;
408        public Bundle result = null;
409        public PendingAssistExtras(ActivityRecord _activity) {
410            activity = _activity;
411        }
412        @Override
413        public void run() {
414            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
415            synchronized (this) {
416                haveResult = true;
417                notifyAll();
418            }
419        }
420    }
421
422    final ArrayList<PendingAssistExtras> mPendingAssistExtras
423            = new ArrayList<PendingAssistExtras>();
424
425    /**
426     * Process management.
427     */
428    final ProcessList mProcessList = new ProcessList();
429
430    /**
431     * All of the applications we currently have running organized by name.
432     * The keys are strings of the application package name (as
433     * returned by the package manager), and the keys are ApplicationRecord
434     * objects.
435     */
436    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
437
438    /**
439     * Tracking long-term execution of processes to look for abuse and other
440     * bad app behavior.
441     */
442    final ProcessStatsService mProcessStats;
443
444    /**
445     * The currently running isolated processes.
446     */
447    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
448
449    /**
450     * Counter for assigning isolated process uids, to avoid frequently reusing the
451     * same ones.
452     */
453    int mNextIsolatedProcessUid = 0;
454
455    /**
456     * The currently running heavy-weight process, if any.
457     */
458    ProcessRecord mHeavyWeightProcess = null;
459
460    /**
461     * The last time that various processes have crashed.
462     */
463    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
464
465    /**
466     * Information about a process that is currently marked as bad.
467     */
468    static final class BadProcessInfo {
469        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
470            this.time = time;
471            this.shortMsg = shortMsg;
472            this.longMsg = longMsg;
473            this.stack = stack;
474        }
475
476        final long time;
477        final String shortMsg;
478        final String longMsg;
479        final String stack;
480    }
481
482    /**
483     * Set of applications that we consider to be bad, and will reject
484     * incoming broadcasts from (which the user has no control over).
485     * Processes are added to this set when they have crashed twice within
486     * a minimum amount of time; they are removed from it when they are
487     * later restarted (hopefully due to some user action).  The value is the
488     * time it was added to the list.
489     */
490    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
491
492    /**
493     * All of the processes we currently have running organized by pid.
494     * The keys are the pid running the application.
495     *
496     * <p>NOTE: This object is protected by its own lock, NOT the global
497     * activity manager lock!
498     */
499    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
500
501    /**
502     * All of the processes that have been forced to be foreground.  The key
503     * is the pid of the caller who requested it (we hold a death
504     * link on it).
505     */
506    abstract class ForegroundToken implements IBinder.DeathRecipient {
507        int pid;
508        IBinder token;
509    }
510    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
511
512    /**
513     * List of records for processes that someone had tried to start before the
514     * system was ready.  We don't start them at that point, but ensure they
515     * are started by the time booting is complete.
516     */
517    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
518
519    /**
520     * List of persistent applications that are in the process
521     * of being started.
522     */
523    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
524
525    /**
526     * Processes that are being forcibly torn down.
527     */
528    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
529
530    /**
531     * List of running applications, sorted by recent usage.
532     * The first entry in the list is the least recently used.
533     */
534    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
535
536    /**
537     * Where in mLruProcesses that the processes hosting activities start.
538     */
539    int mLruProcessActivityStart = 0;
540
541    /**
542     * Where in mLruProcesses that the processes hosting services start.
543     * This is after (lower index) than mLruProcessesActivityStart.
544     */
545    int mLruProcessServiceStart = 0;
546
547    /**
548     * List of processes that should gc as soon as things are idle.
549     */
550    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
551
552    /**
553     * Processes we want to collect PSS data from.
554     */
555    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
556
557    /**
558     * Last time we requested PSS data of all processes.
559     */
560    long mLastFullPssTime = SystemClock.uptimeMillis();
561
562    /**
563     * This is the process holding what we currently consider to be
564     * the "home" activity.
565     */
566    ProcessRecord mHomeProcess;
567
568    /**
569     * This is the process holding the activity the user last visited that
570     * is in a different process from the one they are currently in.
571     */
572    ProcessRecord mPreviousProcess;
573
574    /**
575     * The time at which the previous process was last visible.
576     */
577    long mPreviousProcessVisibleTime;
578
579    /**
580     * Which uses have been started, so are allowed to run code.
581     */
582    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
583
584    /**
585     * LRU list of history of current users.  Most recently current is at the end.
586     */
587    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
588
589    /**
590     * Constant array of the users that are currently started.
591     */
592    int[] mStartedUserArray = new int[] { 0 };
593
594    /**
595     * Registered observers of the user switching mechanics.
596     */
597    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
598            = new RemoteCallbackList<IUserSwitchObserver>();
599
600    /**
601     * Currently active user switch.
602     */
603    Object mCurUserSwitchCallback;
604
605    /**
606     * Packages that the user has asked to have run in screen size
607     * compatibility mode instead of filling the screen.
608     */
609    final CompatModePackages mCompatModePackages;
610
611    /**
612     * Set of IntentSenderRecord objects that are currently active.
613     */
614    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
615            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
616
617    /**
618     * Fingerprints (hashCode()) of stack traces that we've
619     * already logged DropBox entries for.  Guarded by itself.  If
620     * something (rogue user app) forces this over
621     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
622     */
623    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
624    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
625
626    /**
627     * Strict Mode background batched logging state.
628     *
629     * The string buffer is guarded by itself, and its lock is also
630     * used to determine if another batched write is already
631     * in-flight.
632     */
633    private final StringBuilder mStrictModeBuffer = new StringBuilder();
634
635    /**
636     * Keeps track of all IIntentReceivers that have been registered for
637     * broadcasts.  Hash keys are the receiver IBinder, hash value is
638     * a ReceiverList.
639     */
640    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
641            new HashMap<IBinder, ReceiverList>();
642
643    /**
644     * Resolver for broadcast intents to registered receivers.
645     * Holds BroadcastFilter (subclass of IntentFilter).
646     */
647    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
648            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
649        @Override
650        protected boolean allowFilterResult(
651                BroadcastFilter filter, List<BroadcastFilter> dest) {
652            IBinder target = filter.receiverList.receiver.asBinder();
653            for (int i=dest.size()-1; i>=0; i--) {
654                if (dest.get(i).receiverList.receiver.asBinder() == target) {
655                    return false;
656                }
657            }
658            return true;
659        }
660
661        @Override
662        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
663            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
664                    || userId == filter.owningUserId) {
665                return super.newResult(filter, match, userId);
666            }
667            return null;
668        }
669
670        @Override
671        protected BroadcastFilter[] newArray(int size) {
672            return new BroadcastFilter[size];
673        }
674
675        @Override
676        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
677            return packageName.equals(filter.packageName);
678        }
679    };
680
681    /**
682     * State of all active sticky broadcasts per user.  Keys are the action of the
683     * sticky Intent, values are an ArrayList of all broadcasted intents with
684     * that action (which should usually be one).  The SparseArray is keyed
685     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
686     * for stickies that are sent to all users.
687     */
688    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
689            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
690
691    final ActiveServices mServices;
692
693    /**
694     * Backup/restore process management
695     */
696    String mBackupAppName = null;
697    BackupRecord mBackupTarget = null;
698
699    /**
700     * List of PendingThumbnailsRecord objects of clients who are still
701     * waiting to receive all of the thumbnails for a task.
702     */
703    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
704            new ArrayList<PendingThumbnailsRecord>();
705
706    final ProviderMap mProviderMap;
707
708    /**
709     * List of content providers who have clients waiting for them.  The
710     * application is currently being launched and the provider will be
711     * removed from this list once it is published.
712     */
713    final ArrayList<ContentProviderRecord> mLaunchingProviders
714            = new ArrayList<ContentProviderRecord>();
715
716    /**
717     * File storing persisted {@link #mGrantedUriPermissions}.
718     */
719    private final AtomicFile mGrantFile;
720
721    /** XML constants used in {@link #mGrantFile} */
722    private static final String TAG_URI_GRANTS = "uri-grants";
723    private static final String TAG_URI_GRANT = "uri-grant";
724    private static final String ATTR_USER_HANDLE = "userHandle";
725    private static final String ATTR_SOURCE_PKG = "sourcePkg";
726    private static final String ATTR_TARGET_PKG = "targetPkg";
727    private static final String ATTR_URI = "uri";
728    private static final String ATTR_MODE_FLAGS = "modeFlags";
729    private static final String ATTR_CREATED_TIME = "createdTime";
730    private static final String ATTR_PREFIX = "prefix";
731
732    /**
733     * Global set of specific {@link Uri} permissions that have been granted.
734     * This optimized lookup structure maps from {@link UriPermission#targetUid}
735     * to {@link UriPermission#uri} to {@link UriPermission}.
736     */
737    @GuardedBy("this")
738    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
739            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
740
741    public static class GrantUri {
742        public final Uri uri;
743        public final boolean prefix;
744
745        public GrantUri(Uri uri, boolean prefix) {
746            this.uri = uri;
747            this.prefix = prefix;
748        }
749
750        @Override
751        public int hashCode() {
752            return toString().hashCode();
753        }
754
755        @Override
756        public boolean equals(Object o) {
757            if (o instanceof GrantUri) {
758                GrantUri other = (GrantUri) o;
759                return uri.equals(other.uri) && prefix == other.prefix;
760            }
761            return false;
762        }
763
764        @Override
765        public String toString() {
766            if (prefix) {
767                return uri.toString() + " [prefix]";
768            } else {
769                return uri.toString();
770            }
771        }
772    }
773
774    CoreSettingsObserver mCoreSettingsObserver;
775
776    /**
777     * Thread-local storage used to carry caller permissions over through
778     * indirect content-provider access.
779     */
780    private class Identity {
781        public int pid;
782        public int uid;
783
784        Identity(int _pid, int _uid) {
785            pid = _pid;
786            uid = _uid;
787        }
788    }
789
790    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
791
792    /**
793     * All information we have collected about the runtime performance of
794     * any user id that can impact battery performance.
795     */
796    final BatteryStatsService mBatteryStatsService;
797
798    /**
799     * Information about component usage
800     */
801    final UsageStatsService mUsageStatsService;
802
803    /**
804     * Information about and control over application operations
805     */
806    final AppOpsService mAppOpsService;
807
808    /**
809     * Current configuration information.  HistoryRecord objects are given
810     * a reference to this object to indicate which configuration they are
811     * currently running in, so this object must be kept immutable.
812     */
813    Configuration mConfiguration = new Configuration();
814
815    /**
816     * Current sequencing integer of the configuration, for skipping old
817     * configurations.
818     */
819    int mConfigurationSeq = 0;
820
821    /**
822     * Hardware-reported OpenGLES version.
823     */
824    final int GL_ES_VERSION;
825
826    /**
827     * List of initialization arguments to pass to all processes when binding applications to them.
828     * For example, references to the commonly used services.
829     */
830    HashMap<String, IBinder> mAppBindArgs;
831
832    /**
833     * Temporary to avoid allocations.  Protected by main lock.
834     */
835    final StringBuilder mStringBuilder = new StringBuilder(256);
836
837    /**
838     * Used to control how we initialize the service.
839     */
840    ComponentName mTopComponent;
841    String mTopAction = Intent.ACTION_MAIN;
842    String mTopData;
843    boolean mProcessesReady = false;
844    boolean mSystemReady = false;
845    boolean mBooting = false;
846    boolean mWaitingUpdate = false;
847    boolean mDidUpdate = false;
848    boolean mOnBattery = false;
849    boolean mLaunchWarningShown = false;
850
851    Context mContext;
852
853    int mFactoryTest;
854
855    boolean mCheckedForSetup;
856
857    /**
858     * The time at which we will allow normal application switches again,
859     * after a call to {@link #stopAppSwitches()}.
860     */
861    long mAppSwitchesAllowedTime;
862
863    /**
864     * This is set to true after the first switch after mAppSwitchesAllowedTime
865     * is set; any switches after that will clear the time.
866     */
867    boolean mDidAppSwitch;
868
869    /**
870     * Last time (in realtime) at which we checked for power usage.
871     */
872    long mLastPowerCheckRealtime;
873
874    /**
875     * Last time (in uptime) at which we checked for power usage.
876     */
877    long mLastPowerCheckUptime;
878
879    /**
880     * Set while we are wanting to sleep, to prevent any
881     * activities from being started/resumed.
882     */
883    boolean mSleeping = false;
884
885    /**
886     * State of external calls telling us if the device is asleep.
887     */
888    boolean mWentToSleep = false;
889
890    /**
891     * State of external call telling us if the lock screen is shown.
892     */
893    boolean mLockScreenShown = false;
894
895    /**
896     * Set if we are shutting down the system, similar to sleeping.
897     */
898    boolean mShuttingDown = false;
899
900    /**
901     * Current sequence id for oom_adj computation traversal.
902     */
903    int mAdjSeq = 0;
904
905    /**
906     * Current sequence id for process LRU updating.
907     */
908    int mLruSeq = 0;
909
910    /**
911     * Keep track of the non-cached/empty process we last found, to help
912     * determine how to distribute cached/empty processes next time.
913     */
914    int mNumNonCachedProcs = 0;
915
916    /**
917     * Keep track of the number of cached hidden procs, to balance oom adj
918     * distribution between those and empty procs.
919     */
920    int mNumCachedHiddenProcs = 0;
921
922    /**
923     * Keep track of the number of service processes we last found, to
924     * determine on the next iteration which should be B services.
925     */
926    int mNumServiceProcs = 0;
927    int mNewNumAServiceProcs = 0;
928    int mNewNumServiceProcs = 0;
929
930    /**
931     * Allow the current computed overall memory level of the system to go down?
932     * This is set to false when we are killing processes for reasons other than
933     * memory management, so that the now smaller process list will not be taken as
934     * an indication that memory is tighter.
935     */
936    boolean mAllowLowerMemLevel = false;
937
938    /**
939     * The last computed memory level, for holding when we are in a state that
940     * processes are going away for other reasons.
941     */
942    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
943
944    /**
945     * The last total number of process we have, to determine if changes actually look
946     * like a shrinking number of process due to lower RAM.
947     */
948    int mLastNumProcesses;
949
950    /**
951     * The uptime of the last time we performed idle maintenance.
952     */
953    long mLastIdleTime = SystemClock.uptimeMillis();
954
955    /**
956     * Total time spent with RAM that has been added in the past since the last idle time.
957     */
958    long mLowRamTimeSinceLastIdle = 0;
959
960    /**
961     * If RAM is currently low, when that horrible situation started.
962     */
963    long mLowRamStartTime = 0;
964
965    /**
966     * For reporting to battery stats the current top application.
967     */
968    private String mCurResumedPackage = null;
969    private int mCurResumedUid = -1;
970
971    /**
972     * For reporting to battery stats the apps currently running foreground
973     * service.  The ProcessMap is package/uid tuples; each of these contain
974     * an array of the currently foreground processes.
975     */
976    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
977            = new ProcessMap<ArrayList<ProcessRecord>>();
978
979    /**
980     * This is set if we had to do a delayed dexopt of an app before launching
981     * it, to increasing the ANR timeouts in that case.
982     */
983    boolean mDidDexOpt;
984
985    /**
986     * Set if the systemServer made a call to enterSafeMode.
987     */
988    boolean mSafeMode;
989
990    String mDebugApp = null;
991    boolean mWaitForDebugger = false;
992    boolean mDebugTransient = false;
993    String mOrigDebugApp = null;
994    boolean mOrigWaitForDebugger = false;
995    boolean mAlwaysFinishActivities = false;
996    IActivityController mController = null;
997    String mProfileApp = null;
998    ProcessRecord mProfileProc = null;
999    String mProfileFile;
1000    ParcelFileDescriptor mProfileFd;
1001    int mProfileType = 0;
1002    boolean mAutoStopProfiler = false;
1003    String mOpenGlTraceApp = null;
1004
1005    static class ProcessChangeItem {
1006        static final int CHANGE_ACTIVITIES = 1<<0;
1007        static final int CHANGE_IMPORTANCE= 1<<1;
1008        int changes;
1009        int uid;
1010        int pid;
1011        int importance;
1012        boolean foregroundActivities;
1013    }
1014
1015    final RemoteCallbackList<IProcessObserver> mProcessObservers
1016            = new RemoteCallbackList<IProcessObserver>();
1017    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1018
1019    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1020            = new ArrayList<ProcessChangeItem>();
1021    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1022            = new ArrayList<ProcessChangeItem>();
1023
1024    /**
1025     * Runtime CPU use collection thread.  This object's lock is used to
1026     * protect all related state.
1027     */
1028    final Thread mProcessCpuThread;
1029
1030    /**
1031     * Used to collect process stats when showing not responding dialog.
1032     * Protected by mProcessCpuThread.
1033     */
1034    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1035            MONITOR_THREAD_CPU_USAGE);
1036    final AtomicLong mLastCpuTime = new AtomicLong(0);
1037    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1038
1039    long mLastWriteTime = 0;
1040
1041    /**
1042     * Used to retain an update lock when the foreground activity is in
1043     * immersive mode.
1044     */
1045    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1046
1047    /**
1048     * Set to true after the system has finished booting.
1049     */
1050    boolean mBooted = false;
1051
1052    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1053    int mProcessLimitOverride = -1;
1054
1055    WindowManagerService mWindowManager;
1056
1057    final ActivityThread mSystemThread;
1058
1059    int mCurrentUserId = 0;
1060    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1061    private UserManagerService mUserManager;
1062
1063    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1064        final ProcessRecord mApp;
1065        final int mPid;
1066        final IApplicationThread mAppThread;
1067
1068        AppDeathRecipient(ProcessRecord app, int pid,
1069                IApplicationThread thread) {
1070            if (localLOGV) Slog.v(
1071                TAG, "New death recipient " + this
1072                + " for thread " + thread.asBinder());
1073            mApp = app;
1074            mPid = pid;
1075            mAppThread = thread;
1076        }
1077
1078        @Override
1079        public void binderDied() {
1080            if (localLOGV) Slog.v(
1081                TAG, "Death received in " + this
1082                + " for thread " + mAppThread.asBinder());
1083            synchronized(ActivityManagerService.this) {
1084                appDiedLocked(mApp, mPid, mAppThread);
1085            }
1086        }
1087    }
1088
1089    static final int SHOW_ERROR_MSG = 1;
1090    static final int SHOW_NOT_RESPONDING_MSG = 2;
1091    static final int SHOW_FACTORY_ERROR_MSG = 3;
1092    static final int UPDATE_CONFIGURATION_MSG = 4;
1093    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1094    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1095    static final int SERVICE_TIMEOUT_MSG = 12;
1096    static final int UPDATE_TIME_ZONE = 13;
1097    static final int SHOW_UID_ERROR_MSG = 14;
1098    static final int IM_FEELING_LUCKY_MSG = 15;
1099    static final int PROC_START_TIMEOUT_MSG = 20;
1100    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1101    static final int KILL_APPLICATION_MSG = 22;
1102    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1103    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1104    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1105    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1106    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1107    static final int CLEAR_DNS_CACHE_MSG = 28;
1108    static final int UPDATE_HTTP_PROXY_MSG = 29;
1109    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1110    static final int DISPATCH_PROCESSES_CHANGED = 31;
1111    static final int DISPATCH_PROCESS_DIED = 32;
1112    static final int REPORT_MEM_USAGE_MSG = 33;
1113    static final int REPORT_USER_SWITCH_MSG = 34;
1114    static final int CONTINUE_USER_SWITCH_MSG = 35;
1115    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1116    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1117    static final int PERSIST_URI_GRANTS_MSG = 38;
1118    static final int REQUEST_ALL_PSS_MSG = 39;
1119    static final int START_PROFILES_MSG = 40;
1120    static final int UPDATE_TIME = 41;
1121
1122    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1123    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1124    static final int FIRST_COMPAT_MODE_MSG = 300;
1125    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1126
1127    AlertDialog mUidAlert;
1128    CompatModeDialog mCompatModeDialog;
1129    long mLastMemUsageReportTime = 0;
1130
1131    /**
1132     * Flag whether the current user is a "monkey", i.e. whether
1133     * the UI is driven by a UI automation tool.
1134     */
1135    private boolean mUserIsMonkey;
1136
1137    final ServiceThread mHandlerThread;
1138    final MainHandler mHandler;
1139
1140    final class MainHandler extends Handler {
1141        public MainHandler(Looper looper) {
1142            super(looper, null, true);
1143        }
1144
1145        @Override
1146        public void handleMessage(Message msg) {
1147            switch (msg.what) {
1148            case SHOW_ERROR_MSG: {
1149                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1150                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1151                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1152                synchronized (ActivityManagerService.this) {
1153                    ProcessRecord proc = (ProcessRecord)data.get("app");
1154                    AppErrorResult res = (AppErrorResult) data.get("result");
1155                    if (proc != null && proc.crashDialog != null) {
1156                        Slog.e(TAG, "App already has crash dialog: " + proc);
1157                        if (res != null) {
1158                            res.set(0);
1159                        }
1160                        return;
1161                    }
1162                    if (!showBackground && UserHandle.getAppId(proc.uid)
1163                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1164                            && proc.pid != MY_PID) {
1165                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1166                        if (res != null) {
1167                            res.set(0);
1168                        }
1169                        return;
1170                    }
1171                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1172                        Dialog d = new AppErrorDialog(mContext,
1173                                ActivityManagerService.this, res, proc);
1174                        d.show();
1175                        proc.crashDialog = d;
1176                    } else {
1177                        // The device is asleep, so just pretend that the user
1178                        // saw a crash dialog and hit "force quit".
1179                        if (res != null) {
1180                            res.set(0);
1181                        }
1182                    }
1183                }
1184
1185                ensureBootCompleted();
1186            } break;
1187            case SHOW_NOT_RESPONDING_MSG: {
1188                synchronized (ActivityManagerService.this) {
1189                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1190                    ProcessRecord proc = (ProcessRecord)data.get("app");
1191                    if (proc != null && proc.anrDialog != null) {
1192                        Slog.e(TAG, "App already has anr dialog: " + proc);
1193                        return;
1194                    }
1195
1196                    Intent intent = new Intent("android.intent.action.ANR");
1197                    if (!mProcessesReady) {
1198                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1199                                | Intent.FLAG_RECEIVER_FOREGROUND);
1200                    }
1201                    broadcastIntentLocked(null, null, intent,
1202                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1203                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1204
1205                    if (mShowDialogs) {
1206                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1207                                mContext, proc, (ActivityRecord)data.get("activity"),
1208                                msg.arg1 != 0);
1209                        d.show();
1210                        proc.anrDialog = d;
1211                    } else {
1212                        // Just kill the app if there is no dialog to be shown.
1213                        killAppAtUsersRequest(proc, null);
1214                    }
1215                }
1216
1217                ensureBootCompleted();
1218            } break;
1219            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1220                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1221                synchronized (ActivityManagerService.this) {
1222                    ProcessRecord proc = (ProcessRecord) data.get("app");
1223                    if (proc == null) {
1224                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1225                        break;
1226                    }
1227                    if (proc.crashDialog != null) {
1228                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1229                        return;
1230                    }
1231                    AppErrorResult res = (AppErrorResult) data.get("result");
1232                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1233                        Dialog d = new StrictModeViolationDialog(mContext,
1234                                ActivityManagerService.this, res, proc);
1235                        d.show();
1236                        proc.crashDialog = d;
1237                    } else {
1238                        // The device is asleep, so just pretend that the user
1239                        // saw a crash dialog and hit "force quit".
1240                        res.set(0);
1241                    }
1242                }
1243                ensureBootCompleted();
1244            } break;
1245            case SHOW_FACTORY_ERROR_MSG: {
1246                Dialog d = new FactoryErrorDialog(
1247                    mContext, msg.getData().getCharSequence("msg"));
1248                d.show();
1249                ensureBootCompleted();
1250            } break;
1251            case UPDATE_CONFIGURATION_MSG: {
1252                final ContentResolver resolver = mContext.getContentResolver();
1253                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1254            } break;
1255            case GC_BACKGROUND_PROCESSES_MSG: {
1256                synchronized (ActivityManagerService.this) {
1257                    performAppGcsIfAppropriateLocked();
1258                }
1259            } break;
1260            case WAIT_FOR_DEBUGGER_MSG: {
1261                synchronized (ActivityManagerService.this) {
1262                    ProcessRecord app = (ProcessRecord)msg.obj;
1263                    if (msg.arg1 != 0) {
1264                        if (!app.waitedForDebugger) {
1265                            Dialog d = new AppWaitingForDebuggerDialog(
1266                                    ActivityManagerService.this,
1267                                    mContext, app);
1268                            app.waitDialog = d;
1269                            app.waitedForDebugger = true;
1270                            d.show();
1271                        }
1272                    } else {
1273                        if (app.waitDialog != null) {
1274                            app.waitDialog.dismiss();
1275                            app.waitDialog = null;
1276                        }
1277                    }
1278                }
1279            } break;
1280            case SERVICE_TIMEOUT_MSG: {
1281                if (mDidDexOpt) {
1282                    mDidDexOpt = false;
1283                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1284                    nmsg.obj = msg.obj;
1285                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1286                    return;
1287                }
1288                mServices.serviceTimeout((ProcessRecord)msg.obj);
1289            } break;
1290            case UPDATE_TIME_ZONE: {
1291                synchronized (ActivityManagerService.this) {
1292                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1293                        ProcessRecord r = mLruProcesses.get(i);
1294                        if (r.thread != null) {
1295                            try {
1296                                r.thread.updateTimeZone();
1297                            } catch (RemoteException ex) {
1298                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1299                            }
1300                        }
1301                    }
1302                }
1303            } break;
1304            case CLEAR_DNS_CACHE_MSG: {
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.clearDnsCache();
1311                            } catch (RemoteException ex) {
1312                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1313                            }
1314                        }
1315                    }
1316                }
1317            } break;
1318            case UPDATE_HTTP_PROXY_MSG: {
1319                ProxyProperties proxy = (ProxyProperties)msg.obj;
1320                String host = "";
1321                String port = "";
1322                String exclList = "";
1323                String pacFileUrl = null;
1324                if (proxy != null) {
1325                    host = proxy.getHost();
1326                    port = Integer.toString(proxy.getPort());
1327                    exclList = proxy.getExclusionList();
1328                    pacFileUrl = proxy.getPacFileUrl();
1329                }
1330                synchronized (ActivityManagerService.this) {
1331                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1332                        ProcessRecord r = mLruProcesses.get(i);
1333                        if (r.thread != null) {
1334                            try {
1335                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1336                            } catch (RemoteException ex) {
1337                                Slog.w(TAG, "Failed to update http proxy for: " +
1338                                        r.info.processName);
1339                            }
1340                        }
1341                    }
1342                }
1343            } break;
1344            case SHOW_UID_ERROR_MSG: {
1345                String title = "System UIDs Inconsistent";
1346                String text = "UIDs on the system are inconsistent, you need to wipe your"
1347                        + " data partition or your device will be unstable.";
1348                Log.e(TAG, title + ": " + text);
1349                if (mShowDialogs) {
1350                    // XXX This is a temporary dialog, no need to localize.
1351                    AlertDialog d = new BaseErrorDialog(mContext);
1352                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1353                    d.setCancelable(false);
1354                    d.setTitle(title);
1355                    d.setMessage(text);
1356                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1357                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1358                    mUidAlert = d;
1359                    d.show();
1360                }
1361            } break;
1362            case IM_FEELING_LUCKY_MSG: {
1363                if (mUidAlert != null) {
1364                    mUidAlert.dismiss();
1365                    mUidAlert = null;
1366                }
1367            } break;
1368            case PROC_START_TIMEOUT_MSG: {
1369                if (mDidDexOpt) {
1370                    mDidDexOpt = false;
1371                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1372                    nmsg.obj = msg.obj;
1373                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1374                    return;
1375                }
1376                ProcessRecord app = (ProcessRecord)msg.obj;
1377                synchronized (ActivityManagerService.this) {
1378                    processStartTimedOutLocked(app);
1379                }
1380            } break;
1381            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1382                synchronized (ActivityManagerService.this) {
1383                    doPendingActivityLaunchesLocked(true);
1384                }
1385            } break;
1386            case KILL_APPLICATION_MSG: {
1387                synchronized (ActivityManagerService.this) {
1388                    int appid = msg.arg1;
1389                    boolean restart = (msg.arg2 == 1);
1390                    Bundle bundle = (Bundle)msg.obj;
1391                    String pkg = bundle.getString("pkg");
1392                    String reason = bundle.getString("reason");
1393                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1394                            false, UserHandle.USER_ALL, reason);
1395                }
1396            } break;
1397            case FINALIZE_PENDING_INTENT_MSG: {
1398                ((PendingIntentRecord)msg.obj).completeFinalize();
1399            } break;
1400            case POST_HEAVY_NOTIFICATION_MSG: {
1401                INotificationManager inm = NotificationManager.getService();
1402                if (inm == null) {
1403                    return;
1404                }
1405
1406                ActivityRecord root = (ActivityRecord)msg.obj;
1407                ProcessRecord process = root.app;
1408                if (process == null) {
1409                    return;
1410                }
1411
1412                try {
1413                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1414                    String text = mContext.getString(R.string.heavy_weight_notification,
1415                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1416                    Notification notification = new Notification();
1417                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1418                    notification.when = 0;
1419                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1420                    notification.tickerText = text;
1421                    notification.defaults = 0; // please be quiet
1422                    notification.sound = null;
1423                    notification.vibrate = null;
1424                    notification.setLatestEventInfo(context, text,
1425                            mContext.getText(R.string.heavy_weight_notification_detail),
1426                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1427                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1428                                    new UserHandle(root.userId)));
1429
1430                    try {
1431                        int[] outId = new int[1];
1432                        inm.enqueueNotificationWithTag("android", "android", null,
1433                                R.string.heavy_weight_notification,
1434                                notification, outId, root.userId);
1435                    } catch (RuntimeException e) {
1436                        Slog.w(ActivityManagerService.TAG,
1437                                "Error showing notification for heavy-weight app", e);
1438                    } catch (RemoteException e) {
1439                    }
1440                } catch (NameNotFoundException e) {
1441                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1442                }
1443            } break;
1444            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1445                INotificationManager inm = NotificationManager.getService();
1446                if (inm == null) {
1447                    return;
1448                }
1449                try {
1450                    inm.cancelNotificationWithTag("android", null,
1451                            R.string.heavy_weight_notification,  msg.arg1);
1452                } catch (RuntimeException e) {
1453                    Slog.w(ActivityManagerService.TAG,
1454                            "Error canceling notification for service", e);
1455                } catch (RemoteException e) {
1456                }
1457            } break;
1458            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1459                synchronized (ActivityManagerService.this) {
1460                    checkExcessivePowerUsageLocked(true);
1461                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1462                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1463                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1464                }
1465            } break;
1466            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1467                synchronized (ActivityManagerService.this) {
1468                    ActivityRecord ar = (ActivityRecord)msg.obj;
1469                    if (mCompatModeDialog != null) {
1470                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1471                                ar.info.applicationInfo.packageName)) {
1472                            return;
1473                        }
1474                        mCompatModeDialog.dismiss();
1475                        mCompatModeDialog = null;
1476                    }
1477                    if (ar != null && false) {
1478                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1479                                ar.packageName)) {
1480                            int mode = mCompatModePackages.computeCompatModeLocked(
1481                                    ar.info.applicationInfo);
1482                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1483                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1484                                mCompatModeDialog = new CompatModeDialog(
1485                                        ActivityManagerService.this, mContext,
1486                                        ar.info.applicationInfo);
1487                                mCompatModeDialog.show();
1488                            }
1489                        }
1490                    }
1491                }
1492                break;
1493            }
1494            case DISPATCH_PROCESSES_CHANGED: {
1495                dispatchProcessesChanged();
1496                break;
1497            }
1498            case DISPATCH_PROCESS_DIED: {
1499                final int pid = msg.arg1;
1500                final int uid = msg.arg2;
1501                dispatchProcessDied(pid, uid);
1502                break;
1503            }
1504            case REPORT_MEM_USAGE_MSG: {
1505                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1506                Thread thread = new Thread() {
1507                    @Override public void run() {
1508                        final SparseArray<ProcessMemInfo> infoMap
1509                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1510                        for (int i=0, N=memInfos.size(); i<N; i++) {
1511                            ProcessMemInfo mi = memInfos.get(i);
1512                            infoMap.put(mi.pid, mi);
1513                        }
1514                        updateCpuStatsNow();
1515                        synchronized (mProcessCpuThread) {
1516                            final int N = mProcessCpuTracker.countStats();
1517                            for (int i=0; i<N; i++) {
1518                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1519                                if (st.vsize > 0) {
1520                                    long pss = Debug.getPss(st.pid, null);
1521                                    if (pss > 0) {
1522                                        if (infoMap.indexOfKey(st.pid) < 0) {
1523                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1524                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1525                                            mi.pss = pss;
1526                                            memInfos.add(mi);
1527                                        }
1528                                    }
1529                                }
1530                            }
1531                        }
1532
1533                        long totalPss = 0;
1534                        for (int i=0, N=memInfos.size(); i<N; i++) {
1535                            ProcessMemInfo mi = memInfos.get(i);
1536                            if (mi.pss == 0) {
1537                                mi.pss = Debug.getPss(mi.pid, null);
1538                            }
1539                            totalPss += mi.pss;
1540                        }
1541                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1542                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1543                                if (lhs.oomAdj != rhs.oomAdj) {
1544                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1545                                }
1546                                if (lhs.pss != rhs.pss) {
1547                                    return lhs.pss < rhs.pss ? 1 : -1;
1548                                }
1549                                return 0;
1550                            }
1551                        });
1552
1553                        StringBuilder tag = new StringBuilder(128);
1554                        StringBuilder stack = new StringBuilder(128);
1555                        tag.append("Low on memory -- ");
1556                        appendMemBucket(tag, totalPss, "total", false);
1557                        appendMemBucket(stack, totalPss, "total", true);
1558
1559                        StringBuilder logBuilder = new StringBuilder(1024);
1560                        logBuilder.append("Low on memory:\n");
1561
1562                        boolean firstLine = true;
1563                        int lastOomAdj = Integer.MIN_VALUE;
1564                        for (int i=0, N=memInfos.size(); i<N; i++) {
1565                            ProcessMemInfo mi = memInfos.get(i);
1566
1567                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1568                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1569                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1570                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1571                                if (lastOomAdj != mi.oomAdj) {
1572                                    lastOomAdj = mi.oomAdj;
1573                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1574                                        tag.append(" / ");
1575                                    }
1576                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1577                                        if (firstLine) {
1578                                            stack.append(":");
1579                                            firstLine = false;
1580                                        }
1581                                        stack.append("\n\t at ");
1582                                    } else {
1583                                        stack.append("$");
1584                                    }
1585                                } else {
1586                                    tag.append(" ");
1587                                    stack.append("$");
1588                                }
1589                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1590                                    appendMemBucket(tag, mi.pss, mi.name, false);
1591                                }
1592                                appendMemBucket(stack, mi.pss, mi.name, true);
1593                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1594                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1595                                    stack.append("(");
1596                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1597                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1598                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1599                                            stack.append(":");
1600                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1601                                        }
1602                                    }
1603                                    stack.append(")");
1604                                }
1605                            }
1606
1607                            logBuilder.append("  ");
1608                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1609                            logBuilder.append(' ');
1610                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1611                            logBuilder.append(' ');
1612                            ProcessList.appendRamKb(logBuilder, mi.pss);
1613                            logBuilder.append(" kB: ");
1614                            logBuilder.append(mi.name);
1615                            logBuilder.append(" (");
1616                            logBuilder.append(mi.pid);
1617                            logBuilder.append(") ");
1618                            logBuilder.append(mi.adjType);
1619                            logBuilder.append('\n');
1620                            if (mi.adjReason != null) {
1621                                logBuilder.append("                      ");
1622                                logBuilder.append(mi.adjReason);
1623                                logBuilder.append('\n');
1624                            }
1625                        }
1626
1627                        logBuilder.append("           ");
1628                        ProcessList.appendRamKb(logBuilder, totalPss);
1629                        logBuilder.append(" kB: TOTAL\n");
1630
1631                        long[] infos = new long[Debug.MEMINFO_COUNT];
1632                        Debug.getMemInfo(infos);
1633                        logBuilder.append("  MemInfo: ");
1634                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1635                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1636                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1637                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1638                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1639                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1640                            logBuilder.append("  ZRAM: ");
1641                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1642                            logBuilder.append(" kB RAM, ");
1643                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1644                            logBuilder.append(" kB swap total, ");
1645                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1646                            logBuilder.append(" kB swap free\n");
1647                        }
1648                        Slog.i(TAG, logBuilder.toString());
1649
1650                        StringBuilder dropBuilder = new StringBuilder(1024);
1651                        /*
1652                        StringWriter oomSw = new StringWriter();
1653                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1654                        StringWriter catSw = new StringWriter();
1655                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1656                        String[] emptyArgs = new String[] { };
1657                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1658                        oomPw.flush();
1659                        String oomString = oomSw.toString();
1660                        */
1661                        dropBuilder.append(stack);
1662                        dropBuilder.append('\n');
1663                        dropBuilder.append('\n');
1664                        dropBuilder.append(logBuilder);
1665                        dropBuilder.append('\n');
1666                        /*
1667                        dropBuilder.append(oomString);
1668                        dropBuilder.append('\n');
1669                        */
1670                        StringWriter catSw = new StringWriter();
1671                        synchronized (ActivityManagerService.this) {
1672                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1673                            String[] emptyArgs = new String[] { };
1674                            catPw.println();
1675                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1676                            catPw.println();
1677                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1678                                    false, false, null);
1679                            catPw.println();
1680                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1681                            catPw.flush();
1682                        }
1683                        dropBuilder.append(catSw.toString());
1684                        addErrorToDropBox("lowmem", null, "system_server", null,
1685                                null, tag.toString(), dropBuilder.toString(), null, null);
1686                        //Slog.i(TAG, "Sent to dropbox:");
1687                        //Slog.i(TAG, dropBuilder.toString());
1688                        synchronized (ActivityManagerService.this) {
1689                            long now = SystemClock.uptimeMillis();
1690                            if (mLastMemUsageReportTime < now) {
1691                                mLastMemUsageReportTime = now;
1692                            }
1693                        }
1694                    }
1695                };
1696                thread.start();
1697                break;
1698            }
1699            case REPORT_USER_SWITCH_MSG: {
1700                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1701                break;
1702            }
1703            case CONTINUE_USER_SWITCH_MSG: {
1704                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1705                break;
1706            }
1707            case USER_SWITCH_TIMEOUT_MSG: {
1708                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1709                break;
1710            }
1711            case IMMERSIVE_MODE_LOCK_MSG: {
1712                final boolean nextState = (msg.arg1 != 0);
1713                if (mUpdateLock.isHeld() != nextState) {
1714                    if (DEBUG_IMMERSIVE) {
1715                        final ActivityRecord r = (ActivityRecord) msg.obj;
1716                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1717                    }
1718                    if (nextState) {
1719                        mUpdateLock.acquire();
1720                    } else {
1721                        mUpdateLock.release();
1722                    }
1723                }
1724                break;
1725            }
1726            case PERSIST_URI_GRANTS_MSG: {
1727                writeGrantedUriPermissions();
1728                break;
1729            }
1730            case REQUEST_ALL_PSS_MSG: {
1731                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1732                break;
1733            }
1734            case START_PROFILES_MSG: {
1735                synchronized (ActivityManagerService.this) {
1736                    startProfilesLocked();
1737                }
1738                break;
1739            }
1740            case UPDATE_TIME: {
1741                synchronized (ActivityManagerService.this) {
1742                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1743                        ProcessRecord r = mLruProcesses.get(i);
1744                        if (r.thread != null) {
1745                            try {
1746                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1747                            } catch (RemoteException ex) {
1748                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1749                            }
1750                        }
1751                    }
1752                }
1753                break;
1754            }
1755            }
1756        }
1757    };
1758
1759    static final int COLLECT_PSS_BG_MSG = 1;
1760
1761    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1762        @Override
1763        public void handleMessage(Message msg) {
1764            switch (msg.what) {
1765            case COLLECT_PSS_BG_MSG: {
1766                int i=0, num=0;
1767                long start = SystemClock.uptimeMillis();
1768                long[] tmp = new long[1];
1769                do {
1770                    ProcessRecord proc;
1771                    int procState;
1772                    int pid;
1773                    synchronized (ActivityManagerService.this) {
1774                        if (i >= mPendingPssProcesses.size()) {
1775                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1776                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1777                            mPendingPssProcesses.clear();
1778                            return;
1779                        }
1780                        proc = mPendingPssProcesses.get(i);
1781                        procState = proc.pssProcState;
1782                        if (proc.thread != null && procState == proc.setProcState) {
1783                            pid = proc.pid;
1784                        } else {
1785                            proc = null;
1786                            pid = 0;
1787                        }
1788                        i++;
1789                    }
1790                    if (proc != null) {
1791                        long pss = Debug.getPss(pid, tmp);
1792                        synchronized (ActivityManagerService.this) {
1793                            if (proc.thread != null && proc.setProcState == procState
1794                                    && proc.pid == pid) {
1795                                num++;
1796                                proc.lastPssTime = SystemClock.uptimeMillis();
1797                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1798                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1799                                        + ": " + pss + " lastPss=" + proc.lastPss
1800                                        + " state=" + ProcessList.makeProcStateString(procState));
1801                                if (proc.initialIdlePss == 0) {
1802                                    proc.initialIdlePss = pss;
1803                                }
1804                                proc.lastPss = pss;
1805                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1806                                    proc.lastCachedPss = pss;
1807                                }
1808                            }
1809                        }
1810                    }
1811                } while (true);
1812            }
1813            }
1814        }
1815    };
1816
1817    /**
1818     * Monitor for package changes and update our internal state.
1819     */
1820    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1821        @Override
1822        public void onPackageRemoved(String packageName, int uid) {
1823            // Remove all tasks with activities in the specified package from the list of recent tasks
1824            synchronized (ActivityManagerService.this) {
1825                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1826                    TaskRecord tr = mRecentTasks.get(i);
1827                    ComponentName cn = tr.intent.getComponent();
1828                    if (cn != null && cn.getPackageName().equals(packageName)) {
1829                        // If the package name matches, remove the task and kill the process
1830                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1831                    }
1832                }
1833            }
1834        }
1835
1836        @Override
1837        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1838            final PackageManager pm = mContext.getPackageManager();
1839            final ArrayList<TaskRecord> recentTasks = new ArrayList<TaskRecord>();
1840            final ArrayList<TaskRecord> tasksToRemove = new ArrayList<TaskRecord>();
1841            // Copy the list of recent tasks so that we don't hold onto the lock on
1842            // ActivityManagerService for long periods while checking if components exist.
1843            synchronized (ActivityManagerService.this) {
1844                recentTasks.addAll(mRecentTasks);
1845            }
1846            // Check the recent tasks and filter out all tasks with components that no longer exist.
1847            Intent tmpI = new Intent();
1848            for (int i = recentTasks.size() - 1; i >= 0; i--) {
1849                TaskRecord tr = recentTasks.get(i);
1850                ComponentName cn = tr.intent.getComponent();
1851                if (cn != null && cn.getPackageName().equals(packageName)) {
1852                    try {
1853                        // Add the task to the list to remove if the component no longer exists
1854                        tmpI.setComponent(cn);
1855                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1856                            tasksToRemove.add(tr);
1857                        }
1858                    } catch (Exception e) {}
1859                }
1860            }
1861            // Prune all the tasks with removed components from the list of recent tasks
1862            synchronized (ActivityManagerService.this) {
1863                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1864                    TaskRecord tr = tasksToRemove.get(i);
1865                    // Remove the task but don't kill the process
1866                    removeTaskByIdLocked(tr.taskId, 0);
1867                }
1868            }
1869            return true;
1870        }
1871
1872        @Override
1873        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1874            // Force stop the specified packages
1875            if (packages != null) {
1876                for (String pkg : packages) {
1877                    synchronized (ActivityManagerService.this) {
1878                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1879                                "finished booting")) {
1880                            return true;
1881                        }
1882                    }
1883                }
1884            }
1885            return false;
1886        }
1887    };
1888
1889    public void setSystemProcess() {
1890        try {
1891            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1892            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1893            ServiceManager.addService("meminfo", new MemBinder(this));
1894            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1895            ServiceManager.addService("dbinfo", new DbBinder(this));
1896            if (MONITOR_CPU_USAGE) {
1897                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1898            }
1899            ServiceManager.addService("permission", new PermissionController(this));
1900
1901            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1902                    "android", STOCK_PM_FLAGS);
1903            mSystemThread.installSystemApplicationInfo(info);
1904
1905            synchronized (this) {
1906                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1907                app.persistent = true;
1908                app.pid = MY_PID;
1909                app.maxAdj = ProcessList.SYSTEM_ADJ;
1910                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1911                mProcessNames.put(app.processName, app.uid, app);
1912                synchronized (mPidsSelfLocked) {
1913                    mPidsSelfLocked.put(app.pid, app);
1914                }
1915                updateLruProcessLocked(app, false, null);
1916                updateOomAdjLocked();
1917            }
1918        } catch (PackageManager.NameNotFoundException e) {
1919            throw new RuntimeException(
1920                    "Unable to find android system package", e);
1921        }
1922    }
1923
1924    public void setWindowManager(WindowManagerService wm) {
1925        mWindowManager = wm;
1926        mStackSupervisor.setWindowManager(wm);
1927    }
1928
1929    public void startObservingNativeCrashes() {
1930        final NativeCrashListener ncl = new NativeCrashListener(this);
1931        ncl.start();
1932    }
1933
1934    public IAppOpsService getAppOpsService() {
1935        return mAppOpsService;
1936    }
1937
1938    static class MemBinder extends Binder {
1939        ActivityManagerService mActivityManagerService;
1940        MemBinder(ActivityManagerService activityManagerService) {
1941            mActivityManagerService = activityManagerService;
1942        }
1943
1944        @Override
1945        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1946            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1947                    != PackageManager.PERMISSION_GRANTED) {
1948                pw.println("Permission Denial: can't dump meminfo from from pid="
1949                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1950                        + " without permission " + android.Manifest.permission.DUMP);
1951                return;
1952            }
1953
1954            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1955        }
1956    }
1957
1958    static class GraphicsBinder extends Binder {
1959        ActivityManagerService mActivityManagerService;
1960        GraphicsBinder(ActivityManagerService activityManagerService) {
1961            mActivityManagerService = activityManagerService;
1962        }
1963
1964        @Override
1965        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1966            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1967                    != PackageManager.PERMISSION_GRANTED) {
1968                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1969                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1970                        + " without permission " + android.Manifest.permission.DUMP);
1971                return;
1972            }
1973
1974            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1975        }
1976    }
1977
1978    static class DbBinder extends Binder {
1979        ActivityManagerService mActivityManagerService;
1980        DbBinder(ActivityManagerService activityManagerService) {
1981            mActivityManagerService = activityManagerService;
1982        }
1983
1984        @Override
1985        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1986            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1987                    != PackageManager.PERMISSION_GRANTED) {
1988                pw.println("Permission Denial: can't dump dbinfo from from pid="
1989                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1990                        + " without permission " + android.Manifest.permission.DUMP);
1991                return;
1992            }
1993
1994            mActivityManagerService.dumpDbInfo(fd, pw, args);
1995        }
1996    }
1997
1998    static class CpuBinder extends Binder {
1999        ActivityManagerService mActivityManagerService;
2000        CpuBinder(ActivityManagerService activityManagerService) {
2001            mActivityManagerService = activityManagerService;
2002        }
2003
2004        @Override
2005        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2006            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2007                    != PackageManager.PERMISSION_GRANTED) {
2008                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2009                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2010                        + " without permission " + android.Manifest.permission.DUMP);
2011                return;
2012            }
2013
2014            synchronized (mActivityManagerService.mProcessCpuThread) {
2015                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2016                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2017                        SystemClock.uptimeMillis()));
2018            }
2019        }
2020    }
2021
2022    public static final class Lifecycle extends SystemService {
2023        private final ActivityManagerService mService;
2024
2025        public Lifecycle(Context context) {
2026            super(context);
2027            mService = new ActivityManagerService(context);
2028        }
2029
2030        @Override
2031        public void onStart() {
2032            mService.start();
2033        }
2034
2035        public ActivityManagerService getService() {
2036            return mService;
2037        }
2038    }
2039
2040    // Note: This method is invoked on the main thread but may need to attach various
2041    // handlers to other threads.  So take care to be explicit about the looper.
2042    public ActivityManagerService(Context systemContext) {
2043        mContext = systemContext;
2044        mFactoryTest = FactoryTest.getMode();
2045        mSystemThread = ActivityThread.currentActivityThread();
2046
2047        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2048
2049        mHandlerThread = new ServiceThread(TAG,
2050                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2051        mHandlerThread.start();
2052        mHandler = new MainHandler(mHandlerThread.getLooper());
2053
2054        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2055                "foreground", BROADCAST_FG_TIMEOUT, false);
2056        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2057                "background", BROADCAST_BG_TIMEOUT, true);
2058        mBroadcastQueues[0] = mFgBroadcastQueue;
2059        mBroadcastQueues[1] = mBgBroadcastQueue;
2060
2061        mServices = new ActiveServices(this);
2062        mProviderMap = new ProviderMap(this);
2063
2064        // TODO: Move creation of battery stats service outside of activity manager service.
2065        File dataDir = Environment.getDataDirectory();
2066        File systemDir = new File(dataDir, "system");
2067        systemDir.mkdirs();
2068        mBatteryStatsService = new BatteryStatsService(new File(
2069                systemDir, "batterystats.bin").toString(), mHandler);
2070        mBatteryStatsService.getActiveStatistics().readLocked();
2071        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2072        mOnBattery = DEBUG_POWER ? true
2073                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2074        mBatteryStatsService.getActiveStatistics().setCallback(this);
2075
2076        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2077
2078        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2079        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2080
2081        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2082
2083        // User 0 is the first and only user that runs at boot.
2084        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2085        mUserLru.add(Integer.valueOf(0));
2086        updateStartedUserArrayLocked();
2087
2088        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2089            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2090
2091        mConfiguration.setToDefaults();
2092        mConfiguration.setLocale(Locale.getDefault());
2093
2094        mConfigurationSeq = mConfiguration.seq = 1;
2095        mProcessCpuTracker.init();
2096
2097        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2098        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2099        mStackSupervisor = new ActivityStackSupervisor(this);
2100
2101        mProcessCpuThread = new Thread("CpuTracker") {
2102            @Override
2103            public void run() {
2104                while (true) {
2105                    try {
2106                        try {
2107                            synchronized(this) {
2108                                final long now = SystemClock.uptimeMillis();
2109                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2110                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2111                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2112                                //        + ", write delay=" + nextWriteDelay);
2113                                if (nextWriteDelay < nextCpuDelay) {
2114                                    nextCpuDelay = nextWriteDelay;
2115                                }
2116                                if (nextCpuDelay > 0) {
2117                                    mProcessCpuMutexFree.set(true);
2118                                    this.wait(nextCpuDelay);
2119                                }
2120                            }
2121                        } catch (InterruptedException e) {
2122                        }
2123                        updateCpuStatsNow();
2124                    } catch (Exception e) {
2125                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2126                    }
2127                }
2128            }
2129        };
2130
2131        Watchdog.getInstance().addMonitor(this);
2132        Watchdog.getInstance().addThread(mHandler);
2133    }
2134
2135    private void start() {
2136        mProcessCpuThread.start();
2137
2138        mBatteryStatsService.publish(mContext);
2139        mUsageStatsService.publish(mContext);
2140        mAppOpsService.publish(mContext);
2141
2142        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2143    }
2144
2145    @Override
2146    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2147            throws RemoteException {
2148        if (code == SYSPROPS_TRANSACTION) {
2149            // We need to tell all apps about the system property change.
2150            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2151            synchronized(this) {
2152                final int NP = mProcessNames.getMap().size();
2153                for (int ip=0; ip<NP; ip++) {
2154                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2155                    final int NA = apps.size();
2156                    for (int ia=0; ia<NA; ia++) {
2157                        ProcessRecord app = apps.valueAt(ia);
2158                        if (app.thread != null) {
2159                            procs.add(app.thread.asBinder());
2160                        }
2161                    }
2162                }
2163            }
2164
2165            int N = procs.size();
2166            for (int i=0; i<N; i++) {
2167                Parcel data2 = Parcel.obtain();
2168                try {
2169                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2170                } catch (RemoteException e) {
2171                }
2172                data2.recycle();
2173            }
2174        }
2175        try {
2176            return super.onTransact(code, data, reply, flags);
2177        } catch (RuntimeException e) {
2178            // The activity manager only throws security exceptions, so let's
2179            // log all others.
2180            if (!(e instanceof SecurityException)) {
2181                Slog.wtf(TAG, "Activity Manager Crash", e);
2182            }
2183            throw e;
2184        }
2185    }
2186
2187    void updateCpuStats() {
2188        final long now = SystemClock.uptimeMillis();
2189        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2190            return;
2191        }
2192        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2193            synchronized (mProcessCpuThread) {
2194                mProcessCpuThread.notify();
2195            }
2196        }
2197    }
2198
2199    void updateCpuStatsNow() {
2200        synchronized (mProcessCpuThread) {
2201            mProcessCpuMutexFree.set(false);
2202            final long now = SystemClock.uptimeMillis();
2203            boolean haveNewCpuStats = false;
2204
2205            if (MONITOR_CPU_USAGE &&
2206                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2207                mLastCpuTime.set(now);
2208                haveNewCpuStats = true;
2209                mProcessCpuTracker.update();
2210                //Slog.i(TAG, mProcessCpu.printCurrentState());
2211                //Slog.i(TAG, "Total CPU usage: "
2212                //        + mProcessCpu.getTotalCpuPercent() + "%");
2213
2214                // Slog the cpu usage if the property is set.
2215                if ("true".equals(SystemProperties.get("events.cpu"))) {
2216                    int user = mProcessCpuTracker.getLastUserTime();
2217                    int system = mProcessCpuTracker.getLastSystemTime();
2218                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2219                    int irq = mProcessCpuTracker.getLastIrqTime();
2220                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2221                    int idle = mProcessCpuTracker.getLastIdleTime();
2222
2223                    int total = user + system + iowait + irq + softIrq + idle;
2224                    if (total == 0) total = 1;
2225
2226                    EventLog.writeEvent(EventLogTags.CPU,
2227                            ((user+system+iowait+irq+softIrq) * 100) / total,
2228                            (user * 100) / total,
2229                            (system * 100) / total,
2230                            (iowait * 100) / total,
2231                            (irq * 100) / total,
2232                            (softIrq * 100) / total);
2233                }
2234            }
2235
2236            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2237            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2238            synchronized(bstats) {
2239                synchronized(mPidsSelfLocked) {
2240                    if (haveNewCpuStats) {
2241                        if (mOnBattery) {
2242                            int perc = bstats.startAddingCpuLocked();
2243                            int totalUTime = 0;
2244                            int totalSTime = 0;
2245                            final int N = mProcessCpuTracker.countStats();
2246                            for (int i=0; i<N; i++) {
2247                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2248                                if (!st.working) {
2249                                    continue;
2250                                }
2251                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2252                                int otherUTime = (st.rel_utime*perc)/100;
2253                                int otherSTime = (st.rel_stime*perc)/100;
2254                                totalUTime += otherUTime;
2255                                totalSTime += otherSTime;
2256                                if (pr != null) {
2257                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2258                                    if (ps == null || !ps.isActive()) {
2259                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2260                                                pr.info.uid, pr.processName);
2261                                    }
2262                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2263                                            st.rel_stime-otherSTime);
2264                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2265                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2266                                } else {
2267                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2268                                    if (ps == null || !ps.isActive()) {
2269                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2270                                                bstats.mapUid(st.uid), st.name);
2271                                    }
2272                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2273                                            st.rel_stime-otherSTime);
2274                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2275                                }
2276                            }
2277                            bstats.finishAddingCpuLocked(perc, totalUTime,
2278                                    totalSTime, cpuSpeedTimes);
2279                        }
2280                    }
2281                }
2282
2283                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2284                    mLastWriteTime = now;
2285                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2286                }
2287            }
2288        }
2289    }
2290
2291    @Override
2292    public void batteryNeedsCpuUpdate() {
2293        updateCpuStatsNow();
2294    }
2295
2296    @Override
2297    public void batteryPowerChanged(boolean onBattery) {
2298        // When plugging in, update the CPU stats first before changing
2299        // the plug state.
2300        updateCpuStatsNow();
2301        synchronized (this) {
2302            synchronized(mPidsSelfLocked) {
2303                mOnBattery = DEBUG_POWER ? true : onBattery;
2304            }
2305        }
2306    }
2307
2308    /**
2309     * Initialize the application bind args. These are passed to each
2310     * process when the bindApplication() IPC is sent to the process. They're
2311     * lazily setup to make sure the services are running when they're asked for.
2312     */
2313    private HashMap<String, IBinder> getCommonServicesLocked() {
2314        if (mAppBindArgs == null) {
2315            mAppBindArgs = new HashMap<String, IBinder>();
2316
2317            // Setup the application init args
2318            mAppBindArgs.put("package", ServiceManager.getService("package"));
2319            mAppBindArgs.put("window", ServiceManager.getService("window"));
2320            mAppBindArgs.put(Context.ALARM_SERVICE,
2321                    ServiceManager.getService(Context.ALARM_SERVICE));
2322        }
2323        return mAppBindArgs;
2324    }
2325
2326    final void setFocusedActivityLocked(ActivityRecord r) {
2327        if (mFocusedActivity != r) {
2328            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2329            mFocusedActivity = r;
2330            mStackSupervisor.setFocusedStack(r);
2331            if (r != null) {
2332                mWindowManager.setFocusedApp(r.appToken, true);
2333            }
2334            applyUpdateLockStateLocked(r);
2335        }
2336    }
2337
2338    @Override
2339    public void setFocusedStack(int stackId) {
2340        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2341        synchronized (ActivityManagerService.this) {
2342            ActivityStack stack = mStackSupervisor.getStack(stackId);
2343            if (stack != null) {
2344                ActivityRecord r = stack.topRunningActivityLocked(null);
2345                if (r != null) {
2346                    setFocusedActivityLocked(r);
2347                }
2348            }
2349        }
2350    }
2351
2352    @Override
2353    public void notifyActivityDrawn(IBinder token) {
2354        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2355        synchronized (this) {
2356            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2357            if (r != null) {
2358                r.task.stack.notifyActivityDrawnLocked(r);
2359            }
2360        }
2361    }
2362
2363    final void applyUpdateLockStateLocked(ActivityRecord r) {
2364        // Modifications to the UpdateLock state are done on our handler, outside
2365        // the activity manager's locks.  The new state is determined based on the
2366        // state *now* of the relevant activity record.  The object is passed to
2367        // the handler solely for logging detail, not to be consulted/modified.
2368        final boolean nextState = r != null && r.immersive;
2369        mHandler.sendMessage(
2370                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2371    }
2372
2373    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2374        Message msg = Message.obtain();
2375        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2376        msg.obj = r.task.askedCompatMode ? null : r;
2377        mHandler.sendMessage(msg);
2378    }
2379
2380    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2381            String what, Object obj, ProcessRecord srcApp) {
2382        app.lastActivityTime = now;
2383
2384        if (app.activities.size() > 0) {
2385            // Don't want to touch dependent processes that are hosting activities.
2386            return index;
2387        }
2388
2389        int lrui = mLruProcesses.lastIndexOf(app);
2390        if (lrui < 0) {
2391            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2392                    + what + " " + obj + " from " + srcApp);
2393            return index;
2394        }
2395
2396        if (lrui >= index) {
2397            // Don't want to cause this to move dependent processes *back* in the
2398            // list as if they were less frequently used.
2399            return index;
2400        }
2401
2402        if (lrui >= mLruProcessActivityStart) {
2403            // Don't want to touch dependent processes that are hosting activities.
2404            return index;
2405        }
2406
2407        mLruProcesses.remove(lrui);
2408        if (index > 0) {
2409            index--;
2410        }
2411        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2412                + " in LRU list: " + app);
2413        mLruProcesses.add(index, app);
2414        return index;
2415    }
2416
2417    final void removeLruProcessLocked(ProcessRecord app) {
2418        int lrui = mLruProcesses.lastIndexOf(app);
2419        if (lrui >= 0) {
2420            if (lrui <= mLruProcessActivityStart) {
2421                mLruProcessActivityStart--;
2422            }
2423            if (lrui <= mLruProcessServiceStart) {
2424                mLruProcessServiceStart--;
2425            }
2426            mLruProcesses.remove(lrui);
2427        }
2428    }
2429
2430    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2431            ProcessRecord client) {
2432        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2433                || app.treatLikeActivity;
2434        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2435        if (!activityChange && hasActivity) {
2436            // The process has activities, so we are only allowing activity-based adjustments
2437            // to move it.  It should be kept in the front of the list with other
2438            // processes that have activities, and we don't want those to change their
2439            // order except due to activity operations.
2440            return;
2441        }
2442
2443        mLruSeq++;
2444        final long now = SystemClock.uptimeMillis();
2445        app.lastActivityTime = now;
2446
2447        // First a quick reject: if the app is already at the position we will
2448        // put it, then there is nothing to do.
2449        if (hasActivity) {
2450            final int N = mLruProcesses.size();
2451            if (N > 0 && mLruProcesses.get(N-1) == app) {
2452                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2453                return;
2454            }
2455        } else {
2456            if (mLruProcessServiceStart > 0
2457                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2458                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2459                return;
2460            }
2461        }
2462
2463        int lrui = mLruProcesses.lastIndexOf(app);
2464
2465        if (app.persistent && lrui >= 0) {
2466            // We don't care about the position of persistent processes, as long as
2467            // they are in the list.
2468            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2469            return;
2470        }
2471
2472        /* In progress: compute new position first, so we can avoid doing work
2473           if the process is not actually going to move.  Not yet working.
2474        int addIndex;
2475        int nextIndex;
2476        boolean inActivity = false, inService = false;
2477        if (hasActivity) {
2478            // Process has activities, put it at the very tipsy-top.
2479            addIndex = mLruProcesses.size();
2480            nextIndex = mLruProcessServiceStart;
2481            inActivity = true;
2482        } else if (hasService) {
2483            // Process has services, put it at the top of the service list.
2484            addIndex = mLruProcessActivityStart;
2485            nextIndex = mLruProcessServiceStart;
2486            inActivity = true;
2487            inService = true;
2488        } else  {
2489            // Process not otherwise of interest, it goes to the top of the non-service area.
2490            addIndex = mLruProcessServiceStart;
2491            if (client != null) {
2492                int clientIndex = mLruProcesses.lastIndexOf(client);
2493                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2494                        + app);
2495                if (clientIndex >= 0 && addIndex > clientIndex) {
2496                    addIndex = clientIndex;
2497                }
2498            }
2499            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2500        }
2501
2502        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2503                + mLruProcessActivityStart + "): " + app);
2504        */
2505
2506        if (lrui >= 0) {
2507            if (lrui < mLruProcessActivityStart) {
2508                mLruProcessActivityStart--;
2509            }
2510            if (lrui < mLruProcessServiceStart) {
2511                mLruProcessServiceStart--;
2512            }
2513            /*
2514            if (addIndex > lrui) {
2515                addIndex--;
2516            }
2517            if (nextIndex > lrui) {
2518                nextIndex--;
2519            }
2520            */
2521            mLruProcesses.remove(lrui);
2522        }
2523
2524        /*
2525        mLruProcesses.add(addIndex, app);
2526        if (inActivity) {
2527            mLruProcessActivityStart++;
2528        }
2529        if (inService) {
2530            mLruProcessActivityStart++;
2531        }
2532        */
2533
2534        int nextIndex;
2535        if (hasActivity) {
2536            final int N = mLruProcesses.size();
2537            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2538                // Process doesn't have activities, but has clients with
2539                // activities...  move it up, but one below the top (the top
2540                // should always have a real activity).
2541                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2542                mLruProcesses.add(N-1, app);
2543                // To keep it from spamming the LRU list (by making a bunch of clients),
2544                // we will push down any other entries owned by the app.
2545                final int uid = app.info.uid;
2546                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2547                    ProcessRecord subProc = mLruProcesses.get(i);
2548                    if (subProc.info.uid == uid) {
2549                        // We want to push this one down the list.  If the process after
2550                        // it is for the same uid, however, don't do so, because we don't
2551                        // want them internally to be re-ordered.
2552                        if (mLruProcesses.get(i-1).info.uid != uid) {
2553                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2554                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2555                            ProcessRecord tmp = mLruProcesses.get(i);
2556                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2557                            mLruProcesses.set(i-1, tmp);
2558                            i--;
2559                        }
2560                    } else {
2561                        // A gap, we can stop here.
2562                        break;
2563                    }
2564                }
2565            } else {
2566                // Process has activities, put it at the very tipsy-top.
2567                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2568                mLruProcesses.add(app);
2569            }
2570            nextIndex = mLruProcessServiceStart;
2571        } else if (hasService) {
2572            // Process has services, put it at the top of the service list.
2573            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2574            mLruProcesses.add(mLruProcessActivityStart, app);
2575            nextIndex = mLruProcessServiceStart;
2576            mLruProcessActivityStart++;
2577        } else  {
2578            // Process not otherwise of interest, it goes to the top of the non-service area.
2579            int index = mLruProcessServiceStart;
2580            if (client != null) {
2581                // If there is a client, don't allow the process to be moved up higher
2582                // in the list than that client.
2583                int clientIndex = mLruProcesses.lastIndexOf(client);
2584                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2585                        + " when updating " + app);
2586                if (clientIndex <= lrui) {
2587                    // Don't allow the client index restriction to push it down farther in the
2588                    // list than it already is.
2589                    clientIndex = lrui;
2590                }
2591                if (clientIndex >= 0 && index > clientIndex) {
2592                    index = clientIndex;
2593                }
2594            }
2595            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2596            mLruProcesses.add(index, app);
2597            nextIndex = index-1;
2598            mLruProcessActivityStart++;
2599            mLruProcessServiceStart++;
2600        }
2601
2602        // If the app is currently using a content provider or service,
2603        // bump those processes as well.
2604        for (int j=app.connections.size()-1; j>=0; j--) {
2605            ConnectionRecord cr = app.connections.valueAt(j);
2606            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2607                    && cr.binding.service.app != null
2608                    && cr.binding.service.app.lruSeq != mLruSeq
2609                    && !cr.binding.service.app.persistent) {
2610                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2611                        "service connection", cr, app);
2612            }
2613        }
2614        for (int j=app.conProviders.size()-1; j>=0; j--) {
2615            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2616            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2617                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2618                        "provider reference", cpr, app);
2619            }
2620        }
2621    }
2622
2623    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2624        if (uid == Process.SYSTEM_UID) {
2625            // The system gets to run in any process.  If there are multiple
2626            // processes with the same uid, just pick the first (this
2627            // should never happen).
2628            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2629            if (procs == null) return null;
2630            final int N = procs.size();
2631            for (int i = 0; i < N; i++) {
2632                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2633            }
2634        }
2635        ProcessRecord proc = mProcessNames.get(processName, uid);
2636        if (false && proc != null && !keepIfLarge
2637                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2638                && proc.lastCachedPss >= 4000) {
2639            // Turn this condition on to cause killing to happen regularly, for testing.
2640            if (proc.baseProcessTracker != null) {
2641                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2642            }
2643            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2644                    + "k from cached");
2645        } else if (proc != null && !keepIfLarge
2646                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2647                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2648            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2649            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2650                if (proc.baseProcessTracker != null) {
2651                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2652                }
2653                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2654                        + "k from cached");
2655            }
2656        }
2657        return proc;
2658    }
2659
2660    void ensurePackageDexOpt(String packageName) {
2661        IPackageManager pm = AppGlobals.getPackageManager();
2662        try {
2663            if (pm.performDexOpt(packageName)) {
2664                mDidDexOpt = true;
2665            }
2666        } catch (RemoteException e) {
2667        }
2668    }
2669
2670    boolean isNextTransitionForward() {
2671        int transit = mWindowManager.getPendingAppTransition();
2672        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2673                || transit == AppTransition.TRANSIT_TASK_OPEN
2674                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2675    }
2676
2677    final ProcessRecord startProcessLocked(String processName,
2678            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2679            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2680            boolean isolated, boolean keepIfLarge) {
2681        ProcessRecord app;
2682        if (!isolated) {
2683            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2684        } else {
2685            // If this is an isolated process, it can't re-use an existing process.
2686            app = null;
2687        }
2688        // We don't have to do anything more if:
2689        // (1) There is an existing application record; and
2690        // (2) The caller doesn't think it is dead, OR there is no thread
2691        //     object attached to it so we know it couldn't have crashed; and
2692        // (3) There is a pid assigned to it, so it is either starting or
2693        //     already running.
2694        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2695                + " app=" + app + " knownToBeDead=" + knownToBeDead
2696                + " thread=" + (app != null ? app.thread : null)
2697                + " pid=" + (app != null ? app.pid : -1));
2698        if (app != null && app.pid > 0) {
2699            if (!knownToBeDead || app.thread == null) {
2700                // We already have the app running, or are waiting for it to
2701                // come up (we have a pid but not yet its thread), so keep it.
2702                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2703                // If this is a new package in the process, add the package to the list
2704                app.addPackage(info.packageName, mProcessStats);
2705                return app;
2706            }
2707
2708            // An application record is attached to a previous process,
2709            // clean it up now.
2710            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2711            handleAppDiedLocked(app, true, true);
2712        }
2713
2714        String hostingNameStr = hostingName != null
2715                ? hostingName.flattenToShortString() : null;
2716
2717        if (!isolated) {
2718            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2719                // If we are in the background, then check to see if this process
2720                // is bad.  If so, we will just silently fail.
2721                if (mBadProcesses.get(info.processName, info.uid) != null) {
2722                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2723                            + "/" + info.processName);
2724                    return null;
2725                }
2726            } else {
2727                // When the user is explicitly starting a process, then clear its
2728                // crash count so that we won't make it bad until they see at
2729                // least one crash dialog again, and make the process good again
2730                // if it had been bad.
2731                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2732                        + "/" + info.processName);
2733                mProcessCrashTimes.remove(info.processName, info.uid);
2734                if (mBadProcesses.get(info.processName, info.uid) != null) {
2735                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2736                            UserHandle.getUserId(info.uid), info.uid,
2737                            info.processName);
2738                    mBadProcesses.remove(info.processName, info.uid);
2739                    if (app != null) {
2740                        app.bad = false;
2741                    }
2742                }
2743            }
2744        }
2745
2746        if (app == null) {
2747            app = newProcessRecordLocked(info, processName, isolated);
2748            if (app == null) {
2749                Slog.w(TAG, "Failed making new process record for "
2750                        + processName + "/" + info.uid + " isolated=" + isolated);
2751                return null;
2752            }
2753            mProcessNames.put(processName, app.uid, app);
2754            if (isolated) {
2755                mIsolatedProcesses.put(app.uid, app);
2756            }
2757        } else {
2758            // If this is a new package in the process, add the package to the list
2759            app.addPackage(info.packageName, mProcessStats);
2760        }
2761
2762        // If the system is not ready yet, then hold off on starting this
2763        // process until it is.
2764        if (!mProcessesReady
2765                && !isAllowedWhileBooting(info)
2766                && !allowWhileBooting) {
2767            if (!mProcessesOnHold.contains(app)) {
2768                mProcessesOnHold.add(app);
2769            }
2770            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2771            return app;
2772        }
2773
2774        startProcessLocked(app, hostingType, hostingNameStr);
2775        return (app.pid != 0) ? app : null;
2776    }
2777
2778    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2779        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2780    }
2781
2782    private final void startProcessLocked(ProcessRecord app,
2783            String hostingType, String hostingNameStr) {
2784        if (app.pid > 0 && app.pid != MY_PID) {
2785            synchronized (mPidsSelfLocked) {
2786                mPidsSelfLocked.remove(app.pid);
2787                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2788            }
2789            app.setPid(0);
2790        }
2791
2792        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2793                "startProcessLocked removing on hold: " + app);
2794        mProcessesOnHold.remove(app);
2795
2796        updateCpuStats();
2797
2798        try {
2799            int uid = app.uid;
2800
2801            int[] gids = null;
2802            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2803            if (!app.isolated) {
2804                int[] permGids = null;
2805                try {
2806                    final PackageManager pm = mContext.getPackageManager();
2807                    permGids = pm.getPackageGids(app.info.packageName);
2808
2809                    if (Environment.isExternalStorageEmulated()) {
2810                        if (pm.checkPermission(
2811                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2812                                app.info.packageName) == PERMISSION_GRANTED) {
2813                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2814                        } else {
2815                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2816                        }
2817                    }
2818                } catch (PackageManager.NameNotFoundException e) {
2819                    Slog.w(TAG, "Unable to retrieve gids", e);
2820                }
2821
2822                /*
2823                 * Add shared application GID so applications can share some
2824                 * resources like shared libraries
2825                 */
2826                if (permGids == null) {
2827                    gids = new int[1];
2828                } else {
2829                    gids = new int[permGids.length + 1];
2830                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2831                }
2832                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2833            }
2834            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2835                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2836                        && mTopComponent != null
2837                        && app.processName.equals(mTopComponent.getPackageName())) {
2838                    uid = 0;
2839                }
2840                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2841                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2842                    uid = 0;
2843                }
2844            }
2845            int debugFlags = 0;
2846            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2847                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2848                // Also turn on CheckJNI for debuggable apps. It's quite
2849                // awkward to turn on otherwise.
2850                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2851            }
2852            // Run the app in safe mode if its manifest requests so or the
2853            // system is booted in safe mode.
2854            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2855                mSafeMode == true) {
2856                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2857            }
2858            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2859                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2860            }
2861            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2862                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2863            }
2864            if ("1".equals(SystemProperties.get("debug.assert"))) {
2865                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2866            }
2867
2868            String requiredAbi = app.info.requiredCpuAbi;
2869            if (requiredAbi == null) {
2870                requiredAbi = Build.SUPPORTED_ABIS[0];
2871            }
2872
2873            // Start the process.  It will either succeed and return a result containing
2874            // the PID of the new process, or else throw a RuntimeException.
2875            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2876                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2877                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2878
2879            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2880            synchronized (bs) {
2881                if (bs.isOnBattery()) {
2882                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2883                }
2884            }
2885
2886            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2887                    UserHandle.getUserId(uid), startResult.pid, uid,
2888                    app.processName, hostingType,
2889                    hostingNameStr != null ? hostingNameStr : "");
2890
2891            if (app.persistent) {
2892                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2893            }
2894
2895            StringBuilder buf = mStringBuilder;
2896            buf.setLength(0);
2897            buf.append("Start proc ");
2898            buf.append(app.processName);
2899            buf.append(" for ");
2900            buf.append(hostingType);
2901            if (hostingNameStr != null) {
2902                buf.append(" ");
2903                buf.append(hostingNameStr);
2904            }
2905            buf.append(": pid=");
2906            buf.append(startResult.pid);
2907            buf.append(" uid=");
2908            buf.append(uid);
2909            buf.append(" gids={");
2910            if (gids != null) {
2911                for (int gi=0; gi<gids.length; gi++) {
2912                    if (gi != 0) buf.append(", ");
2913                    buf.append(gids[gi]);
2914
2915                }
2916            }
2917            buf.append("}");
2918            Slog.i(TAG, buf.toString());
2919            app.setPid(startResult.pid);
2920            app.usingWrapper = startResult.usingWrapper;
2921            app.removed = false;
2922            synchronized (mPidsSelfLocked) {
2923                this.mPidsSelfLocked.put(startResult.pid, app);
2924                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2925                msg.obj = app;
2926                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2927                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2928            }
2929            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2930                    app.processName, app.info.uid);
2931            if (app.isolated) {
2932                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2933            }
2934        } catch (RuntimeException e) {
2935            // XXX do better error recovery.
2936            app.setPid(0);
2937            Slog.e(TAG, "Failure starting process " + app.processName, e);
2938        }
2939    }
2940
2941    void updateUsageStats(ActivityRecord component, boolean resumed) {
2942        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2943        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2944        if (resumed) {
2945            mUsageStatsService.noteResumeComponent(component.realActivity);
2946            synchronized (stats) {
2947                stats.noteActivityResumedLocked(component.app.uid);
2948            }
2949        } else {
2950            mUsageStatsService.notePauseComponent(component.realActivity);
2951            synchronized (stats) {
2952                stats.noteActivityPausedLocked(component.app.uid);
2953            }
2954        }
2955    }
2956
2957    Intent getHomeIntent() {
2958        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2959        intent.setComponent(mTopComponent);
2960        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2961            intent.addCategory(Intent.CATEGORY_HOME);
2962        }
2963        return intent;
2964    }
2965
2966    boolean startHomeActivityLocked(int userId) {
2967        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2968                && mTopAction == null) {
2969            // We are running in factory test mode, but unable to find
2970            // the factory test app, so just sit around displaying the
2971            // error message and don't try to start anything.
2972            return false;
2973        }
2974        Intent intent = getHomeIntent();
2975        ActivityInfo aInfo =
2976            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2977        if (aInfo != null) {
2978            intent.setComponent(new ComponentName(
2979                    aInfo.applicationInfo.packageName, aInfo.name));
2980            // Don't do this if the home app is currently being
2981            // instrumented.
2982            aInfo = new ActivityInfo(aInfo);
2983            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2984            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2985                    aInfo.applicationInfo.uid, true);
2986            if (app == null || app.instrumentationClass == null) {
2987                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2988                mStackSupervisor.startHomeActivity(intent, aInfo);
2989            }
2990        }
2991
2992        return true;
2993    }
2994
2995    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2996        ActivityInfo ai = null;
2997        ComponentName comp = intent.getComponent();
2998        try {
2999            if (comp != null) {
3000                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3001            } else {
3002                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3003                        intent,
3004                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3005                            flags, userId);
3006
3007                if (info != null) {
3008                    ai = info.activityInfo;
3009                }
3010            }
3011        } catch (RemoteException e) {
3012            // ignore
3013        }
3014
3015        return ai;
3016    }
3017
3018    /**
3019     * Starts the "new version setup screen" if appropriate.
3020     */
3021    void startSetupActivityLocked() {
3022        // Only do this once per boot.
3023        if (mCheckedForSetup) {
3024            return;
3025        }
3026
3027        // We will show this screen if the current one is a different
3028        // version than the last one shown, and we are not running in
3029        // low-level factory test mode.
3030        final ContentResolver resolver = mContext.getContentResolver();
3031        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3032                Settings.Global.getInt(resolver,
3033                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3034            mCheckedForSetup = true;
3035
3036            // See if we should be showing the platform update setup UI.
3037            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3038            List<ResolveInfo> ris = mContext.getPackageManager()
3039                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3040
3041            // We don't allow third party apps to replace this.
3042            ResolveInfo ri = null;
3043            for (int i=0; ris != null && i<ris.size(); i++) {
3044                if ((ris.get(i).activityInfo.applicationInfo.flags
3045                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3046                    ri = ris.get(i);
3047                    break;
3048                }
3049            }
3050
3051            if (ri != null) {
3052                String vers = ri.activityInfo.metaData != null
3053                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3054                        : null;
3055                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3056                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3057                            Intent.METADATA_SETUP_VERSION);
3058                }
3059                String lastVers = Settings.Secure.getString(
3060                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3061                if (vers != null && !vers.equals(lastVers)) {
3062                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3063                    intent.setComponent(new ComponentName(
3064                            ri.activityInfo.packageName, ri.activityInfo.name));
3065                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3066                            null, null, 0, 0, 0, null, 0, null, false, null, null);
3067                }
3068            }
3069        }
3070    }
3071
3072    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3073        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3074    }
3075
3076    void enforceNotIsolatedCaller(String caller) {
3077        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3078            throw new SecurityException("Isolated process not allowed to call " + caller);
3079        }
3080    }
3081
3082    @Override
3083    public int getFrontActivityScreenCompatMode() {
3084        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3085        synchronized (this) {
3086            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3087        }
3088    }
3089
3090    @Override
3091    public void setFrontActivityScreenCompatMode(int mode) {
3092        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3093                "setFrontActivityScreenCompatMode");
3094        synchronized (this) {
3095            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3096        }
3097    }
3098
3099    @Override
3100    public int getPackageScreenCompatMode(String packageName) {
3101        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3102        synchronized (this) {
3103            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3104        }
3105    }
3106
3107    @Override
3108    public void setPackageScreenCompatMode(String packageName, int mode) {
3109        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3110                "setPackageScreenCompatMode");
3111        synchronized (this) {
3112            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3113        }
3114    }
3115
3116    @Override
3117    public boolean getPackageAskScreenCompat(String packageName) {
3118        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3119        synchronized (this) {
3120            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3121        }
3122    }
3123
3124    @Override
3125    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3126        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3127                "setPackageAskScreenCompat");
3128        synchronized (this) {
3129            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3130        }
3131    }
3132
3133    private void dispatchProcessesChanged() {
3134        int N;
3135        synchronized (this) {
3136            N = mPendingProcessChanges.size();
3137            if (mActiveProcessChanges.length < N) {
3138                mActiveProcessChanges = new ProcessChangeItem[N];
3139            }
3140            mPendingProcessChanges.toArray(mActiveProcessChanges);
3141            mAvailProcessChanges.addAll(mPendingProcessChanges);
3142            mPendingProcessChanges.clear();
3143            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3144        }
3145
3146        int i = mProcessObservers.beginBroadcast();
3147        while (i > 0) {
3148            i--;
3149            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3150            if (observer != null) {
3151                try {
3152                    for (int j=0; j<N; j++) {
3153                        ProcessChangeItem item = mActiveProcessChanges[j];
3154                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3155                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3156                                    + item.pid + " uid=" + item.uid + ": "
3157                                    + item.foregroundActivities);
3158                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3159                                    item.foregroundActivities);
3160                        }
3161                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3162                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3163                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3164                            observer.onImportanceChanged(item.pid, item.uid,
3165                                    item.importance);
3166                        }
3167                    }
3168                } catch (RemoteException e) {
3169                }
3170            }
3171        }
3172        mProcessObservers.finishBroadcast();
3173    }
3174
3175    private void dispatchProcessDied(int pid, int uid) {
3176        int i = mProcessObservers.beginBroadcast();
3177        while (i > 0) {
3178            i--;
3179            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3180            if (observer != null) {
3181                try {
3182                    observer.onProcessDied(pid, uid);
3183                } catch (RemoteException e) {
3184                }
3185            }
3186        }
3187        mProcessObservers.finishBroadcast();
3188    }
3189
3190    final void doPendingActivityLaunchesLocked(boolean doResume) {
3191        final int N = mPendingActivityLaunches.size();
3192        if (N <= 0) {
3193            return;
3194        }
3195        for (int i=0; i<N; i++) {
3196            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3197            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3198                    doResume && i == (N-1), null);
3199        }
3200        mPendingActivityLaunches.clear();
3201    }
3202
3203    @Override
3204    public final int startActivity(IApplicationThread caller, String callingPackage,
3205            Intent intent, String resolvedType, IBinder resultTo,
3206            String resultWho, int requestCode, int startFlags,
3207            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3208        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3209                resultWho, requestCode,
3210                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3211    }
3212
3213    @Override
3214    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3215            Intent intent, String resolvedType, IBinder resultTo,
3216            String resultWho, int requestCode, int startFlags,
3217            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3218        enforceNotIsolatedCaller("startActivity");
3219        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3220                false, true, "startActivity", null);
3221        // TODO: Switch to user app stacks here.
3222        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3223                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3224                null, null, options, userId, null);
3225    }
3226
3227    @Override
3228    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3229            Intent intent, String resolvedType, IBinder resultTo,
3230            String resultWho, int requestCode, int startFlags, String profileFile,
3231            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3232        enforceNotIsolatedCaller("startActivityAndWait");
3233        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3234                false, true, "startActivityAndWait", null);
3235        WaitResult res = new WaitResult();
3236        // TODO: Switch to user app stacks here.
3237        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3238                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3239                res, null, options, UserHandle.getCallingUserId(), null);
3240        return res;
3241    }
3242
3243    @Override
3244    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3245            Intent intent, String resolvedType, IBinder resultTo,
3246            String resultWho, int requestCode, int startFlags, Configuration config,
3247            Bundle options, int userId) {
3248        enforceNotIsolatedCaller("startActivityWithConfig");
3249        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3250                false, true, "startActivityWithConfig", null);
3251        // TODO: Switch to user app stacks here.
3252        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3253                resolvedType, resultTo, resultWho, requestCode, startFlags,
3254                null, null, null, config, options, userId, null);
3255        return ret;
3256    }
3257
3258    @Override
3259    public int startActivityIntentSender(IApplicationThread caller,
3260            IntentSender intent, Intent fillInIntent, String resolvedType,
3261            IBinder resultTo, String resultWho, int requestCode,
3262            int flagsMask, int flagsValues, Bundle options) {
3263        enforceNotIsolatedCaller("startActivityIntentSender");
3264        // Refuse possible leaked file descriptors
3265        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3266            throw new IllegalArgumentException("File descriptors passed in Intent");
3267        }
3268
3269        IIntentSender sender = intent.getTarget();
3270        if (!(sender instanceof PendingIntentRecord)) {
3271            throw new IllegalArgumentException("Bad PendingIntent object");
3272        }
3273
3274        PendingIntentRecord pir = (PendingIntentRecord)sender;
3275
3276        synchronized (this) {
3277            // If this is coming from the currently resumed activity, it is
3278            // effectively saying that app switches are allowed at this point.
3279            final ActivityStack stack = getFocusedStack();
3280            if (stack.mResumedActivity != null &&
3281                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3282                mAppSwitchesAllowedTime = 0;
3283            }
3284        }
3285        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3286                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3287        return ret;
3288    }
3289
3290    @Override
3291    public boolean startNextMatchingActivity(IBinder callingActivity,
3292            Intent intent, Bundle options) {
3293        // Refuse possible leaked file descriptors
3294        if (intent != null && intent.hasFileDescriptors() == true) {
3295            throw new IllegalArgumentException("File descriptors passed in Intent");
3296        }
3297
3298        synchronized (this) {
3299            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3300            if (r == null) {
3301                ActivityOptions.abort(options);
3302                return false;
3303            }
3304            if (r.app == null || r.app.thread == null) {
3305                // The caller is not running...  d'oh!
3306                ActivityOptions.abort(options);
3307                return false;
3308            }
3309            intent = new Intent(intent);
3310            // The caller is not allowed to change the data.
3311            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3312            // And we are resetting to find the next component...
3313            intent.setComponent(null);
3314
3315            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3316
3317            ActivityInfo aInfo = null;
3318            try {
3319                List<ResolveInfo> resolves =
3320                    AppGlobals.getPackageManager().queryIntentActivities(
3321                            intent, r.resolvedType,
3322                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3323                            UserHandle.getCallingUserId());
3324
3325                // Look for the original activity in the list...
3326                final int N = resolves != null ? resolves.size() : 0;
3327                for (int i=0; i<N; i++) {
3328                    ResolveInfo rInfo = resolves.get(i);
3329                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3330                            && rInfo.activityInfo.name.equals(r.info.name)) {
3331                        // We found the current one...  the next matching is
3332                        // after it.
3333                        i++;
3334                        if (i<N) {
3335                            aInfo = resolves.get(i).activityInfo;
3336                        }
3337                        if (debug) {
3338                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3339                                    + "/" + r.info.name);
3340                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3341                                    + "/" + aInfo.name);
3342                        }
3343                        break;
3344                    }
3345                }
3346            } catch (RemoteException e) {
3347            }
3348
3349            if (aInfo == null) {
3350                // Nobody who is next!
3351                ActivityOptions.abort(options);
3352                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3353                return false;
3354            }
3355
3356            intent.setComponent(new ComponentName(
3357                    aInfo.applicationInfo.packageName, aInfo.name));
3358            intent.setFlags(intent.getFlags()&~(
3359                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3360                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3361                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3362                    Intent.FLAG_ACTIVITY_NEW_TASK));
3363
3364            // Okay now we need to start the new activity, replacing the
3365            // currently running activity.  This is a little tricky because
3366            // we want to start the new one as if the current one is finished,
3367            // but not finish the current one first so that there is no flicker.
3368            // And thus...
3369            final boolean wasFinishing = r.finishing;
3370            r.finishing = true;
3371
3372            // Propagate reply information over to the new activity.
3373            final ActivityRecord resultTo = r.resultTo;
3374            final String resultWho = r.resultWho;
3375            final int requestCode = r.requestCode;
3376            r.resultTo = null;
3377            if (resultTo != null) {
3378                resultTo.removeResultsLocked(r, resultWho, requestCode);
3379            }
3380
3381            final long origId = Binder.clearCallingIdentity();
3382            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3383                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3384                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3385                    options, false, null, null);
3386            Binder.restoreCallingIdentity(origId);
3387
3388            r.finishing = wasFinishing;
3389            if (res != ActivityManager.START_SUCCESS) {
3390                return false;
3391            }
3392            return true;
3393        }
3394    }
3395
3396    final int startActivityInPackage(int uid, String callingPackage,
3397            Intent intent, String resolvedType, IBinder resultTo,
3398            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3399                    IActivityContainer container) {
3400
3401        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3402                false, true, "startActivityInPackage", null);
3403
3404        // TODO: Switch to user app stacks here.
3405        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3406                resultTo, resultWho, requestCode, startFlags,
3407                null, null, null, null, options, userId, container);
3408        return ret;
3409    }
3410
3411    @Override
3412    public final int startActivities(IApplicationThread caller, String callingPackage,
3413            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3414            int userId) {
3415        enforceNotIsolatedCaller("startActivities");
3416        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3417                false, true, "startActivity", null);
3418        // TODO: Switch to user app stacks here.
3419        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3420                resolvedTypes, resultTo, options, userId);
3421        return ret;
3422    }
3423
3424    final int startActivitiesInPackage(int uid, String callingPackage,
3425            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3426            Bundle options, int userId) {
3427
3428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3429                false, true, "startActivityInPackage", null);
3430        // TODO: Switch to user app stacks here.
3431        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3432                resultTo, options, userId);
3433        return ret;
3434    }
3435
3436    final void addRecentTaskLocked(TaskRecord task) {
3437        int N = mRecentTasks.size();
3438        // Quick case: check if the top-most recent task is the same.
3439        if (N > 0 && mRecentTasks.get(0) == task) {
3440            return;
3441        }
3442        // Remove any existing entries that are the same kind of task.
3443        final Intent intent = task.intent;
3444        final boolean document = intent != null && intent.isDocument();
3445        for (int i=0; i<N; i++) {
3446            TaskRecord tr = mRecentTasks.get(i);
3447            if (task != tr) {
3448                if (task.userId != tr.userId) {
3449                    continue;
3450                }
3451                final Intent trIntent = tr.intent;
3452                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3453                    (intent == null || !intent.filterEquals(trIntent))) {
3454                    continue;
3455                }
3456                if (document || trIntent != null && trIntent.isDocument()) {
3457                    // Document tasks do not match other tasks.
3458                    continue;
3459                }
3460            }
3461
3462            // Either task and tr are the same or, their affinities match or their intents match
3463            // and neither of them is a document.
3464            tr.disposeThumbnail();
3465            mRecentTasks.remove(i);
3466            i--;
3467            N--;
3468            if (task.intent == null) {
3469                // If the new recent task we are adding is not fully
3470                // specified, then replace it with the existing recent task.
3471                task = tr;
3472            }
3473        }
3474        if (N >= MAX_RECENT_TASKS) {
3475            mRecentTasks.remove(N-1).disposeThumbnail();
3476        }
3477        mRecentTasks.add(0, task);
3478    }
3479
3480    @Override
3481    public void reportActivityFullyDrawn(IBinder token) {
3482        synchronized (this) {
3483            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3484            if (r == null) {
3485                return;
3486            }
3487            r.reportFullyDrawnLocked();
3488        }
3489    }
3490
3491    @Override
3492    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3493        synchronized (this) {
3494            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3495            if (r == null) {
3496                return;
3497            }
3498            final long origId = Binder.clearCallingIdentity();
3499            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3500            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3501                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3502            if (config != null) {
3503                r.frozenBeforeDestroy = true;
3504                if (!updateConfigurationLocked(config, r, false, false)) {
3505                    mStackSupervisor.resumeTopActivitiesLocked();
3506                }
3507            }
3508            Binder.restoreCallingIdentity(origId);
3509        }
3510    }
3511
3512    @Override
3513    public int getRequestedOrientation(IBinder token) {
3514        synchronized (this) {
3515            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3516            if (r == null) {
3517                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3518            }
3519            return mWindowManager.getAppOrientation(r.appToken);
3520        }
3521    }
3522
3523    /**
3524     * This is the internal entry point for handling Activity.finish().
3525     *
3526     * @param token The Binder token referencing the Activity we want to finish.
3527     * @param resultCode Result code, if any, from this Activity.
3528     * @param resultData Result data (Intent), if any, from this Activity.
3529     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3530     *            the root Activity in the task.
3531     *
3532     * @return Returns true if the activity successfully finished, or false if it is still running.
3533     */
3534    @Override
3535    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3536            boolean finishTask) {
3537        // Refuse possible leaked file descriptors
3538        if (resultData != null && resultData.hasFileDescriptors() == true) {
3539            throw new IllegalArgumentException("File descriptors passed in Intent");
3540        }
3541
3542        synchronized(this) {
3543            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3544            if (r == null) {
3545                return true;
3546            }
3547            // Keep track of the root activity of the task before we finish it
3548            TaskRecord tr = r.task;
3549            ActivityRecord rootR = tr.getRootActivity();
3550            if (mController != null) {
3551                // Find the first activity that is not finishing.
3552                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3553                if (next != null) {
3554                    // ask watcher if this is allowed
3555                    boolean resumeOK = true;
3556                    try {
3557                        resumeOK = mController.activityResuming(next.packageName);
3558                    } catch (RemoteException e) {
3559                        mController = null;
3560                        Watchdog.getInstance().setActivityController(null);
3561                    }
3562
3563                    if (!resumeOK) {
3564                        return false;
3565                    }
3566                }
3567            }
3568            final long origId = Binder.clearCallingIdentity();
3569            try {
3570                boolean res;
3571                if (finishTask && r == rootR) {
3572                    // If requested, remove the task that is associated to this activity only if it
3573                    // was the root activity in the task.  The result code and data is ignored because
3574                    // we don't support returning them across task boundaries.
3575                    res = removeTaskByIdLocked(tr.taskId, 0);
3576                } else {
3577                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3578                            resultData, "app-request", true);
3579                }
3580                return res;
3581            } finally {
3582                Binder.restoreCallingIdentity(origId);
3583            }
3584        }
3585    }
3586
3587    @Override
3588    public final void finishHeavyWeightApp() {
3589        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3590                != PackageManager.PERMISSION_GRANTED) {
3591            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3592                    + Binder.getCallingPid()
3593                    + ", uid=" + Binder.getCallingUid()
3594                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3595            Slog.w(TAG, msg);
3596            throw new SecurityException(msg);
3597        }
3598
3599        synchronized(this) {
3600            if (mHeavyWeightProcess == null) {
3601                return;
3602            }
3603
3604            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3605                    mHeavyWeightProcess.activities);
3606            for (int i=0; i<activities.size(); i++) {
3607                ActivityRecord r = activities.get(i);
3608                if (!r.finishing) {
3609                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3610                            null, "finish-heavy", true);
3611                }
3612            }
3613
3614            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3615                    mHeavyWeightProcess.userId, 0));
3616            mHeavyWeightProcess = null;
3617        }
3618    }
3619
3620    @Override
3621    public void crashApplication(int uid, int initialPid, String packageName,
3622            String message) {
3623        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3624                != PackageManager.PERMISSION_GRANTED) {
3625            String msg = "Permission Denial: crashApplication() from pid="
3626                    + Binder.getCallingPid()
3627                    + ", uid=" + Binder.getCallingUid()
3628                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3629            Slog.w(TAG, msg);
3630            throw new SecurityException(msg);
3631        }
3632
3633        synchronized(this) {
3634            ProcessRecord proc = null;
3635
3636            // Figure out which process to kill.  We don't trust that initialPid
3637            // still has any relation to current pids, so must scan through the
3638            // list.
3639            synchronized (mPidsSelfLocked) {
3640                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3641                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3642                    if (p.uid != uid) {
3643                        continue;
3644                    }
3645                    if (p.pid == initialPid) {
3646                        proc = p;
3647                        break;
3648                    }
3649                    if (p.pkgList.containsKey(packageName)) {
3650                        proc = p;
3651                    }
3652                }
3653            }
3654
3655            if (proc == null) {
3656                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3657                        + " initialPid=" + initialPid
3658                        + " packageName=" + packageName);
3659                return;
3660            }
3661
3662            if (proc.thread != null) {
3663                if (proc.pid == Process.myPid()) {
3664                    Log.w(TAG, "crashApplication: trying to crash self!");
3665                    return;
3666                }
3667                long ident = Binder.clearCallingIdentity();
3668                try {
3669                    proc.thread.scheduleCrash(message);
3670                } catch (RemoteException e) {
3671                }
3672                Binder.restoreCallingIdentity(ident);
3673            }
3674        }
3675    }
3676
3677    @Override
3678    public final void finishSubActivity(IBinder token, String resultWho,
3679            int requestCode) {
3680        synchronized(this) {
3681            final long origId = Binder.clearCallingIdentity();
3682            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3683            if (r != null) {
3684                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3685            }
3686            Binder.restoreCallingIdentity(origId);
3687        }
3688    }
3689
3690    @Override
3691    public boolean finishActivityAffinity(IBinder token) {
3692        synchronized(this) {
3693            final long origId = Binder.clearCallingIdentity();
3694            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3695            boolean res = false;
3696            if (r != null) {
3697                res = r.task.stack.finishActivityAffinityLocked(r);
3698            }
3699            Binder.restoreCallingIdentity(origId);
3700            return res;
3701        }
3702    }
3703
3704    @Override
3705    public boolean willActivityBeVisible(IBinder token) {
3706        synchronized(this) {
3707            ActivityStack stack = ActivityRecord.getStackLocked(token);
3708            if (stack != null) {
3709                return stack.willActivityBeVisibleLocked(token);
3710            }
3711            return false;
3712        }
3713    }
3714
3715    @Override
3716    public void overridePendingTransition(IBinder token, String packageName,
3717            int enterAnim, int exitAnim) {
3718        synchronized(this) {
3719            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3720            if (self == null) {
3721                return;
3722            }
3723
3724            final long origId = Binder.clearCallingIdentity();
3725
3726            if (self.state == ActivityState.RESUMED
3727                    || self.state == ActivityState.PAUSING) {
3728                mWindowManager.overridePendingAppTransition(packageName,
3729                        enterAnim, exitAnim, null);
3730            }
3731
3732            Binder.restoreCallingIdentity(origId);
3733        }
3734    }
3735
3736    /**
3737     * Main function for removing an existing process from the activity manager
3738     * as a result of that process going away.  Clears out all connections
3739     * to the process.
3740     */
3741    private final void handleAppDiedLocked(ProcessRecord app,
3742            boolean restarting, boolean allowRestart) {
3743        int pid = app.pid;
3744        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3745        if (!restarting) {
3746            removeLruProcessLocked(app);
3747            if (pid > 0) {
3748                ProcessList.remove(pid);
3749            }
3750        }
3751
3752        if (mProfileProc == app) {
3753            clearProfilerLocked();
3754        }
3755
3756        // Remove this application's activities from active lists.
3757        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3758
3759        app.activities.clear();
3760
3761        if (app.instrumentationClass != null) {
3762            Slog.w(TAG, "Crash of app " + app.processName
3763                  + " running instrumentation " + app.instrumentationClass);
3764            Bundle info = new Bundle();
3765            info.putString("shortMsg", "Process crashed.");
3766            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3767        }
3768
3769        if (!restarting) {
3770            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3771                // If there was nothing to resume, and we are not already
3772                // restarting this process, but there is a visible activity that
3773                // is hosted by the process...  then make sure all visible
3774                // activities are running, taking care of restarting this
3775                // process.
3776                if (hasVisibleActivities) {
3777                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3778                }
3779            }
3780        }
3781    }
3782
3783    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3784        IBinder threadBinder = thread.asBinder();
3785        // Find the application record.
3786        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3787            ProcessRecord rec = mLruProcesses.get(i);
3788            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3789                return i;
3790            }
3791        }
3792        return -1;
3793    }
3794
3795    final ProcessRecord getRecordForAppLocked(
3796            IApplicationThread thread) {
3797        if (thread == null) {
3798            return null;
3799        }
3800
3801        int appIndex = getLRURecordIndexForAppLocked(thread);
3802        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3803    }
3804
3805    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3806        // If there are no longer any background processes running,
3807        // and the app that died was not running instrumentation,
3808        // then tell everyone we are now low on memory.
3809        boolean haveBg = false;
3810        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3811            ProcessRecord rec = mLruProcesses.get(i);
3812            if (rec.thread != null
3813                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3814                haveBg = true;
3815                break;
3816            }
3817        }
3818
3819        if (!haveBg) {
3820            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3821            if (doReport) {
3822                long now = SystemClock.uptimeMillis();
3823                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3824                    doReport = false;
3825                } else {
3826                    mLastMemUsageReportTime = now;
3827                }
3828            }
3829            final ArrayList<ProcessMemInfo> memInfos
3830                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3831            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3832            long now = SystemClock.uptimeMillis();
3833            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3834                ProcessRecord rec = mLruProcesses.get(i);
3835                if (rec == dyingProc || rec.thread == null) {
3836                    continue;
3837                }
3838                if (doReport) {
3839                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3840                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3841                }
3842                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3843                    // The low memory report is overriding any current
3844                    // state for a GC request.  Make sure to do
3845                    // heavy/important/visible/foreground processes first.
3846                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3847                        rec.lastRequestedGc = 0;
3848                    } else {
3849                        rec.lastRequestedGc = rec.lastLowMemory;
3850                    }
3851                    rec.reportLowMemory = true;
3852                    rec.lastLowMemory = now;
3853                    mProcessesToGc.remove(rec);
3854                    addProcessToGcListLocked(rec);
3855                }
3856            }
3857            if (doReport) {
3858                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3859                mHandler.sendMessage(msg);
3860            }
3861            scheduleAppGcsLocked();
3862        }
3863    }
3864
3865    final void appDiedLocked(ProcessRecord app, int pid,
3866            IApplicationThread thread) {
3867
3868        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3869        synchronized (stats) {
3870            stats.noteProcessDiedLocked(app.info.uid, pid);
3871        }
3872
3873        // Clean up already done if the process has been re-started.
3874        if (app.pid == pid && app.thread != null &&
3875                app.thread.asBinder() == thread.asBinder()) {
3876            boolean doLowMem = app.instrumentationClass == null;
3877            boolean doOomAdj = doLowMem;
3878            if (!app.killedByAm) {
3879                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3880                        + ") has died.");
3881                mAllowLowerMemLevel = true;
3882            } else {
3883                // Note that we always want to do oom adj to update our state with the
3884                // new number of procs.
3885                mAllowLowerMemLevel = false;
3886                doLowMem = false;
3887            }
3888            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3889            if (DEBUG_CLEANUP) Slog.v(
3890                TAG, "Dying app: " + app + ", pid: " + pid
3891                + ", thread: " + thread.asBinder());
3892            handleAppDiedLocked(app, false, true);
3893
3894            if (doOomAdj) {
3895                updateOomAdjLocked();
3896            }
3897            if (doLowMem) {
3898                doLowMemReportIfNeededLocked(app);
3899            }
3900        } else if (app.pid != pid) {
3901            // A new process has already been started.
3902            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3903                    + ") has died and restarted (pid " + app.pid + ").");
3904            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3905        } else if (DEBUG_PROCESSES) {
3906            Slog.d(TAG, "Received spurious death notification for thread "
3907                    + thread.asBinder());
3908        }
3909    }
3910
3911    /**
3912     * If a stack trace dump file is configured, dump process stack traces.
3913     * @param clearTraces causes the dump file to be erased prior to the new
3914     *    traces being written, if true; when false, the new traces will be
3915     *    appended to any existing file content.
3916     * @param firstPids of dalvik VM processes to dump stack traces for first
3917     * @param lastPids of dalvik VM processes to dump stack traces for last
3918     * @param nativeProcs optional list of native process names to dump stack crawls
3919     * @return file containing stack traces, or null if no dump file is configured
3920     */
3921    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3922            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3923        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3924        if (tracesPath == null || tracesPath.length() == 0) {
3925            return null;
3926        }
3927
3928        File tracesFile = new File(tracesPath);
3929        try {
3930            File tracesDir = tracesFile.getParentFile();
3931            if (!tracesDir.exists()) {
3932                tracesFile.mkdirs();
3933                if (!SELinux.restorecon(tracesDir)) {
3934                    return null;
3935                }
3936            }
3937            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3938
3939            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3940            tracesFile.createNewFile();
3941            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3942        } catch (IOException e) {
3943            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3944            return null;
3945        }
3946
3947        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3948        return tracesFile;
3949    }
3950
3951    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3952            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3953        // Use a FileObserver to detect when traces finish writing.
3954        // The order of traces is considered important to maintain for legibility.
3955        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3956            @Override
3957            public synchronized void onEvent(int event, String path) { notify(); }
3958        };
3959
3960        try {
3961            observer.startWatching();
3962
3963            // First collect all of the stacks of the most important pids.
3964            if (firstPids != null) {
3965                try {
3966                    int num = firstPids.size();
3967                    for (int i = 0; i < num; i++) {
3968                        synchronized (observer) {
3969                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3970                            observer.wait(200);  // Wait for write-close, give up after 200msec
3971                        }
3972                    }
3973                } catch (InterruptedException e) {
3974                    Log.wtf(TAG, e);
3975                }
3976            }
3977
3978            // Next collect the stacks of the native pids
3979            if (nativeProcs != null) {
3980                int[] pids = Process.getPidsForCommands(nativeProcs);
3981                if (pids != null) {
3982                    for (int pid : pids) {
3983                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3984                    }
3985                }
3986            }
3987
3988            // Lastly, measure CPU usage.
3989            if (processCpuTracker != null) {
3990                processCpuTracker.init();
3991                System.gc();
3992                processCpuTracker.update();
3993                try {
3994                    synchronized (processCpuTracker) {
3995                        processCpuTracker.wait(500); // measure over 1/2 second.
3996                    }
3997                } catch (InterruptedException e) {
3998                }
3999                processCpuTracker.update();
4000
4001                // We'll take the stack crawls of just the top apps using CPU.
4002                final int N = processCpuTracker.countWorkingStats();
4003                int numProcs = 0;
4004                for (int i=0; i<N && numProcs<5; i++) {
4005                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4006                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4007                        numProcs++;
4008                        try {
4009                            synchronized (observer) {
4010                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4011                                observer.wait(200);  // Wait for write-close, give up after 200msec
4012                            }
4013                        } catch (InterruptedException e) {
4014                            Log.wtf(TAG, e);
4015                        }
4016
4017                    }
4018                }
4019            }
4020        } finally {
4021            observer.stopWatching();
4022        }
4023    }
4024
4025    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4026        if (true || IS_USER_BUILD) {
4027            return;
4028        }
4029        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4030        if (tracesPath == null || tracesPath.length() == 0) {
4031            return;
4032        }
4033
4034        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4035        StrictMode.allowThreadDiskWrites();
4036        try {
4037            final File tracesFile = new File(tracesPath);
4038            final File tracesDir = tracesFile.getParentFile();
4039            final File tracesTmp = new File(tracesDir, "__tmp__");
4040            try {
4041                if (!tracesDir.exists()) {
4042                    tracesFile.mkdirs();
4043                    if (!SELinux.restorecon(tracesDir.getPath())) {
4044                        return;
4045                    }
4046                }
4047                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4048
4049                if (tracesFile.exists()) {
4050                    tracesTmp.delete();
4051                    tracesFile.renameTo(tracesTmp);
4052                }
4053                StringBuilder sb = new StringBuilder();
4054                Time tobj = new Time();
4055                tobj.set(System.currentTimeMillis());
4056                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4057                sb.append(": ");
4058                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4059                sb.append(" since ");
4060                sb.append(msg);
4061                FileOutputStream fos = new FileOutputStream(tracesFile);
4062                fos.write(sb.toString().getBytes());
4063                if (app == null) {
4064                    fos.write("\n*** No application process!".getBytes());
4065                }
4066                fos.close();
4067                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4068            } catch (IOException e) {
4069                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4070                return;
4071            }
4072
4073            if (app != null) {
4074                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4075                firstPids.add(app.pid);
4076                dumpStackTraces(tracesPath, firstPids, null, null, null);
4077            }
4078
4079            File lastTracesFile = null;
4080            File curTracesFile = null;
4081            for (int i=9; i>=0; i--) {
4082                String name = String.format(Locale.US, "slow%02d.txt", i);
4083                curTracesFile = new File(tracesDir, name);
4084                if (curTracesFile.exists()) {
4085                    if (lastTracesFile != null) {
4086                        curTracesFile.renameTo(lastTracesFile);
4087                    } else {
4088                        curTracesFile.delete();
4089                    }
4090                }
4091                lastTracesFile = curTracesFile;
4092            }
4093            tracesFile.renameTo(curTracesFile);
4094            if (tracesTmp.exists()) {
4095                tracesTmp.renameTo(tracesFile);
4096            }
4097        } finally {
4098            StrictMode.setThreadPolicy(oldPolicy);
4099        }
4100    }
4101
4102    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4103            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4104        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4105        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4106
4107        if (mController != null) {
4108            try {
4109                // 0 == continue, -1 = kill process immediately
4110                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4111                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4112            } catch (RemoteException e) {
4113                mController = null;
4114                Watchdog.getInstance().setActivityController(null);
4115            }
4116        }
4117
4118        long anrTime = SystemClock.uptimeMillis();
4119        if (MONITOR_CPU_USAGE) {
4120            updateCpuStatsNow();
4121        }
4122
4123        synchronized (this) {
4124            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4125            if (mShuttingDown) {
4126                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4127                return;
4128            } else if (app.notResponding) {
4129                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4130                return;
4131            } else if (app.crashing) {
4132                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4133                return;
4134            }
4135
4136            // In case we come through here for the same app before completing
4137            // this one, mark as anring now so we will bail out.
4138            app.notResponding = true;
4139
4140            // Log the ANR to the event log.
4141            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4142                    app.processName, app.info.flags, annotation);
4143
4144            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4145            firstPids.add(app.pid);
4146
4147            int parentPid = app.pid;
4148            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4149            if (parentPid != app.pid) firstPids.add(parentPid);
4150
4151            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4152
4153            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4154                ProcessRecord r = mLruProcesses.get(i);
4155                if (r != null && r.thread != null) {
4156                    int pid = r.pid;
4157                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4158                        if (r.persistent) {
4159                            firstPids.add(pid);
4160                        } else {
4161                            lastPids.put(pid, Boolean.TRUE);
4162                        }
4163                    }
4164                }
4165            }
4166        }
4167
4168        // Log the ANR to the main log.
4169        StringBuilder info = new StringBuilder();
4170        info.setLength(0);
4171        info.append("ANR in ").append(app.processName);
4172        if (activity != null && activity.shortComponentName != null) {
4173            info.append(" (").append(activity.shortComponentName).append(")");
4174        }
4175        info.append("\n");
4176        info.append("PID: ").append(app.pid).append("\n");
4177        if (annotation != null) {
4178            info.append("Reason: ").append(annotation).append("\n");
4179        }
4180        if (parent != null && parent != activity) {
4181            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4182        }
4183
4184        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4185
4186        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4187                NATIVE_STACKS_OF_INTEREST);
4188
4189        String cpuInfo = null;
4190        if (MONITOR_CPU_USAGE) {
4191            updateCpuStatsNow();
4192            synchronized (mProcessCpuThread) {
4193                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4194            }
4195            info.append(processCpuTracker.printCurrentLoad());
4196            info.append(cpuInfo);
4197        }
4198
4199        info.append(processCpuTracker.printCurrentState(anrTime));
4200
4201        Slog.e(TAG, info.toString());
4202        if (tracesFile == null) {
4203            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4204            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4205        }
4206
4207        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4208                cpuInfo, tracesFile, null);
4209
4210        if (mController != null) {
4211            try {
4212                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4213                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4214                if (res != 0) {
4215                    if (res < 0 && app.pid != MY_PID) {
4216                        Process.killProcess(app.pid);
4217                    } else {
4218                        synchronized (this) {
4219                            mServices.scheduleServiceTimeoutLocked(app);
4220                        }
4221                    }
4222                    return;
4223                }
4224            } catch (RemoteException e) {
4225                mController = null;
4226                Watchdog.getInstance().setActivityController(null);
4227            }
4228        }
4229
4230        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4231        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4232                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4233
4234        synchronized (this) {
4235            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4236                killUnneededProcessLocked(app, "background ANR");
4237                return;
4238            }
4239
4240            // Set the app's notResponding state, and look up the errorReportReceiver
4241            makeAppNotRespondingLocked(app,
4242                    activity != null ? activity.shortComponentName : null,
4243                    annotation != null ? "ANR " + annotation : "ANR",
4244                    info.toString());
4245
4246            // Bring up the infamous App Not Responding dialog
4247            Message msg = Message.obtain();
4248            HashMap<String, Object> map = new HashMap<String, Object>();
4249            msg.what = SHOW_NOT_RESPONDING_MSG;
4250            msg.obj = map;
4251            msg.arg1 = aboveSystem ? 1 : 0;
4252            map.put("app", app);
4253            if (activity != null) {
4254                map.put("activity", activity);
4255            }
4256
4257            mHandler.sendMessage(msg);
4258        }
4259    }
4260
4261    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4262        if (!mLaunchWarningShown) {
4263            mLaunchWarningShown = true;
4264            mHandler.post(new Runnable() {
4265                @Override
4266                public void run() {
4267                    synchronized (ActivityManagerService.this) {
4268                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4269                        d.show();
4270                        mHandler.postDelayed(new Runnable() {
4271                            @Override
4272                            public void run() {
4273                                synchronized (ActivityManagerService.this) {
4274                                    d.dismiss();
4275                                    mLaunchWarningShown = false;
4276                                }
4277                            }
4278                        }, 4000);
4279                    }
4280                }
4281            });
4282        }
4283    }
4284
4285    @Override
4286    public boolean clearApplicationUserData(final String packageName,
4287            final IPackageDataObserver observer, int userId) {
4288        enforceNotIsolatedCaller("clearApplicationUserData");
4289        int uid = Binder.getCallingUid();
4290        int pid = Binder.getCallingPid();
4291        userId = handleIncomingUser(pid, uid,
4292                userId, false, true, "clearApplicationUserData", null);
4293        long callingId = Binder.clearCallingIdentity();
4294        try {
4295            IPackageManager pm = AppGlobals.getPackageManager();
4296            int pkgUid = -1;
4297            synchronized(this) {
4298                try {
4299                    pkgUid = pm.getPackageUid(packageName, userId);
4300                } catch (RemoteException e) {
4301                }
4302                if (pkgUid == -1) {
4303                    Slog.w(TAG, "Invalid packageName: " + packageName);
4304                    if (observer != null) {
4305                        try {
4306                            observer.onRemoveCompleted(packageName, false);
4307                        } catch (RemoteException e) {
4308                            Slog.i(TAG, "Observer no longer exists.");
4309                        }
4310                    }
4311                    return false;
4312                }
4313                if (uid == pkgUid || checkComponentPermission(
4314                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4315                        pid, uid, -1, true)
4316                        == PackageManager.PERMISSION_GRANTED) {
4317                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4318                } else {
4319                    throw new SecurityException("PID " + pid + " does not have permission "
4320                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4321                                    + " of package " + packageName);
4322                }
4323            }
4324
4325            try {
4326                // Clear application user data
4327                pm.clearApplicationUserData(packageName, observer, userId);
4328
4329                // Remove all permissions granted from/to this package
4330                removeUriPermissionsForPackageLocked(packageName, userId, true);
4331
4332                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4333                        Uri.fromParts("package", packageName, null));
4334                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4335                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4336                        null, null, 0, null, null, null, false, false, userId);
4337            } catch (RemoteException e) {
4338            }
4339        } finally {
4340            Binder.restoreCallingIdentity(callingId);
4341        }
4342        return true;
4343    }
4344
4345    @Override
4346    public void killBackgroundProcesses(final String packageName, int userId) {
4347        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4348                != PackageManager.PERMISSION_GRANTED &&
4349                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4350                        != PackageManager.PERMISSION_GRANTED) {
4351            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4352                    + Binder.getCallingPid()
4353                    + ", uid=" + Binder.getCallingUid()
4354                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4355            Slog.w(TAG, msg);
4356            throw new SecurityException(msg);
4357        }
4358
4359        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4360                userId, true, true, "killBackgroundProcesses", null);
4361        long callingId = Binder.clearCallingIdentity();
4362        try {
4363            IPackageManager pm = AppGlobals.getPackageManager();
4364            synchronized(this) {
4365                int appId = -1;
4366                try {
4367                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4368                } catch (RemoteException e) {
4369                }
4370                if (appId == -1) {
4371                    Slog.w(TAG, "Invalid packageName: " + packageName);
4372                    return;
4373                }
4374                killPackageProcessesLocked(packageName, appId, userId,
4375                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4376            }
4377        } finally {
4378            Binder.restoreCallingIdentity(callingId);
4379        }
4380    }
4381
4382    @Override
4383    public void killAllBackgroundProcesses() {
4384        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4385                != PackageManager.PERMISSION_GRANTED) {
4386            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4387                    + Binder.getCallingPid()
4388                    + ", uid=" + Binder.getCallingUid()
4389                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4390            Slog.w(TAG, msg);
4391            throw new SecurityException(msg);
4392        }
4393
4394        long callingId = Binder.clearCallingIdentity();
4395        try {
4396            synchronized(this) {
4397                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4398                final int NP = mProcessNames.getMap().size();
4399                for (int ip=0; ip<NP; ip++) {
4400                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4401                    final int NA = apps.size();
4402                    for (int ia=0; ia<NA; ia++) {
4403                        ProcessRecord app = apps.valueAt(ia);
4404                        if (app.persistent) {
4405                            // we don't kill persistent processes
4406                            continue;
4407                        }
4408                        if (app.removed) {
4409                            procs.add(app);
4410                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4411                            app.removed = true;
4412                            procs.add(app);
4413                        }
4414                    }
4415                }
4416
4417                int N = procs.size();
4418                for (int i=0; i<N; i++) {
4419                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4420                }
4421                mAllowLowerMemLevel = true;
4422                updateOomAdjLocked();
4423                doLowMemReportIfNeededLocked(null);
4424            }
4425        } finally {
4426            Binder.restoreCallingIdentity(callingId);
4427        }
4428    }
4429
4430    @Override
4431    public void forceStopPackage(final String packageName, int userId) {
4432        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4433                != PackageManager.PERMISSION_GRANTED) {
4434            String msg = "Permission Denial: forceStopPackage() from pid="
4435                    + Binder.getCallingPid()
4436                    + ", uid=" + Binder.getCallingUid()
4437                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4438            Slog.w(TAG, msg);
4439            throw new SecurityException(msg);
4440        }
4441        final int callingPid = Binder.getCallingPid();
4442        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4443                userId, true, true, "forceStopPackage", null);
4444        long callingId = Binder.clearCallingIdentity();
4445        try {
4446            IPackageManager pm = AppGlobals.getPackageManager();
4447            synchronized(this) {
4448                int[] users = userId == UserHandle.USER_ALL
4449                        ? getUsersLocked() : new int[] { userId };
4450                for (int user : users) {
4451                    int pkgUid = -1;
4452                    try {
4453                        pkgUid = pm.getPackageUid(packageName, user);
4454                    } catch (RemoteException e) {
4455                    }
4456                    if (pkgUid == -1) {
4457                        Slog.w(TAG, "Invalid packageName: " + packageName);
4458                        continue;
4459                    }
4460                    try {
4461                        pm.setPackageStoppedState(packageName, true, user);
4462                    } catch (RemoteException e) {
4463                    } catch (IllegalArgumentException e) {
4464                        Slog.w(TAG, "Failed trying to unstop package "
4465                                + packageName + ": " + e);
4466                    }
4467                    if (isUserRunningLocked(user, false)) {
4468                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4469                    }
4470                }
4471            }
4472        } finally {
4473            Binder.restoreCallingIdentity(callingId);
4474        }
4475    }
4476
4477    /*
4478     * The pkg name and app id have to be specified.
4479     */
4480    @Override
4481    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4482        if (pkg == null) {
4483            return;
4484        }
4485        // Make sure the uid is valid.
4486        if (appid < 0) {
4487            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4488            return;
4489        }
4490        int callerUid = Binder.getCallingUid();
4491        // Only the system server can kill an application
4492        if (callerUid == Process.SYSTEM_UID) {
4493            // Post an aysnc message to kill the application
4494            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4495            msg.arg1 = appid;
4496            msg.arg2 = 0;
4497            Bundle bundle = new Bundle();
4498            bundle.putString("pkg", pkg);
4499            bundle.putString("reason", reason);
4500            msg.obj = bundle;
4501            mHandler.sendMessage(msg);
4502        } else {
4503            throw new SecurityException(callerUid + " cannot kill pkg: " +
4504                    pkg);
4505        }
4506    }
4507
4508    @Override
4509    public void closeSystemDialogs(String reason) {
4510        enforceNotIsolatedCaller("closeSystemDialogs");
4511
4512        final int pid = Binder.getCallingPid();
4513        final int uid = Binder.getCallingUid();
4514        final long origId = Binder.clearCallingIdentity();
4515        try {
4516            synchronized (this) {
4517                // Only allow this from foreground processes, so that background
4518                // applications can't abuse it to prevent system UI from being shown.
4519                if (uid >= Process.FIRST_APPLICATION_UID) {
4520                    ProcessRecord proc;
4521                    synchronized (mPidsSelfLocked) {
4522                        proc = mPidsSelfLocked.get(pid);
4523                    }
4524                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4525                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4526                                + " from background process " + proc);
4527                        return;
4528                    }
4529                }
4530                closeSystemDialogsLocked(reason);
4531            }
4532        } finally {
4533            Binder.restoreCallingIdentity(origId);
4534        }
4535    }
4536
4537    void closeSystemDialogsLocked(String reason) {
4538        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4539        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4540                | Intent.FLAG_RECEIVER_FOREGROUND);
4541        if (reason != null) {
4542            intent.putExtra("reason", reason);
4543        }
4544        mWindowManager.closeSystemDialogs(reason);
4545
4546        mStackSupervisor.closeSystemDialogsLocked();
4547
4548        broadcastIntentLocked(null, null, intent, null,
4549                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4550                Process.SYSTEM_UID, UserHandle.USER_ALL);
4551    }
4552
4553    @Override
4554    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4555        enforceNotIsolatedCaller("getProcessMemoryInfo");
4556        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4557        for (int i=pids.length-1; i>=0; i--) {
4558            ProcessRecord proc;
4559            int oomAdj;
4560            synchronized (this) {
4561                synchronized (mPidsSelfLocked) {
4562                    proc = mPidsSelfLocked.get(pids[i]);
4563                    oomAdj = proc != null ? proc.setAdj : 0;
4564                }
4565            }
4566            infos[i] = new Debug.MemoryInfo();
4567            Debug.getMemoryInfo(pids[i], infos[i]);
4568            if (proc != null) {
4569                synchronized (this) {
4570                    if (proc.thread != null && proc.setAdj == oomAdj) {
4571                        // Record this for posterity if the process has been stable.
4572                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4573                                infos[i].getTotalUss(), false, proc.pkgList);
4574                    }
4575                }
4576            }
4577        }
4578        return infos;
4579    }
4580
4581    @Override
4582    public long[] getProcessPss(int[] pids) {
4583        enforceNotIsolatedCaller("getProcessPss");
4584        long[] pss = new long[pids.length];
4585        for (int i=pids.length-1; i>=0; i--) {
4586            ProcessRecord proc;
4587            int oomAdj;
4588            synchronized (this) {
4589                synchronized (mPidsSelfLocked) {
4590                    proc = mPidsSelfLocked.get(pids[i]);
4591                    oomAdj = proc != null ? proc.setAdj : 0;
4592                }
4593            }
4594            long[] tmpUss = new long[1];
4595            pss[i] = Debug.getPss(pids[i], tmpUss);
4596            if (proc != null) {
4597                synchronized (this) {
4598                    if (proc.thread != null && proc.setAdj == oomAdj) {
4599                        // Record this for posterity if the process has been stable.
4600                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4601                    }
4602                }
4603            }
4604        }
4605        return pss;
4606    }
4607
4608    @Override
4609    public void killApplicationProcess(String processName, int uid) {
4610        if (processName == null) {
4611            return;
4612        }
4613
4614        int callerUid = Binder.getCallingUid();
4615        // Only the system server can kill an application
4616        if (callerUid == Process.SYSTEM_UID) {
4617            synchronized (this) {
4618                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4619                if (app != null && app.thread != null) {
4620                    try {
4621                        app.thread.scheduleSuicide();
4622                    } catch (RemoteException e) {
4623                        // If the other end already died, then our work here is done.
4624                    }
4625                } else {
4626                    Slog.w(TAG, "Process/uid not found attempting kill of "
4627                            + processName + " / " + uid);
4628                }
4629            }
4630        } else {
4631            throw new SecurityException(callerUid + " cannot kill app process: " +
4632                    processName);
4633        }
4634    }
4635
4636    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4637        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4638                false, true, false, false, UserHandle.getUserId(uid), reason);
4639        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4640                Uri.fromParts("package", packageName, null));
4641        if (!mProcessesReady) {
4642            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4643                    | Intent.FLAG_RECEIVER_FOREGROUND);
4644        }
4645        intent.putExtra(Intent.EXTRA_UID, uid);
4646        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4647        broadcastIntentLocked(null, null, intent,
4648                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4649                false, false,
4650                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4651    }
4652
4653    private void forceStopUserLocked(int userId, String reason) {
4654        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4655        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4656        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4657                | Intent.FLAG_RECEIVER_FOREGROUND);
4658        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4659        broadcastIntentLocked(null, null, intent,
4660                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4661                false, false,
4662                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4663    }
4664
4665    private final boolean killPackageProcessesLocked(String packageName, int appId,
4666            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4667            boolean doit, boolean evenPersistent, String reason) {
4668        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4669
4670        // Remove all processes this package may have touched: all with the
4671        // same UID (except for the system or root user), and all whose name
4672        // matches the package name.
4673        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4674        final int NP = mProcessNames.getMap().size();
4675        for (int ip=0; ip<NP; ip++) {
4676            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4677            final int NA = apps.size();
4678            for (int ia=0; ia<NA; ia++) {
4679                ProcessRecord app = apps.valueAt(ia);
4680                if (app.persistent && !evenPersistent) {
4681                    // we don't kill persistent processes
4682                    continue;
4683                }
4684                if (app.removed) {
4685                    if (doit) {
4686                        procs.add(app);
4687                    }
4688                    continue;
4689                }
4690
4691                // Skip process if it doesn't meet our oom adj requirement.
4692                if (app.setAdj < minOomAdj) {
4693                    continue;
4694                }
4695
4696                // If no package is specified, we call all processes under the
4697                // give user id.
4698                if (packageName == null) {
4699                    if (app.userId != userId) {
4700                        continue;
4701                    }
4702                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4703                        continue;
4704                    }
4705                // Package has been specified, we want to hit all processes
4706                // that match it.  We need to qualify this by the processes
4707                // that are running under the specified app and user ID.
4708                } else {
4709                    if (UserHandle.getAppId(app.uid) != appId) {
4710                        continue;
4711                    }
4712                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4713                        continue;
4714                    }
4715                    if (!app.pkgList.containsKey(packageName)) {
4716                        continue;
4717                    }
4718                }
4719
4720                // Process has passed all conditions, kill it!
4721                if (!doit) {
4722                    return true;
4723                }
4724                app.removed = true;
4725                procs.add(app);
4726            }
4727        }
4728
4729        int N = procs.size();
4730        for (int i=0; i<N; i++) {
4731            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4732        }
4733        updateOomAdjLocked();
4734        return N > 0;
4735    }
4736
4737    private final boolean forceStopPackageLocked(String name, int appId,
4738            boolean callerWillRestart, boolean purgeCache, boolean doit,
4739            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4740        int i;
4741        int N;
4742
4743        if (userId == UserHandle.USER_ALL && name == null) {
4744            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4745        }
4746
4747        if (appId < 0 && name != null) {
4748            try {
4749                appId = UserHandle.getAppId(
4750                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4751            } catch (RemoteException e) {
4752            }
4753        }
4754
4755        if (doit) {
4756            if (name != null) {
4757                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4758                        + " user=" + userId + ": " + reason);
4759            } else {
4760                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4761            }
4762
4763            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4764            for (int ip=pmap.size()-1; ip>=0; ip--) {
4765                SparseArray<Long> ba = pmap.valueAt(ip);
4766                for (i=ba.size()-1; i>=0; i--) {
4767                    boolean remove = false;
4768                    final int entUid = ba.keyAt(i);
4769                    if (name != null) {
4770                        if (userId == UserHandle.USER_ALL) {
4771                            if (UserHandle.getAppId(entUid) == appId) {
4772                                remove = true;
4773                            }
4774                        } else {
4775                            if (entUid == UserHandle.getUid(userId, appId)) {
4776                                remove = true;
4777                            }
4778                        }
4779                    } else if (UserHandle.getUserId(entUid) == userId) {
4780                        remove = true;
4781                    }
4782                    if (remove) {
4783                        ba.removeAt(i);
4784                    }
4785                }
4786                if (ba.size() == 0) {
4787                    pmap.removeAt(ip);
4788                }
4789            }
4790        }
4791
4792        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4793                -100, callerWillRestart, true, doit, evenPersistent,
4794                name == null ? ("stop user " + userId) : ("stop " + name));
4795
4796        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4797            if (!doit) {
4798                return true;
4799            }
4800            didSomething = true;
4801        }
4802
4803        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4804            if (!doit) {
4805                return true;
4806            }
4807            didSomething = true;
4808        }
4809
4810        if (name == null) {
4811            // Remove all sticky broadcasts from this user.
4812            mStickyBroadcasts.remove(userId);
4813        }
4814
4815        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4816        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4817                userId, providers)) {
4818            if (!doit) {
4819                return true;
4820            }
4821            didSomething = true;
4822        }
4823        N = providers.size();
4824        for (i=0; i<N; i++) {
4825            removeDyingProviderLocked(null, providers.get(i), true);
4826        }
4827
4828        // Remove transient permissions granted from/to this package/user
4829        removeUriPermissionsForPackageLocked(name, userId, false);
4830
4831        if (name == null || uninstalling) {
4832            // Remove pending intents.  For now we only do this when force
4833            // stopping users, because we have some problems when doing this
4834            // for packages -- app widgets are not currently cleaned up for
4835            // such packages, so they can be left with bad pending intents.
4836            if (mIntentSenderRecords.size() > 0) {
4837                Iterator<WeakReference<PendingIntentRecord>> it
4838                        = mIntentSenderRecords.values().iterator();
4839                while (it.hasNext()) {
4840                    WeakReference<PendingIntentRecord> wpir = it.next();
4841                    if (wpir == null) {
4842                        it.remove();
4843                        continue;
4844                    }
4845                    PendingIntentRecord pir = wpir.get();
4846                    if (pir == null) {
4847                        it.remove();
4848                        continue;
4849                    }
4850                    if (name == null) {
4851                        // Stopping user, remove all objects for the user.
4852                        if (pir.key.userId != userId) {
4853                            // Not the same user, skip it.
4854                            continue;
4855                        }
4856                    } else {
4857                        if (UserHandle.getAppId(pir.uid) != appId) {
4858                            // Different app id, skip it.
4859                            continue;
4860                        }
4861                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4862                            // Different user, skip it.
4863                            continue;
4864                        }
4865                        if (!pir.key.packageName.equals(name)) {
4866                            // Different package, skip it.
4867                            continue;
4868                        }
4869                    }
4870                    if (!doit) {
4871                        return true;
4872                    }
4873                    didSomething = true;
4874                    it.remove();
4875                    pir.canceled = true;
4876                    if (pir.key.activity != null) {
4877                        pir.key.activity.pendingResults.remove(pir.ref);
4878                    }
4879                }
4880            }
4881        }
4882
4883        if (doit) {
4884            if (purgeCache && name != null) {
4885                AttributeCache ac = AttributeCache.instance();
4886                if (ac != null) {
4887                    ac.removePackage(name);
4888                }
4889            }
4890            if (mBooted) {
4891                mStackSupervisor.resumeTopActivitiesLocked();
4892                mStackSupervisor.scheduleIdleLocked();
4893            }
4894        }
4895
4896        return didSomething;
4897    }
4898
4899    private final boolean removeProcessLocked(ProcessRecord app,
4900            boolean callerWillRestart, boolean allowRestart, String reason) {
4901        final String name = app.processName;
4902        final int uid = app.uid;
4903        if (DEBUG_PROCESSES) Slog.d(
4904            TAG, "Force removing proc " + app.toShortString() + " (" + name
4905            + "/" + uid + ")");
4906
4907        mProcessNames.remove(name, uid);
4908        mIsolatedProcesses.remove(app.uid);
4909        if (mHeavyWeightProcess == app) {
4910            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4911                    mHeavyWeightProcess.userId, 0));
4912            mHeavyWeightProcess = null;
4913        }
4914        boolean needRestart = false;
4915        if (app.pid > 0 && app.pid != MY_PID) {
4916            int pid = app.pid;
4917            synchronized (mPidsSelfLocked) {
4918                mPidsSelfLocked.remove(pid);
4919                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4920            }
4921            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4922                    app.processName, app.info.uid);
4923            if (app.isolated) {
4924                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4925            }
4926            killUnneededProcessLocked(app, reason);
4927            handleAppDiedLocked(app, true, allowRestart);
4928            removeLruProcessLocked(app);
4929
4930            if (app.persistent && !app.isolated) {
4931                if (!callerWillRestart) {
4932                    addAppLocked(app.info, false);
4933                } else {
4934                    needRestart = true;
4935                }
4936            }
4937        } else {
4938            mRemovedProcesses.add(app);
4939        }
4940
4941        return needRestart;
4942    }
4943
4944    private final void processStartTimedOutLocked(ProcessRecord app) {
4945        final int pid = app.pid;
4946        boolean gone = false;
4947        synchronized (mPidsSelfLocked) {
4948            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4949            if (knownApp != null && knownApp.thread == null) {
4950                mPidsSelfLocked.remove(pid);
4951                gone = true;
4952            }
4953        }
4954
4955        if (gone) {
4956            Slog.w(TAG, "Process " + app + " failed to attach");
4957            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4958                    pid, app.uid, app.processName);
4959            mProcessNames.remove(app.processName, app.uid);
4960            mIsolatedProcesses.remove(app.uid);
4961            if (mHeavyWeightProcess == app) {
4962                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4963                        mHeavyWeightProcess.userId, 0));
4964                mHeavyWeightProcess = null;
4965            }
4966            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4967                    app.processName, app.info.uid);
4968            if (app.isolated) {
4969                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4970            }
4971            // Take care of any launching providers waiting for this process.
4972            checkAppInLaunchingProvidersLocked(app, true);
4973            // Take care of any services that are waiting for the process.
4974            mServices.processStartTimedOutLocked(app);
4975            killUnneededProcessLocked(app, "start timeout");
4976            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4977                Slog.w(TAG, "Unattached app died before backup, skipping");
4978                try {
4979                    IBackupManager bm = IBackupManager.Stub.asInterface(
4980                            ServiceManager.getService(Context.BACKUP_SERVICE));
4981                    bm.agentDisconnected(app.info.packageName);
4982                } catch (RemoteException e) {
4983                    // Can't happen; the backup manager is local
4984                }
4985            }
4986            if (isPendingBroadcastProcessLocked(pid)) {
4987                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4988                skipPendingBroadcastLocked(pid);
4989            }
4990        } else {
4991            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4992        }
4993    }
4994
4995    private final boolean attachApplicationLocked(IApplicationThread thread,
4996            int pid) {
4997
4998        // Find the application record that is being attached...  either via
4999        // the pid if we are running in multiple processes, or just pull the
5000        // next app record if we are emulating process with anonymous threads.
5001        ProcessRecord app;
5002        if (pid != MY_PID && pid >= 0) {
5003            synchronized (mPidsSelfLocked) {
5004                app = mPidsSelfLocked.get(pid);
5005            }
5006        } else {
5007            app = null;
5008        }
5009
5010        if (app == null) {
5011            Slog.w(TAG, "No pending application record for pid " + pid
5012                    + " (IApplicationThread " + thread + "); dropping process");
5013            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5014            if (pid > 0 && pid != MY_PID) {
5015                Process.killProcessQuiet(pid);
5016            } else {
5017                try {
5018                    thread.scheduleExit();
5019                } catch (Exception e) {
5020                    // Ignore exceptions.
5021                }
5022            }
5023            return false;
5024        }
5025
5026        // If this application record is still attached to a previous
5027        // process, clean it up now.
5028        if (app.thread != null) {
5029            handleAppDiedLocked(app, true, true);
5030        }
5031
5032        // Tell the process all about itself.
5033
5034        if (localLOGV) Slog.v(
5035                TAG, "Binding process pid " + pid + " to record " + app);
5036
5037        final String processName = app.processName;
5038        try {
5039            AppDeathRecipient adr = new AppDeathRecipient(
5040                    app, pid, thread);
5041            thread.asBinder().linkToDeath(adr, 0);
5042            app.deathRecipient = adr;
5043        } catch (RemoteException e) {
5044            app.resetPackageList(mProcessStats);
5045            startProcessLocked(app, "link fail", processName);
5046            return false;
5047        }
5048
5049        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5050
5051        app.makeActive(thread, mProcessStats);
5052        app.curAdj = app.setAdj = -100;
5053        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5054        app.forcingToForeground = null;
5055        updateProcessForegroundLocked(app, false, false);
5056        app.hasShownUi = false;
5057        app.debugging = false;
5058        app.cached = false;
5059
5060        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5061
5062        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5063        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5064
5065        if (!normalMode) {
5066            Slog.i(TAG, "Launching preboot mode app: " + app);
5067        }
5068
5069        if (localLOGV) Slog.v(
5070            TAG, "New app record " + app
5071            + " thread=" + thread.asBinder() + " pid=" + pid);
5072        try {
5073            int testMode = IApplicationThread.DEBUG_OFF;
5074            if (mDebugApp != null && mDebugApp.equals(processName)) {
5075                testMode = mWaitForDebugger
5076                    ? IApplicationThread.DEBUG_WAIT
5077                    : IApplicationThread.DEBUG_ON;
5078                app.debugging = true;
5079                if (mDebugTransient) {
5080                    mDebugApp = mOrigDebugApp;
5081                    mWaitForDebugger = mOrigWaitForDebugger;
5082                }
5083            }
5084            String profileFile = app.instrumentationProfileFile;
5085            ParcelFileDescriptor profileFd = null;
5086            boolean profileAutoStop = false;
5087            if (mProfileApp != null && mProfileApp.equals(processName)) {
5088                mProfileProc = app;
5089                profileFile = mProfileFile;
5090                profileFd = mProfileFd;
5091                profileAutoStop = mAutoStopProfiler;
5092            }
5093            boolean enableOpenGlTrace = false;
5094            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5095                enableOpenGlTrace = true;
5096                mOpenGlTraceApp = null;
5097            }
5098
5099            // If the app is being launched for restore or full backup, set it up specially
5100            boolean isRestrictedBackupMode = false;
5101            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5102                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5103                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5104                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5105            }
5106
5107            ensurePackageDexOpt(app.instrumentationInfo != null
5108                    ? app.instrumentationInfo.packageName
5109                    : app.info.packageName);
5110            if (app.instrumentationClass != null) {
5111                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5112            }
5113            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5114                    + processName + " with config " + mConfiguration);
5115            ApplicationInfo appInfo = app.instrumentationInfo != null
5116                    ? app.instrumentationInfo : app.info;
5117            app.compat = compatibilityInfoForPackageLocked(appInfo);
5118            if (profileFd != null) {
5119                profileFd = profileFd.dup();
5120            }
5121            thread.bindApplication(processName, appInfo, providers,
5122                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5123                    app.instrumentationArguments, app.instrumentationWatcher,
5124                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5125                    isRestrictedBackupMode || !normalMode, app.persistent,
5126                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5127                    mCoreSettingsObserver.getCoreSettingsLocked());
5128            updateLruProcessLocked(app, false, null);
5129            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5130        } catch (Exception e) {
5131            // todo: Yikes!  What should we do?  For now we will try to
5132            // start another process, but that could easily get us in
5133            // an infinite loop of restarting processes...
5134            Slog.w(TAG, "Exception thrown during bind!", e);
5135
5136            app.resetPackageList(mProcessStats);
5137            app.unlinkDeathRecipient();
5138            startProcessLocked(app, "bind fail", processName);
5139            return false;
5140        }
5141
5142        // Remove this record from the list of starting applications.
5143        mPersistentStartingProcesses.remove(app);
5144        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5145                "Attach application locked removing on hold: " + app);
5146        mProcessesOnHold.remove(app);
5147
5148        boolean badApp = false;
5149        boolean didSomething = false;
5150
5151        // See if the top visible activity is waiting to run in this process...
5152        if (normalMode) {
5153            try {
5154                if (mStackSupervisor.attachApplicationLocked(app)) {
5155                    didSomething = true;
5156                }
5157            } catch (Exception e) {
5158                badApp = true;
5159            }
5160        }
5161
5162        // Find any services that should be running in this process...
5163        if (!badApp) {
5164            try {
5165                didSomething |= mServices.attachApplicationLocked(app, processName);
5166            } catch (Exception e) {
5167                badApp = true;
5168            }
5169        }
5170
5171        // Check if a next-broadcast receiver is in this process...
5172        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5173            try {
5174                didSomething |= sendPendingBroadcastsLocked(app);
5175            } catch (Exception e) {
5176                // If the app died trying to launch the receiver we declare it 'bad'
5177                badApp = true;
5178            }
5179        }
5180
5181        // Check whether the next backup agent is in this process...
5182        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5183            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5184            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5185            try {
5186                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5187                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5188                        mBackupTarget.backupMode);
5189            } catch (Exception e) {
5190                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5191                e.printStackTrace();
5192            }
5193        }
5194
5195        if (badApp) {
5196            // todo: Also need to kill application to deal with all
5197            // kinds of exceptions.
5198            handleAppDiedLocked(app, false, true);
5199            return false;
5200        }
5201
5202        if (!didSomething) {
5203            updateOomAdjLocked();
5204        }
5205
5206        return true;
5207    }
5208
5209    @Override
5210    public final void attachApplication(IApplicationThread thread) {
5211        synchronized (this) {
5212            int callingPid = Binder.getCallingPid();
5213            final long origId = Binder.clearCallingIdentity();
5214            attachApplicationLocked(thread, callingPid);
5215            Binder.restoreCallingIdentity(origId);
5216        }
5217    }
5218
5219    @Override
5220    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5221        final long origId = Binder.clearCallingIdentity();
5222        synchronized (this) {
5223            ActivityStack stack = ActivityRecord.getStackLocked(token);
5224            if (stack != null) {
5225                ActivityRecord r =
5226                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5227                if (stopProfiling) {
5228                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5229                        try {
5230                            mProfileFd.close();
5231                        } catch (IOException e) {
5232                        }
5233                        clearProfilerLocked();
5234                    }
5235                }
5236            }
5237        }
5238        Binder.restoreCallingIdentity(origId);
5239    }
5240
5241    void enableScreenAfterBoot() {
5242        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5243                SystemClock.uptimeMillis());
5244        mWindowManager.enableScreenAfterBoot();
5245
5246        synchronized (this) {
5247            updateEventDispatchingLocked();
5248        }
5249    }
5250
5251    @Override
5252    public void showBootMessage(final CharSequence msg, final boolean always) {
5253        enforceNotIsolatedCaller("showBootMessage");
5254        mWindowManager.showBootMessage(msg, always);
5255    }
5256
5257    @Override
5258    public void dismissKeyguardOnNextActivity() {
5259        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5260        final long token = Binder.clearCallingIdentity();
5261        try {
5262            synchronized (this) {
5263                if (DEBUG_LOCKSCREEN) logLockScreen("");
5264                if (mLockScreenShown) {
5265                    mLockScreenShown = false;
5266                    comeOutOfSleepIfNeededLocked();
5267                }
5268                mStackSupervisor.setDismissKeyguard(true);
5269            }
5270        } finally {
5271            Binder.restoreCallingIdentity(token);
5272        }
5273    }
5274
5275    final void finishBooting() {
5276        // Register receivers to handle package update events
5277        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5278
5279        synchronized (this) {
5280            // Ensure that any processes we had put on hold are now started
5281            // up.
5282            final int NP = mProcessesOnHold.size();
5283            if (NP > 0) {
5284                ArrayList<ProcessRecord> procs =
5285                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5286                for (int ip=0; ip<NP; ip++) {
5287                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5288                            + procs.get(ip));
5289                    startProcessLocked(procs.get(ip), "on-hold", null);
5290                }
5291            }
5292
5293            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5294                // Start looking for apps that are abusing wake locks.
5295                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5296                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5297                // Tell anyone interested that we are done booting!
5298                SystemProperties.set("sys.boot_completed", "1");
5299                SystemProperties.set("dev.bootcomplete", "1");
5300                for (int i=0; i<mStartedUsers.size(); i++) {
5301                    UserStartedState uss = mStartedUsers.valueAt(i);
5302                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5303                        uss.mState = UserStartedState.STATE_RUNNING;
5304                        final int userId = mStartedUsers.keyAt(i);
5305                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5306                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5307                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5308                        broadcastIntentLocked(null, null, intent, null,
5309                                new IIntentReceiver.Stub() {
5310                                    @Override
5311                                    public void performReceive(Intent intent, int resultCode,
5312                                            String data, Bundle extras, boolean ordered,
5313                                            boolean sticky, int sendingUser) {
5314                                        synchronized (ActivityManagerService.this) {
5315                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5316                                                    true, false);
5317                                        }
5318                                    }
5319                                },
5320                                0, null, null,
5321                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5322                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5323                                userId);
5324                    }
5325                }
5326                scheduleStartProfilesLocked();
5327            }
5328        }
5329    }
5330
5331    final void ensureBootCompleted() {
5332        boolean booting;
5333        boolean enableScreen;
5334        synchronized (this) {
5335            booting = mBooting;
5336            mBooting = false;
5337            enableScreen = !mBooted;
5338            mBooted = true;
5339        }
5340
5341        if (booting) {
5342            finishBooting();
5343        }
5344
5345        if (enableScreen) {
5346            enableScreenAfterBoot();
5347        }
5348    }
5349
5350    @Override
5351    public final void activityResumed(IBinder token) {
5352        final long origId = Binder.clearCallingIdentity();
5353        synchronized(this) {
5354            ActivityStack stack = ActivityRecord.getStackLocked(token);
5355            if (stack != null) {
5356                ActivityRecord.activityResumedLocked(token);
5357            }
5358        }
5359        Binder.restoreCallingIdentity(origId);
5360    }
5361
5362    @Override
5363    public final void activityPaused(IBinder token) {
5364        final long origId = Binder.clearCallingIdentity();
5365        synchronized(this) {
5366            ActivityStack stack = ActivityRecord.getStackLocked(token);
5367            if (stack != null) {
5368                stack.activityPausedLocked(token, false);
5369            }
5370        }
5371        Binder.restoreCallingIdentity(origId);
5372    }
5373
5374    @Override
5375    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5376            CharSequence description) {
5377        if (localLOGV) Slog.v(
5378            TAG, "Activity stopped: token=" + token);
5379
5380        // Refuse possible leaked file descriptors
5381        if (icicle != null && icicle.hasFileDescriptors()) {
5382            throw new IllegalArgumentException("File descriptors passed in Bundle");
5383        }
5384
5385        ActivityRecord r = null;
5386
5387        final long origId = Binder.clearCallingIdentity();
5388
5389        synchronized (this) {
5390            r = ActivityRecord.isInStackLocked(token);
5391            if (r != null) {
5392                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5393            }
5394        }
5395
5396        if (r != null) {
5397            sendPendingThumbnail(r, null, null, null, false);
5398        }
5399
5400        trimApplications();
5401
5402        Binder.restoreCallingIdentity(origId);
5403    }
5404
5405    @Override
5406    public final void activityDestroyed(IBinder token) {
5407        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5408        synchronized (this) {
5409            ActivityStack stack = ActivityRecord.getStackLocked(token);
5410            if (stack != null) {
5411                stack.activityDestroyedLocked(token);
5412            }
5413        }
5414    }
5415
5416    @Override
5417    public String getCallingPackage(IBinder token) {
5418        synchronized (this) {
5419            ActivityRecord r = getCallingRecordLocked(token);
5420            return r != null ? r.info.packageName : null;
5421        }
5422    }
5423
5424    @Override
5425    public ComponentName getCallingActivity(IBinder token) {
5426        synchronized (this) {
5427            ActivityRecord r = getCallingRecordLocked(token);
5428            return r != null ? r.intent.getComponent() : null;
5429        }
5430    }
5431
5432    private ActivityRecord getCallingRecordLocked(IBinder token) {
5433        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5434        if (r == null) {
5435            return null;
5436        }
5437        return r.resultTo;
5438    }
5439
5440    @Override
5441    public ComponentName getActivityClassForToken(IBinder token) {
5442        synchronized(this) {
5443            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5444            if (r == null) {
5445                return null;
5446            }
5447            return r.intent.getComponent();
5448        }
5449    }
5450
5451    @Override
5452    public String getPackageForToken(IBinder token) {
5453        synchronized(this) {
5454            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5455            if (r == null) {
5456                return null;
5457            }
5458            return r.packageName;
5459        }
5460    }
5461
5462    @Override
5463    public IIntentSender getIntentSender(int type,
5464            String packageName, IBinder token, String resultWho,
5465            int requestCode, Intent[] intents, String[] resolvedTypes,
5466            int flags, Bundle options, int userId) {
5467        enforceNotIsolatedCaller("getIntentSender");
5468        // Refuse possible leaked file descriptors
5469        if (intents != null) {
5470            if (intents.length < 1) {
5471                throw new IllegalArgumentException("Intents array length must be >= 1");
5472            }
5473            for (int i=0; i<intents.length; i++) {
5474                Intent intent = intents[i];
5475                if (intent != null) {
5476                    if (intent.hasFileDescriptors()) {
5477                        throw new IllegalArgumentException("File descriptors passed in Intent");
5478                    }
5479                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5480                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5481                        throw new IllegalArgumentException(
5482                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5483                    }
5484                    intents[i] = new Intent(intent);
5485                }
5486            }
5487            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5488                throw new IllegalArgumentException(
5489                        "Intent array length does not match resolvedTypes length");
5490            }
5491        }
5492        if (options != null) {
5493            if (options.hasFileDescriptors()) {
5494                throw new IllegalArgumentException("File descriptors passed in options");
5495            }
5496        }
5497
5498        synchronized(this) {
5499            int callingUid = Binder.getCallingUid();
5500            int origUserId = userId;
5501            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5502                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5503                    "getIntentSender", null);
5504            if (origUserId == UserHandle.USER_CURRENT) {
5505                // We don't want to evaluate this until the pending intent is
5506                // actually executed.  However, we do want to always do the
5507                // security checking for it above.
5508                userId = UserHandle.USER_CURRENT;
5509            }
5510            try {
5511                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5512                    int uid = AppGlobals.getPackageManager()
5513                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5514                    if (!UserHandle.isSameApp(callingUid, uid)) {
5515                        String msg = "Permission Denial: getIntentSender() from pid="
5516                            + Binder.getCallingPid()
5517                            + ", uid=" + Binder.getCallingUid()
5518                            + ", (need uid=" + uid + ")"
5519                            + " is not allowed to send as package " + packageName;
5520                        Slog.w(TAG, msg);
5521                        throw new SecurityException(msg);
5522                    }
5523                }
5524
5525                return getIntentSenderLocked(type, packageName, callingUid, userId,
5526                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5527
5528            } catch (RemoteException e) {
5529                throw new SecurityException(e);
5530            }
5531        }
5532    }
5533
5534    IIntentSender getIntentSenderLocked(int type, String packageName,
5535            int callingUid, int userId, IBinder token, String resultWho,
5536            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5537            Bundle options) {
5538        if (DEBUG_MU)
5539            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5540        ActivityRecord activity = null;
5541        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5542            activity = ActivityRecord.isInStackLocked(token);
5543            if (activity == null) {
5544                return null;
5545            }
5546            if (activity.finishing) {
5547                return null;
5548            }
5549        }
5550
5551        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5552        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5553        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5554        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5555                |PendingIntent.FLAG_UPDATE_CURRENT);
5556
5557        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5558                type, packageName, activity, resultWho,
5559                requestCode, intents, resolvedTypes, flags, options, userId);
5560        WeakReference<PendingIntentRecord> ref;
5561        ref = mIntentSenderRecords.get(key);
5562        PendingIntentRecord rec = ref != null ? ref.get() : null;
5563        if (rec != null) {
5564            if (!cancelCurrent) {
5565                if (updateCurrent) {
5566                    if (rec.key.requestIntent != null) {
5567                        rec.key.requestIntent.replaceExtras(intents != null ?
5568                                intents[intents.length - 1] : null);
5569                    }
5570                    if (intents != null) {
5571                        intents[intents.length-1] = rec.key.requestIntent;
5572                        rec.key.allIntents = intents;
5573                        rec.key.allResolvedTypes = resolvedTypes;
5574                    } else {
5575                        rec.key.allIntents = null;
5576                        rec.key.allResolvedTypes = null;
5577                    }
5578                }
5579                return rec;
5580            }
5581            rec.canceled = true;
5582            mIntentSenderRecords.remove(key);
5583        }
5584        if (noCreate) {
5585            return rec;
5586        }
5587        rec = new PendingIntentRecord(this, key, callingUid);
5588        mIntentSenderRecords.put(key, rec.ref);
5589        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5590            if (activity.pendingResults == null) {
5591                activity.pendingResults
5592                        = new HashSet<WeakReference<PendingIntentRecord>>();
5593            }
5594            activity.pendingResults.add(rec.ref);
5595        }
5596        return rec;
5597    }
5598
5599    @Override
5600    public void cancelIntentSender(IIntentSender sender) {
5601        if (!(sender instanceof PendingIntentRecord)) {
5602            return;
5603        }
5604        synchronized(this) {
5605            PendingIntentRecord rec = (PendingIntentRecord)sender;
5606            try {
5607                int uid = AppGlobals.getPackageManager()
5608                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5609                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5610                    String msg = "Permission Denial: cancelIntentSender() from pid="
5611                        + Binder.getCallingPid()
5612                        + ", uid=" + Binder.getCallingUid()
5613                        + " is not allowed to cancel packges "
5614                        + rec.key.packageName;
5615                    Slog.w(TAG, msg);
5616                    throw new SecurityException(msg);
5617                }
5618            } catch (RemoteException e) {
5619                throw new SecurityException(e);
5620            }
5621            cancelIntentSenderLocked(rec, true);
5622        }
5623    }
5624
5625    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5626        rec.canceled = true;
5627        mIntentSenderRecords.remove(rec.key);
5628        if (cleanActivity && rec.key.activity != null) {
5629            rec.key.activity.pendingResults.remove(rec.ref);
5630        }
5631    }
5632
5633    @Override
5634    public String getPackageForIntentSender(IIntentSender pendingResult) {
5635        if (!(pendingResult instanceof PendingIntentRecord)) {
5636            return null;
5637        }
5638        try {
5639            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5640            return res.key.packageName;
5641        } catch (ClassCastException e) {
5642        }
5643        return null;
5644    }
5645
5646    @Override
5647    public int getUidForIntentSender(IIntentSender sender) {
5648        if (sender instanceof PendingIntentRecord) {
5649            try {
5650                PendingIntentRecord res = (PendingIntentRecord)sender;
5651                return res.uid;
5652            } catch (ClassCastException e) {
5653            }
5654        }
5655        return -1;
5656    }
5657
5658    @Override
5659    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5660        if (!(pendingResult instanceof PendingIntentRecord)) {
5661            return false;
5662        }
5663        try {
5664            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5665            if (res.key.allIntents == null) {
5666                return false;
5667            }
5668            for (int i=0; i<res.key.allIntents.length; i++) {
5669                Intent intent = res.key.allIntents[i];
5670                if (intent.getPackage() != null && intent.getComponent() != null) {
5671                    return false;
5672                }
5673            }
5674            return true;
5675        } catch (ClassCastException e) {
5676        }
5677        return false;
5678    }
5679
5680    @Override
5681    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5682        if (!(pendingResult instanceof PendingIntentRecord)) {
5683            return false;
5684        }
5685        try {
5686            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5687            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5688                return true;
5689            }
5690            return false;
5691        } catch (ClassCastException e) {
5692        }
5693        return false;
5694    }
5695
5696    @Override
5697    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5698        if (!(pendingResult instanceof PendingIntentRecord)) {
5699            return null;
5700        }
5701        try {
5702            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5703            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5704        } catch (ClassCastException e) {
5705        }
5706        return null;
5707    }
5708
5709    @Override
5710    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5711        if (!(pendingResult instanceof PendingIntentRecord)) {
5712            return null;
5713        }
5714        try {
5715            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5716            Intent intent = res.key.requestIntent;
5717            if (intent != null) {
5718                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5719                        || res.lastTagPrefix.equals(prefix))) {
5720                    return res.lastTag;
5721                }
5722                res.lastTagPrefix = prefix;
5723                StringBuilder sb = new StringBuilder(128);
5724                if (prefix != null) {
5725                    sb.append(prefix);
5726                }
5727                if (intent.getAction() != null) {
5728                    sb.append(intent.getAction());
5729                } else if (intent.getComponent() != null) {
5730                    intent.getComponent().appendShortString(sb);
5731                } else {
5732                    sb.append("?");
5733                }
5734                return res.lastTag = sb.toString();
5735            }
5736        } catch (ClassCastException e) {
5737        }
5738        return null;
5739    }
5740
5741    @Override
5742    public void setProcessLimit(int max) {
5743        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5744                "setProcessLimit()");
5745        synchronized (this) {
5746            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5747            mProcessLimitOverride = max;
5748        }
5749        trimApplications();
5750    }
5751
5752    @Override
5753    public int getProcessLimit() {
5754        synchronized (this) {
5755            return mProcessLimitOverride;
5756        }
5757    }
5758
5759    void foregroundTokenDied(ForegroundToken token) {
5760        synchronized (ActivityManagerService.this) {
5761            synchronized (mPidsSelfLocked) {
5762                ForegroundToken cur
5763                    = mForegroundProcesses.get(token.pid);
5764                if (cur != token) {
5765                    return;
5766                }
5767                mForegroundProcesses.remove(token.pid);
5768                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5769                if (pr == null) {
5770                    return;
5771                }
5772                pr.forcingToForeground = null;
5773                updateProcessForegroundLocked(pr, false, false);
5774            }
5775            updateOomAdjLocked();
5776        }
5777    }
5778
5779    @Override
5780    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5781        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5782                "setProcessForeground()");
5783        synchronized(this) {
5784            boolean changed = false;
5785
5786            synchronized (mPidsSelfLocked) {
5787                ProcessRecord pr = mPidsSelfLocked.get(pid);
5788                if (pr == null && isForeground) {
5789                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5790                    return;
5791                }
5792                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5793                if (oldToken != null) {
5794                    oldToken.token.unlinkToDeath(oldToken, 0);
5795                    mForegroundProcesses.remove(pid);
5796                    if (pr != null) {
5797                        pr.forcingToForeground = null;
5798                    }
5799                    changed = true;
5800                }
5801                if (isForeground && token != null) {
5802                    ForegroundToken newToken = new ForegroundToken() {
5803                        @Override
5804                        public void binderDied() {
5805                            foregroundTokenDied(this);
5806                        }
5807                    };
5808                    newToken.pid = pid;
5809                    newToken.token = token;
5810                    try {
5811                        token.linkToDeath(newToken, 0);
5812                        mForegroundProcesses.put(pid, newToken);
5813                        pr.forcingToForeground = token;
5814                        changed = true;
5815                    } catch (RemoteException e) {
5816                        // If the process died while doing this, we will later
5817                        // do the cleanup with the process death link.
5818                    }
5819                }
5820            }
5821
5822            if (changed) {
5823                updateOomAdjLocked();
5824            }
5825        }
5826    }
5827
5828    // =========================================================
5829    // PERMISSIONS
5830    // =========================================================
5831
5832    static class PermissionController extends IPermissionController.Stub {
5833        ActivityManagerService mActivityManagerService;
5834        PermissionController(ActivityManagerService activityManagerService) {
5835            mActivityManagerService = activityManagerService;
5836        }
5837
5838        @Override
5839        public boolean checkPermission(String permission, int pid, int uid) {
5840            return mActivityManagerService.checkPermission(permission, pid,
5841                    uid) == PackageManager.PERMISSION_GRANTED;
5842        }
5843    }
5844
5845    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5846        @Override
5847        public int checkComponentPermission(String permission, int pid, int uid,
5848                int owningUid, boolean exported) {
5849            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5850                    owningUid, exported);
5851        }
5852
5853        @Override
5854        public Object getAMSLock() {
5855            return ActivityManagerService.this;
5856        }
5857    }
5858
5859    /**
5860     * This can be called with or without the global lock held.
5861     */
5862    int checkComponentPermission(String permission, int pid, int uid,
5863            int owningUid, boolean exported) {
5864        // We might be performing an operation on behalf of an indirect binder
5865        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5866        // client identity accordingly before proceeding.
5867        Identity tlsIdentity = sCallerIdentity.get();
5868        if (tlsIdentity != null) {
5869            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5870                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5871            uid = tlsIdentity.uid;
5872            pid = tlsIdentity.pid;
5873        }
5874
5875        if (pid == MY_PID) {
5876            return PackageManager.PERMISSION_GRANTED;
5877        }
5878
5879        return ActivityManager.checkComponentPermission(permission, uid,
5880                owningUid, exported);
5881    }
5882
5883    /**
5884     * As the only public entry point for permissions checking, this method
5885     * can enforce the semantic that requesting a check on a null global
5886     * permission is automatically denied.  (Internally a null permission
5887     * string is used when calling {@link #checkComponentPermission} in cases
5888     * when only uid-based security is needed.)
5889     *
5890     * This can be called with or without the global lock held.
5891     */
5892    @Override
5893    public int checkPermission(String permission, int pid, int uid) {
5894        if (permission == null) {
5895            return PackageManager.PERMISSION_DENIED;
5896        }
5897        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5898    }
5899
5900    /**
5901     * Binder IPC calls go through the public entry point.
5902     * This can be called with or without the global lock held.
5903     */
5904    int checkCallingPermission(String permission) {
5905        return checkPermission(permission,
5906                Binder.getCallingPid(),
5907                UserHandle.getAppId(Binder.getCallingUid()));
5908    }
5909
5910    /**
5911     * This can be called with or without the global lock held.
5912     */
5913    void enforceCallingPermission(String permission, String func) {
5914        if (checkCallingPermission(permission)
5915                == PackageManager.PERMISSION_GRANTED) {
5916            return;
5917        }
5918
5919        String msg = "Permission Denial: " + func + " from pid="
5920                + Binder.getCallingPid()
5921                + ", uid=" + Binder.getCallingUid()
5922                + " requires " + permission;
5923        Slog.w(TAG, msg);
5924        throw new SecurityException(msg);
5925    }
5926
5927    /**
5928     * Determine if UID is holding permissions required to access {@link Uri} in
5929     * the given {@link ProviderInfo}. Final permission checking is always done
5930     * in {@link ContentProvider}.
5931     */
5932    private final boolean checkHoldingPermissionsLocked(
5933            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
5934        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5935                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5936
5937        if (pi.applicationInfo.uid == uid) {
5938            return true;
5939        } else if (!pi.exported) {
5940            return false;
5941        }
5942
5943        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5944        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5945        try {
5946            // check if target holds top-level <provider> permissions
5947            if (!readMet && pi.readPermission != null
5948                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5949                readMet = true;
5950            }
5951            if (!writeMet && pi.writePermission != null
5952                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5953                writeMet = true;
5954            }
5955
5956            // track if unprotected read/write is allowed; any denied
5957            // <path-permission> below removes this ability
5958            boolean allowDefaultRead = pi.readPermission == null;
5959            boolean allowDefaultWrite = pi.writePermission == null;
5960
5961            // check if target holds any <path-permission> that match uri
5962            final PathPermission[] pps = pi.pathPermissions;
5963            if (pps != null) {
5964                final String path = uri.getPath();
5965                int i = pps.length;
5966                while (i > 0 && (!readMet || !writeMet)) {
5967                    i--;
5968                    PathPermission pp = pps[i];
5969                    if (pp.match(path)) {
5970                        if (!readMet) {
5971                            final String pprperm = pp.getReadPermission();
5972                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5973                                    + pprperm + " for " + pp.getPath()
5974                                    + ": match=" + pp.match(path)
5975                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5976                            if (pprperm != null) {
5977                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5978                                    readMet = true;
5979                                } else {
5980                                    allowDefaultRead = false;
5981                                }
5982                            }
5983                        }
5984                        if (!writeMet) {
5985                            final String ppwperm = pp.getWritePermission();
5986                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5987                                    + ppwperm + " for " + pp.getPath()
5988                                    + ": match=" + pp.match(path)
5989                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5990                            if (ppwperm != null) {
5991                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5992                                    writeMet = true;
5993                                } else {
5994                                    allowDefaultWrite = false;
5995                                }
5996                            }
5997                        }
5998                    }
5999                }
6000            }
6001
6002            // grant unprotected <provider> read/write, if not blocked by
6003            // <path-permission> above
6004            if (allowDefaultRead) readMet = true;
6005            if (allowDefaultWrite) writeMet = true;
6006
6007        } catch (RemoteException e) {
6008            return false;
6009        }
6010
6011        return readMet && writeMet;
6012    }
6013
6014    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6015        ProviderInfo pi = null;
6016        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6017        if (cpr != null) {
6018            pi = cpr.info;
6019        } else {
6020            try {
6021                pi = AppGlobals.getPackageManager().resolveContentProvider(
6022                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6023            } catch (RemoteException ex) {
6024            }
6025        }
6026        return pi;
6027    }
6028
6029    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
6030        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6031        if (targetUris != null) {
6032            return targetUris.get(uri);
6033        }
6034        return null;
6035    }
6036
6037    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6038            String targetPkg, int targetUid, GrantUri uri) {
6039        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6040        if (targetUris == null) {
6041            targetUris = Maps.newArrayMap();
6042            mGrantedUriPermissions.put(targetUid, targetUris);
6043        }
6044
6045        UriPermission perm = targetUris.get(uri);
6046        if (perm == null) {
6047            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
6048            targetUris.put(uri, perm);
6049        }
6050
6051        return perm;
6052    }
6053
6054    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6055        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6056        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6057                : UriPermission.STRENGTH_OWNED;
6058
6059        // Root gets to do everything.
6060        if (uid == 0) {
6061            return true;
6062        }
6063
6064        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6065        if (perms == null) return false;
6066
6067        // First look for exact match
6068        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6069        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6070            return true;
6071        }
6072
6073        // No exact match, look for prefixes
6074        final int N = perms.size();
6075        for (int i = 0; i < N; i++) {
6076            final UriPermission perm = perms.valueAt(i);
6077            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6078                    && perm.getStrength(modeFlags) >= minStrength) {
6079                return true;
6080            }
6081        }
6082
6083        return false;
6084    }
6085
6086    @Override
6087    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6088        enforceNotIsolatedCaller("checkUriPermission");
6089
6090        // Another redirected-binder-call permissions check as in
6091        // {@link checkComponentPermission}.
6092        Identity tlsIdentity = sCallerIdentity.get();
6093        if (tlsIdentity != null) {
6094            uid = tlsIdentity.uid;
6095            pid = tlsIdentity.pid;
6096        }
6097
6098        // Our own process gets to do everything.
6099        if (pid == MY_PID) {
6100            return PackageManager.PERMISSION_GRANTED;
6101        }
6102        synchronized (this) {
6103            return checkUriPermissionLocked(uri, uid, modeFlags)
6104                    ? PackageManager.PERMISSION_GRANTED
6105                    : PackageManager.PERMISSION_DENIED;
6106        }
6107    }
6108
6109    /**
6110     * Check if the targetPkg can be granted permission to access uri by
6111     * the callingUid using the given modeFlags.  Throws a security exception
6112     * if callingUid is not allowed to do this.  Returns the uid of the target
6113     * if the URI permission grant should be performed; returns -1 if it is not
6114     * needed (for example targetPkg already has permission to access the URI).
6115     * If you already know the uid of the target, you can supply it in
6116     * lastTargetUid else set that to -1.
6117     */
6118    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6119            Uri uri, final int modeFlags, int lastTargetUid) {
6120        if (!Intent.isAccessUriMode(modeFlags)) {
6121            return -1;
6122        }
6123
6124        if (targetPkg != null) {
6125            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6126                    "Checking grant " + targetPkg + " permission to " + uri);
6127        }
6128
6129        final IPackageManager pm = AppGlobals.getPackageManager();
6130
6131        // If this is not a content: uri, we can't do anything with it.
6132        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6133            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6134                    "Can't grant URI permission for non-content URI: " + uri);
6135            return -1;
6136        }
6137
6138        final String authority = uri.getAuthority();
6139        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6140        if (pi == null) {
6141            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6142            return -1;
6143        }
6144
6145        int targetUid = lastTargetUid;
6146        if (targetUid < 0 && targetPkg != null) {
6147            try {
6148                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6149                if (targetUid < 0) {
6150                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6151                            "Can't grant URI permission no uid for: " + targetPkg);
6152                    return -1;
6153                }
6154            } catch (RemoteException ex) {
6155                return -1;
6156            }
6157        }
6158
6159        if (targetUid >= 0) {
6160            // First...  does the target actually need this permission?
6161            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6162                // No need to grant the target this permission.
6163                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6164                        "Target " + targetPkg + " already has full permission to " + uri);
6165                return -1;
6166            }
6167        } else {
6168            // First...  there is no target package, so can anyone access it?
6169            boolean allowed = pi.exported;
6170            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6171                if (pi.readPermission != null) {
6172                    allowed = false;
6173                }
6174            }
6175            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6176                if (pi.writePermission != null) {
6177                    allowed = false;
6178                }
6179            }
6180            if (allowed) {
6181                return -1;
6182            }
6183        }
6184
6185        // Second...  is the provider allowing granting of URI permissions?
6186        if (!pi.grantUriPermissions) {
6187            throw new SecurityException("Provider " + pi.packageName
6188                    + "/" + pi.name
6189                    + " does not allow granting of Uri permissions (uri "
6190                    + uri + ")");
6191        }
6192        if (pi.uriPermissionPatterns != null) {
6193            final int N = pi.uriPermissionPatterns.length;
6194            boolean allowed = false;
6195            for (int i=0; i<N; i++) {
6196                if (pi.uriPermissionPatterns[i] != null
6197                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6198                    allowed = true;
6199                    break;
6200                }
6201            }
6202            if (!allowed) {
6203                throw new SecurityException("Provider " + pi.packageName
6204                        + "/" + pi.name
6205                        + " does not allow granting of permission to path of Uri "
6206                        + uri);
6207            }
6208        }
6209
6210        // Third...  does the caller itself have permission to access
6211        // this uri?
6212        if (callingUid != Process.myUid()) {
6213            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6214                // Require they hold a strong enough Uri permission
6215                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6216                    throw new SecurityException("Uid " + callingUid
6217                            + " does not have permission to uri " + uri);
6218                }
6219            }
6220        }
6221
6222        return targetUid;
6223    }
6224
6225    @Override
6226    public int checkGrantUriPermission(int callingUid, String targetPkg,
6227            Uri uri, final int modeFlags) {
6228        enforceNotIsolatedCaller("checkGrantUriPermission");
6229        synchronized(this) {
6230            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6231        }
6232    }
6233
6234    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6235            final int modeFlags, UriPermissionOwner owner) {
6236        if (!Intent.isAccessUriMode(modeFlags)) {
6237            return;
6238        }
6239
6240        // So here we are: the caller has the assumed permission
6241        // to the uri, and the target doesn't.  Let's now give this to
6242        // the target.
6243
6244        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6245                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6246
6247        final String authority = uri.getAuthority();
6248        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6249        if (pi == null) {
6250            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6251            return;
6252        }
6253
6254        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6255        final UriPermission perm = findOrCreateUriPermissionLocked(
6256                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6257        perm.grantModes(modeFlags, owner);
6258    }
6259
6260    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6261            final int modeFlags, UriPermissionOwner owner) {
6262        if (targetPkg == null) {
6263            throw new NullPointerException("targetPkg");
6264        }
6265
6266        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6267        if (targetUid < 0) {
6268            return;
6269        }
6270
6271        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6272    }
6273
6274    static class NeededUriGrants extends ArrayList<Uri> {
6275        final String targetPkg;
6276        final int targetUid;
6277        final int flags;
6278
6279        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6280            this.targetPkg = targetPkg;
6281            this.targetUid = targetUid;
6282            this.flags = flags;
6283        }
6284    }
6285
6286    /**
6287     * Like checkGrantUriPermissionLocked, but takes an Intent.
6288     */
6289    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6290            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6291        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6292                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6293                + " clip=" + (intent != null ? intent.getClipData() : null)
6294                + " from " + intent + "; flags=0x"
6295                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6296
6297        if (targetPkg == null) {
6298            throw new NullPointerException("targetPkg");
6299        }
6300
6301        if (intent == null) {
6302            return null;
6303        }
6304        Uri data = intent.getData();
6305        ClipData clip = intent.getClipData();
6306        if (data == null && clip == null) {
6307            return null;
6308        }
6309
6310        if (data != null) {
6311            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6312                mode, needed != null ? needed.targetUid : -1);
6313            if (targetUid > 0) {
6314                if (needed == null) {
6315                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6316                }
6317                needed.add(data);
6318            }
6319        }
6320        if (clip != null) {
6321            for (int i=0; i<clip.getItemCount(); i++) {
6322                Uri uri = clip.getItemAt(i).getUri();
6323                if (uri != null) {
6324                    int targetUid = -1;
6325                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6326                            mode, needed != null ? needed.targetUid : -1);
6327                    if (targetUid > 0) {
6328                        if (needed == null) {
6329                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6330                        }
6331                        needed.add(uri);
6332                    }
6333                } else {
6334                    Intent clipIntent = clip.getItemAt(i).getIntent();
6335                    if (clipIntent != null) {
6336                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6337                                callingUid, targetPkg, clipIntent, mode, needed);
6338                        if (newNeeded != null) {
6339                            needed = newNeeded;
6340                        }
6341                    }
6342                }
6343            }
6344        }
6345
6346        return needed;
6347    }
6348
6349    /**
6350     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6351     */
6352    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6353            UriPermissionOwner owner) {
6354        if (needed != null) {
6355            for (int i=0; i<needed.size(); i++) {
6356                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6357                        needed.get(i), needed.flags, owner);
6358            }
6359        }
6360    }
6361
6362    void grantUriPermissionFromIntentLocked(int callingUid,
6363            String targetPkg, Intent intent, UriPermissionOwner owner) {
6364        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6365                intent, intent != null ? intent.getFlags() : 0, null);
6366        if (needed == null) {
6367            return;
6368        }
6369
6370        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6371    }
6372
6373    @Override
6374    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6375            Uri uri, final int modeFlags) {
6376        enforceNotIsolatedCaller("grantUriPermission");
6377        synchronized(this) {
6378            final ProcessRecord r = getRecordForAppLocked(caller);
6379            if (r == null) {
6380                throw new SecurityException("Unable to find app for caller "
6381                        + caller
6382                        + " when granting permission to uri " + uri);
6383            }
6384            if (targetPkg == null) {
6385                throw new IllegalArgumentException("null target");
6386            }
6387            if (uri == null) {
6388                throw new IllegalArgumentException("null uri");
6389            }
6390
6391            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6392                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6393                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6394                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6395
6396            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6397        }
6398    }
6399
6400    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6401        if (perm.modeFlags == 0) {
6402            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6403                    perm.targetUid);
6404            if (perms != null) {
6405                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6406                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6407
6408                perms.remove(perm.uri);
6409                if (perms.isEmpty()) {
6410                    mGrantedUriPermissions.remove(perm.targetUid);
6411                }
6412            }
6413        }
6414    }
6415
6416    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6417        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6418
6419        final IPackageManager pm = AppGlobals.getPackageManager();
6420        final String authority = uri.getAuthority();
6421        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6422        if (pi == null) {
6423            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6424            return;
6425        }
6426
6427        // Does the caller have this permission on the URI?
6428        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6429            // Right now, if you are not the original owner of the permission,
6430            // you are not allowed to revoke it.
6431            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6432                throw new SecurityException("Uid " + callingUid
6433                        + " does not have permission to uri " + uri);
6434            //}
6435        }
6436
6437        boolean persistChanged = false;
6438
6439        // Go through all of the permissions and remove any that match.
6440        int N = mGrantedUriPermissions.size();
6441        for (int i = 0; i < N; i++) {
6442            final int targetUid = mGrantedUriPermissions.keyAt(i);
6443            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6444
6445            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6446                final UriPermission perm = it.next();
6447                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6448                    if (DEBUG_URI_PERMISSION)
6449                        Slog.v(TAG,
6450                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6451                    persistChanged |= perm.revokeModes(
6452                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6453                    if (perm.modeFlags == 0) {
6454                        it.remove();
6455                    }
6456                }
6457            }
6458
6459            if (perms.isEmpty()) {
6460                mGrantedUriPermissions.remove(targetUid);
6461                N--;
6462                i--;
6463            }
6464        }
6465
6466        if (persistChanged) {
6467            schedulePersistUriGrants();
6468        }
6469    }
6470
6471    @Override
6472    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6473            final int modeFlags) {
6474        enforceNotIsolatedCaller("revokeUriPermission");
6475        synchronized(this) {
6476            final ProcessRecord r = getRecordForAppLocked(caller);
6477            if (r == null) {
6478                throw new SecurityException("Unable to find app for caller "
6479                        + caller
6480                        + " when revoking permission to uri " + uri);
6481            }
6482            if (uri == null) {
6483                Slog.w(TAG, "revokeUriPermission: null uri");
6484                return;
6485            }
6486
6487            if (!Intent.isAccessUriMode(modeFlags)) {
6488                return;
6489            }
6490
6491            final IPackageManager pm = AppGlobals.getPackageManager();
6492            final String authority = uri.getAuthority();
6493            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6494            if (pi == null) {
6495                Slog.w(TAG, "No content provider found for permission revoke: "
6496                        + uri.toSafeString());
6497                return;
6498            }
6499
6500            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6501        }
6502    }
6503
6504    /**
6505     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6506     * given package.
6507     *
6508     * @param packageName Package name to match, or {@code null} to apply to all
6509     *            packages.
6510     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6511     *            to all users.
6512     * @param persistable If persistable grants should be removed.
6513     */
6514    private void removeUriPermissionsForPackageLocked(
6515            String packageName, int userHandle, boolean persistable) {
6516        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6517            throw new IllegalArgumentException("Must narrow by either package or user");
6518        }
6519
6520        boolean persistChanged = false;
6521
6522        int N = mGrantedUriPermissions.size();
6523        for (int i = 0; i < N; i++) {
6524            final int targetUid = mGrantedUriPermissions.keyAt(i);
6525            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6526
6527            // Only inspect grants matching user
6528            if (userHandle == UserHandle.USER_ALL
6529                    || userHandle == UserHandle.getUserId(targetUid)) {
6530                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6531                    final UriPermission perm = it.next();
6532
6533                    // Only inspect grants matching package
6534                    if (packageName == null || perm.sourcePkg.equals(packageName)
6535                            || perm.targetPkg.equals(packageName)) {
6536                        persistChanged |= perm.revokeModes(
6537                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6538
6539                        // Only remove when no modes remain; any persisted grants
6540                        // will keep this alive.
6541                        if (perm.modeFlags == 0) {
6542                            it.remove();
6543                        }
6544                    }
6545                }
6546
6547                if (perms.isEmpty()) {
6548                    mGrantedUriPermissions.remove(targetUid);
6549                    N--;
6550                    i--;
6551                }
6552            }
6553        }
6554
6555        if (persistChanged) {
6556            schedulePersistUriGrants();
6557        }
6558    }
6559
6560    @Override
6561    public IBinder newUriPermissionOwner(String name) {
6562        enforceNotIsolatedCaller("newUriPermissionOwner");
6563        synchronized(this) {
6564            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6565            return owner.getExternalTokenLocked();
6566        }
6567    }
6568
6569    @Override
6570    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6571            Uri uri, final int modeFlags) {
6572        synchronized(this) {
6573            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6574            if (owner == null) {
6575                throw new IllegalArgumentException("Unknown owner: " + token);
6576            }
6577            if (fromUid != Binder.getCallingUid()) {
6578                if (Binder.getCallingUid() != Process.myUid()) {
6579                    // Only system code can grant URI permissions on behalf
6580                    // of other users.
6581                    throw new SecurityException("nice try");
6582                }
6583            }
6584            if (targetPkg == null) {
6585                throw new IllegalArgumentException("null target");
6586            }
6587            if (uri == null) {
6588                throw new IllegalArgumentException("null uri");
6589            }
6590
6591            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6592        }
6593    }
6594
6595    @Override
6596    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6597        synchronized(this) {
6598            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6599            if (owner == null) {
6600                throw new IllegalArgumentException("Unknown owner: " + token);
6601            }
6602
6603            if (uri == null) {
6604                owner.removeUriPermissionsLocked(mode);
6605            } else {
6606                owner.removeUriPermissionLocked(uri, mode);
6607            }
6608        }
6609    }
6610
6611    private void schedulePersistUriGrants() {
6612        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6613            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6614                    10 * DateUtils.SECOND_IN_MILLIS);
6615        }
6616    }
6617
6618    private void writeGrantedUriPermissions() {
6619        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6620
6621        // Snapshot permissions so we can persist without lock
6622        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6623        synchronized (this) {
6624            final int size = mGrantedUriPermissions.size();
6625            for (int i = 0; i < size; i++) {
6626                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6627                for (UriPermission perm : perms.values()) {
6628                    if (perm.persistedModeFlags != 0) {
6629                        persist.add(perm.snapshot());
6630                    }
6631                }
6632            }
6633        }
6634
6635        FileOutputStream fos = null;
6636        try {
6637            fos = mGrantFile.startWrite();
6638
6639            XmlSerializer out = new FastXmlSerializer();
6640            out.setOutput(fos, "utf-8");
6641            out.startDocument(null, true);
6642            out.startTag(null, TAG_URI_GRANTS);
6643            for (UriPermission.Snapshot perm : persist) {
6644                out.startTag(null, TAG_URI_GRANT);
6645                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6646                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6647                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6648                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6649                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6650                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6651                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6652                out.endTag(null, TAG_URI_GRANT);
6653            }
6654            out.endTag(null, TAG_URI_GRANTS);
6655            out.endDocument();
6656
6657            mGrantFile.finishWrite(fos);
6658        } catch (IOException e) {
6659            if (fos != null) {
6660                mGrantFile.failWrite(fos);
6661            }
6662        }
6663    }
6664
6665    private void readGrantedUriPermissionsLocked() {
6666        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6667
6668        final long now = System.currentTimeMillis();
6669
6670        FileInputStream fis = null;
6671        try {
6672            fis = mGrantFile.openRead();
6673            final XmlPullParser in = Xml.newPullParser();
6674            in.setInput(fis, null);
6675
6676            int type;
6677            while ((type = in.next()) != END_DOCUMENT) {
6678                final String tag = in.getName();
6679                if (type == START_TAG) {
6680                    if (TAG_URI_GRANT.equals(tag)) {
6681                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6682                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6683                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6684                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6685                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6686                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6687                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6688
6689                        // Sanity check that provider still belongs to source package
6690                        final ProviderInfo pi = getProviderInfoLocked(
6691                                uri.getAuthority(), userHandle);
6692                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6693                            int targetUid = -1;
6694                            try {
6695                                targetUid = AppGlobals.getPackageManager()
6696                                        .getPackageUid(targetPkg, userHandle);
6697                            } catch (RemoteException e) {
6698                            }
6699                            if (targetUid != -1) {
6700                                final UriPermission perm = findOrCreateUriPermissionLocked(
6701                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6702                                perm.initPersistedModes(modeFlags, createdTime);
6703                            }
6704                        } else {
6705                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6706                                    + " but instead found " + pi);
6707                        }
6708                    }
6709                }
6710            }
6711        } catch (FileNotFoundException e) {
6712            // Missing grants is okay
6713        } catch (IOException e) {
6714            Log.wtf(TAG, "Failed reading Uri grants", e);
6715        } catch (XmlPullParserException e) {
6716            Log.wtf(TAG, "Failed reading Uri grants", e);
6717        } finally {
6718            IoUtils.closeQuietly(fis);
6719        }
6720    }
6721
6722    @Override
6723    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6724        enforceNotIsolatedCaller("takePersistableUriPermission");
6725
6726        Preconditions.checkFlagsArgument(modeFlags,
6727                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6728
6729        synchronized (this) {
6730            final int callingUid = Binder.getCallingUid();
6731            boolean persistChanged = false;
6732
6733            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6734            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6735
6736            final boolean exactValid = (exactPerm != null)
6737                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6738            final boolean prefixValid = (prefixPerm != null)
6739                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6740
6741            if (!(exactValid || prefixValid)) {
6742                throw new SecurityException("No persistable permission grants found for UID "
6743                        + callingUid + " and Uri " + uri.toSafeString());
6744            }
6745
6746            if (exactValid) {
6747                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6748            }
6749            if (prefixValid) {
6750                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6751            }
6752
6753            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6754
6755            if (persistChanged) {
6756                schedulePersistUriGrants();
6757            }
6758        }
6759    }
6760
6761    @Override
6762    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6763        enforceNotIsolatedCaller("releasePersistableUriPermission");
6764
6765        Preconditions.checkFlagsArgument(modeFlags,
6766                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6767
6768        synchronized (this) {
6769            final int callingUid = Binder.getCallingUid();
6770            boolean persistChanged = false;
6771
6772            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6773            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6774            if (exactPerm == null && prefixPerm == null) {
6775                throw new SecurityException("No permission grants found for UID " + callingUid
6776                        + " and Uri " + uri.toSafeString());
6777            }
6778
6779            if (exactPerm != null) {
6780                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6781                removeUriPermissionIfNeededLocked(exactPerm);
6782            }
6783            if (prefixPerm != null) {
6784                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6785                removeUriPermissionIfNeededLocked(prefixPerm);
6786            }
6787
6788            if (persistChanged) {
6789                schedulePersistUriGrants();
6790            }
6791        }
6792    }
6793
6794    /**
6795     * Prune any older {@link UriPermission} for the given UID until outstanding
6796     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6797     *
6798     * @return if any mutations occured that require persisting.
6799     */
6800    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6801        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6802        if (perms == null) return false;
6803        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6804
6805        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6806        for (UriPermission perm : perms.values()) {
6807            if (perm.persistedModeFlags != 0) {
6808                persisted.add(perm);
6809            }
6810        }
6811
6812        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6813        if (trimCount <= 0) return false;
6814
6815        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6816        for (int i = 0; i < trimCount; i++) {
6817            final UriPermission perm = persisted.get(i);
6818
6819            if (DEBUG_URI_PERMISSION) {
6820                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6821            }
6822
6823            perm.releasePersistableModes(~0);
6824            removeUriPermissionIfNeededLocked(perm);
6825        }
6826
6827        return true;
6828    }
6829
6830    @Override
6831    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6832            String packageName, boolean incoming) {
6833        enforceNotIsolatedCaller("getPersistedUriPermissions");
6834        Preconditions.checkNotNull(packageName, "packageName");
6835
6836        final int callingUid = Binder.getCallingUid();
6837        final IPackageManager pm = AppGlobals.getPackageManager();
6838        try {
6839            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6840            if (packageUid != callingUid) {
6841                throw new SecurityException(
6842                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6843            }
6844        } catch (RemoteException e) {
6845            throw new SecurityException("Failed to verify package name ownership");
6846        }
6847
6848        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6849        synchronized (this) {
6850            if (incoming) {
6851                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6852                        callingUid);
6853                if (perms == null) {
6854                    Slog.w(TAG, "No permission grants found for " + packageName);
6855                } else {
6856                    for (UriPermission perm : perms.values()) {
6857                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6858                            result.add(perm.buildPersistedPublicApiObject());
6859                        }
6860                    }
6861                }
6862            } else {
6863                final int size = mGrantedUriPermissions.size();
6864                for (int i = 0; i < size; i++) {
6865                    final ArrayMap<GrantUri, UriPermission> perms =
6866                            mGrantedUriPermissions.valueAt(i);
6867                    for (UriPermission perm : perms.values()) {
6868                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6869                            result.add(perm.buildPersistedPublicApiObject());
6870                        }
6871                    }
6872                }
6873            }
6874        }
6875        return new ParceledListSlice<android.content.UriPermission>(result);
6876    }
6877
6878    @Override
6879    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6880        synchronized (this) {
6881            ProcessRecord app =
6882                who != null ? getRecordForAppLocked(who) : null;
6883            if (app == null) return;
6884
6885            Message msg = Message.obtain();
6886            msg.what = WAIT_FOR_DEBUGGER_MSG;
6887            msg.obj = app;
6888            msg.arg1 = waiting ? 1 : 0;
6889            mHandler.sendMessage(msg);
6890        }
6891    }
6892
6893    @Override
6894    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6895        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6896        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6897        outInfo.availMem = Process.getFreeMemory();
6898        outInfo.totalMem = Process.getTotalMemory();
6899        outInfo.threshold = homeAppMem;
6900        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6901        outInfo.hiddenAppThreshold = cachedAppMem;
6902        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6903                ProcessList.SERVICE_ADJ);
6904        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6905                ProcessList.VISIBLE_APP_ADJ);
6906        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6907                ProcessList.FOREGROUND_APP_ADJ);
6908    }
6909
6910    // =========================================================
6911    // TASK MANAGEMENT
6912    // =========================================================
6913
6914    @Override
6915    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6916                         IThumbnailReceiver receiver) {
6917        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6918
6919        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6920        ActivityRecord topRecord = null;
6921
6922        synchronized(this) {
6923            if (localLOGV) Slog.v(
6924                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6925                + ", receiver=" + receiver);
6926
6927            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6928                    != PackageManager.PERMISSION_GRANTED) {
6929                if (receiver != null) {
6930                    // If the caller wants to wait for pending thumbnails,
6931                    // it ain't gonna get them.
6932                    try {
6933                        receiver.finished();
6934                    } catch (RemoteException ex) {
6935                    }
6936                }
6937                String msg = "Permission Denial: getTasks() from pid="
6938                        + Binder.getCallingPid()
6939                        + ", uid=" + Binder.getCallingUid()
6940                        + " requires " + android.Manifest.permission.GET_TASKS;
6941                Slog.w(TAG, msg);
6942                throw new SecurityException(msg);
6943            }
6944
6945            // TODO: Improve with MRU list from all ActivityStacks.
6946            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6947
6948            if (!pending.pendingRecords.isEmpty()) {
6949                mPendingThumbnails.add(pending);
6950            }
6951        }
6952
6953        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6954
6955        if (topRecord != null) {
6956            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6957            try {
6958                IApplicationThread topThumbnail = topRecord.app.thread;
6959                topThumbnail.requestThumbnail(topRecord.appToken);
6960            } catch (Exception e) {
6961                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6962                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6963            }
6964        }
6965
6966        if (pending.pendingRecords.isEmpty() && receiver != null) {
6967            // In this case all thumbnails were available and the client
6968            // is being asked to be told when the remaining ones come in...
6969            // which is unusually, since the top-most currently running
6970            // activity should never have a canned thumbnail!  Oh well.
6971            try {
6972                receiver.finished();
6973            } catch (RemoteException ex) {
6974            }
6975        }
6976
6977        return list;
6978    }
6979
6980    TaskRecord getMostRecentTask() {
6981        return mRecentTasks.get(0);
6982    }
6983
6984    @Override
6985    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6986            int flags, int userId) {
6987        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6988                false, true, "getRecentTasks", null);
6989
6990        synchronized (this) {
6991            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6992                    "getRecentTasks()");
6993            final boolean detailed = checkCallingPermission(
6994                    android.Manifest.permission.GET_DETAILED_TASKS)
6995                    == PackageManager.PERMISSION_GRANTED;
6996
6997            IPackageManager pm = AppGlobals.getPackageManager();
6998
6999            final int N = mRecentTasks.size();
7000            ArrayList<ActivityManager.RecentTaskInfo> res
7001                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7002                            maxNum < N ? maxNum : N);
7003
7004            final Set<Integer> includedUsers;
7005            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7006                includedUsers = getProfileIdsLocked(userId);
7007            } else {
7008                includedUsers = new HashSet<Integer>();
7009            }
7010            includedUsers.add(Integer.valueOf(userId));
7011            for (int i=0; i<N && maxNum > 0; i++) {
7012                TaskRecord tr = mRecentTasks.get(i);
7013                // Only add calling user or related users recent tasks
7014                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7015
7016                // Return the entry if desired by the caller.  We always return
7017                // the first entry, because callers always expect this to be the
7018                // foreground app.  We may filter others if the caller has
7019                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7020                // we should exclude the entry.
7021
7022                if (i == 0
7023                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7024                        || (tr.intent == null)
7025                        || ((tr.intent.getFlags()
7026                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7027                    ActivityManager.RecentTaskInfo rti
7028                            = new ActivityManager.RecentTaskInfo();
7029                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7030                    rti.persistentId = tr.taskId;
7031                    rti.baseIntent = new Intent(
7032                            tr.intent != null ? tr.intent : tr.affinityIntent);
7033                    if (!detailed) {
7034                        rti.baseIntent.replaceExtras((Bundle)null);
7035                    }
7036                    rti.origActivity = tr.origActivity;
7037                    rti.description = tr.lastDescription;
7038                    rti.stackId = tr.stack.mStackId;
7039                    rti.userId = tr.userId;
7040
7041                    // Traverse upwards looking for any break between main task activities and
7042                    // utility activities.
7043                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7044                    int activityNdx;
7045                    final int numActivities = activities.size();
7046                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7047                            ++activityNdx) {
7048                        final ActivityRecord r = activities.get(activityNdx);
7049                        if (r.intent != null &&
7050                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7051                                        != 0) {
7052                            break;
7053                        }
7054                    }
7055                    // Traverse downwards starting below break looking for set label and icon.
7056                    for (--activityNdx; activityNdx >= 0; --activityNdx) {
7057                        final ActivityRecord r = activities.get(activityNdx);
7058                        if (r.activityLabel != null || r.activityIcon != null) {
7059                            rti.activityLabel = r.activityLabel;
7060                            rti.activityIcon = r.activityIcon;
7061                            break;
7062                        }
7063                    }
7064
7065                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7066                        // Check whether this activity is currently available.
7067                        try {
7068                            if (rti.origActivity != null) {
7069                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7070                                        == null) {
7071                                    continue;
7072                                }
7073                            } else if (rti.baseIntent != null) {
7074                                if (pm.queryIntentActivities(rti.baseIntent,
7075                                        null, 0, userId) == null) {
7076                                    continue;
7077                                }
7078                            }
7079                        } catch (RemoteException e) {
7080                            // Will never happen.
7081                        }
7082                    }
7083
7084                    res.add(rti);
7085                    maxNum--;
7086                }
7087            }
7088            return res;
7089        }
7090    }
7091
7092    private TaskRecord recentTaskForIdLocked(int id) {
7093        final int N = mRecentTasks.size();
7094            for (int i=0; i<N; i++) {
7095                TaskRecord tr = mRecentTasks.get(i);
7096                if (tr.taskId == id) {
7097                    return tr;
7098                }
7099            }
7100            return null;
7101    }
7102
7103    @Override
7104    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7105        synchronized (this) {
7106            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7107                    "getTaskThumbnails()");
7108            TaskRecord tr = recentTaskForIdLocked(id);
7109            if (tr != null) {
7110                return tr.getTaskThumbnailsLocked();
7111            }
7112        }
7113        return null;
7114    }
7115
7116    @Override
7117    public Bitmap getTaskTopThumbnail(int id) {
7118        synchronized (this) {
7119            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7120                    "getTaskTopThumbnail()");
7121            TaskRecord tr = recentTaskForIdLocked(id);
7122            if (tr != null) {
7123                return tr.getTaskTopThumbnailLocked();
7124            }
7125        }
7126        return null;
7127    }
7128
7129    @Override
7130    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel,
7131            Bitmap activityIcon) {
7132        synchronized (this) {
7133            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7134            if (r != null) {
7135                r.activityLabel = activityLabel.toString();
7136                r.activityIcon = activityIcon;
7137            }
7138        }
7139    }
7140
7141    @Override
7142    public boolean removeSubTask(int taskId, int subTaskIndex) {
7143        synchronized (this) {
7144            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7145                    "removeSubTask()");
7146            long ident = Binder.clearCallingIdentity();
7147            try {
7148                TaskRecord tr = recentTaskForIdLocked(taskId);
7149                if (tr != null) {
7150                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7151                }
7152                return false;
7153            } finally {
7154                Binder.restoreCallingIdentity(ident);
7155            }
7156        }
7157    }
7158
7159    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7160        if (!pr.killedByAm) {
7161            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7162            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7163                    pr.processName, pr.setAdj, reason);
7164            pr.killedByAm = true;
7165            Process.killProcessQuiet(pr.pid);
7166        }
7167    }
7168
7169    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7170        tr.disposeThumbnail();
7171        mRecentTasks.remove(tr);
7172        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7173        Intent baseIntent = new Intent(
7174                tr.intent != null ? tr.intent : tr.affinityIntent);
7175        ComponentName component = baseIntent.getComponent();
7176        if (component == null) {
7177            Slog.w(TAG, "Now component for base intent of task: " + tr);
7178            return;
7179        }
7180
7181        // Find any running services associated with this app.
7182        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7183
7184        if (killProcesses) {
7185            // Find any running processes associated with this app.
7186            final String pkg = component.getPackageName();
7187            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7188            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7189            for (int i=0; i<pmap.size(); i++) {
7190                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7191                for (int j=0; j<uids.size(); j++) {
7192                    ProcessRecord proc = uids.valueAt(j);
7193                    if (proc.userId != tr.userId) {
7194                        continue;
7195                    }
7196                    if (!proc.pkgList.containsKey(pkg)) {
7197                        continue;
7198                    }
7199                    procs.add(proc);
7200                }
7201            }
7202
7203            // Kill the running processes.
7204            for (int i=0; i<procs.size(); i++) {
7205                ProcessRecord pr = procs.get(i);
7206                if (pr == mHomeProcess) {
7207                    // Don't kill the home process along with tasks from the same package.
7208                    continue;
7209                }
7210                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7211                    killUnneededProcessLocked(pr, "remove task");
7212                } else {
7213                    pr.waitingToKill = "remove task";
7214                }
7215            }
7216        }
7217    }
7218
7219    /**
7220     * Removes the task with the specified task id.
7221     *
7222     * @param taskId Identifier of the task to be removed.
7223     * @param flags Additional operational flags.  May be 0 or
7224     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7225     * @return Returns true if the given task was found and removed.
7226     */
7227    private boolean removeTaskByIdLocked(int taskId, int flags) {
7228        TaskRecord tr = recentTaskForIdLocked(taskId);
7229        if (tr != null) {
7230            tr.removeTaskActivitiesLocked(-1, false);
7231            cleanUpRemovedTaskLocked(tr, flags);
7232            return true;
7233        }
7234        return false;
7235    }
7236
7237    @Override
7238    public boolean removeTask(int taskId, int flags) {
7239        synchronized (this) {
7240            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7241                    "removeTask()");
7242            long ident = Binder.clearCallingIdentity();
7243            try {
7244                return removeTaskByIdLocked(taskId, flags);
7245            } finally {
7246                Binder.restoreCallingIdentity(ident);
7247            }
7248        }
7249    }
7250
7251    /**
7252     * TODO: Add mController hook
7253     */
7254    @Override
7255    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7256        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7257                "moveTaskToFront()");
7258
7259        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7260        synchronized(this) {
7261            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7262                    Binder.getCallingUid(), "Task to front")) {
7263                ActivityOptions.abort(options);
7264                return;
7265            }
7266            final long origId = Binder.clearCallingIdentity();
7267            try {
7268                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7269                if (task == null) {
7270                    return;
7271                }
7272                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7273                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7274                    return;
7275                }
7276                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7277            } finally {
7278                Binder.restoreCallingIdentity(origId);
7279            }
7280            ActivityOptions.abort(options);
7281        }
7282    }
7283
7284    @Override
7285    public void moveTaskToBack(int taskId) {
7286        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7287                "moveTaskToBack()");
7288
7289        synchronized(this) {
7290            TaskRecord tr = recentTaskForIdLocked(taskId);
7291            if (tr != null) {
7292                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7293                ActivityStack stack = tr.stack;
7294                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7295                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7296                            Binder.getCallingUid(), "Task to back")) {
7297                        return;
7298                    }
7299                }
7300                final long origId = Binder.clearCallingIdentity();
7301                try {
7302                    stack.moveTaskToBackLocked(taskId, null);
7303                } finally {
7304                    Binder.restoreCallingIdentity(origId);
7305                }
7306            }
7307        }
7308    }
7309
7310    /**
7311     * Moves an activity, and all of the other activities within the same task, to the bottom
7312     * of the history stack.  The activity's order within the task is unchanged.
7313     *
7314     * @param token A reference to the activity we wish to move
7315     * @param nonRoot If false then this only works if the activity is the root
7316     *                of a task; if true it will work for any activity in a task.
7317     * @return Returns true if the move completed, false if not.
7318     */
7319    @Override
7320    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7321        enforceNotIsolatedCaller("moveActivityTaskToBack");
7322        synchronized(this) {
7323            final long origId = Binder.clearCallingIdentity();
7324            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7325            if (taskId >= 0) {
7326                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7327            }
7328            Binder.restoreCallingIdentity(origId);
7329        }
7330        return false;
7331    }
7332
7333    @Override
7334    public void moveTaskBackwards(int task) {
7335        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7336                "moveTaskBackwards()");
7337
7338        synchronized(this) {
7339            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7340                    Binder.getCallingUid(), "Task backwards")) {
7341                return;
7342            }
7343            final long origId = Binder.clearCallingIdentity();
7344            moveTaskBackwardsLocked(task);
7345            Binder.restoreCallingIdentity(origId);
7346        }
7347    }
7348
7349    private final void moveTaskBackwardsLocked(int task) {
7350        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7351    }
7352
7353    @Override
7354    public IBinder getHomeActivityToken() throws RemoteException {
7355        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7356                "getHomeActivityToken()");
7357        synchronized (this) {
7358            return mStackSupervisor.getHomeActivityToken();
7359        }
7360    }
7361
7362    @Override
7363    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7364            IActivityContainerCallback callback) throws RemoteException {
7365        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7366                "createActivityContainer()");
7367        synchronized (this) {
7368            if (parentActivityToken == null) {
7369                throw new IllegalArgumentException("parent token must not be null");
7370            }
7371            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7372            if (r == null) {
7373                return null;
7374            }
7375            if (callback == null) {
7376                throw new IllegalArgumentException("callback must not be null");
7377            }
7378            return mStackSupervisor.createActivityContainer(r, callback);
7379        }
7380    }
7381
7382    @Override
7383    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7384        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7385                "deleteActivityContainer()");
7386        synchronized (this) {
7387            mStackSupervisor.deleteActivityContainer(container);
7388        }
7389    }
7390
7391    @Override
7392    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7393            throws RemoteException {
7394        synchronized (this) {
7395            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7396            if (stack != null) {
7397                return stack.mActivityContainer;
7398            }
7399            return null;
7400        }
7401    }
7402
7403    @Override
7404    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7405        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7406                "moveTaskToStack()");
7407        if (stackId == HOME_STACK_ID) {
7408            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7409                    new RuntimeException("here").fillInStackTrace());
7410        }
7411        synchronized (this) {
7412            long ident = Binder.clearCallingIdentity();
7413            try {
7414                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7415                        + stackId + " toTop=" + toTop);
7416                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7417            } finally {
7418                Binder.restoreCallingIdentity(ident);
7419            }
7420        }
7421    }
7422
7423    @Override
7424    public void resizeStack(int stackBoxId, Rect bounds) {
7425        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7426                "resizeStackBox()");
7427        long ident = Binder.clearCallingIdentity();
7428        try {
7429            mWindowManager.resizeStack(stackBoxId, bounds);
7430        } finally {
7431            Binder.restoreCallingIdentity(ident);
7432        }
7433    }
7434
7435    @Override
7436    public List<StackInfo> getAllStackInfos() {
7437        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7438                "getAllStackInfos()");
7439        long ident = Binder.clearCallingIdentity();
7440        try {
7441            synchronized (this) {
7442                return mStackSupervisor.getAllStackInfosLocked();
7443            }
7444        } finally {
7445            Binder.restoreCallingIdentity(ident);
7446        }
7447    }
7448
7449    @Override
7450    public StackInfo getStackInfo(int stackId) {
7451        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7452                "getStackInfo()");
7453        long ident = Binder.clearCallingIdentity();
7454        try {
7455            synchronized (this) {
7456                return mStackSupervisor.getStackInfoLocked(stackId);
7457            }
7458        } finally {
7459            Binder.restoreCallingIdentity(ident);
7460        }
7461    }
7462
7463    @Override
7464    public boolean isInHomeStack(int taskId) {
7465        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7466                "getStackInfo()");
7467        long ident = Binder.clearCallingIdentity();
7468        try {
7469            synchronized (this) {
7470                TaskRecord tr = recentTaskForIdLocked(taskId);
7471                if (tr != null) {
7472                    return tr.stack.isHomeStack();
7473                }
7474            }
7475        } finally {
7476            Binder.restoreCallingIdentity(ident);
7477        }
7478        return false;
7479    }
7480
7481    @Override
7482    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7483        synchronized(this) {
7484            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7485        }
7486    }
7487
7488    private boolean isLockTaskAuthorized(ComponentName name) {
7489//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7490//                "startLockTaskMode()");
7491//        DevicePolicyManager dpm = (DevicePolicyManager)
7492//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7493//        return dpm != null && dpm.isLockTaskPermitted(name);
7494        return true;
7495    }
7496
7497    private void startLockTaskMode(TaskRecord task) {
7498        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7499            return;
7500        }
7501        long ident = Binder.clearCallingIdentity();
7502        try {
7503            synchronized (this) {
7504                // Since we lost lock on task, make sure it is still there.
7505                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7506                if (task != null) {
7507                    mStackSupervisor.setLockTaskModeLocked(task);
7508                }
7509            }
7510        } finally {
7511            Binder.restoreCallingIdentity(ident);
7512        }
7513    }
7514
7515    @Override
7516    public void startLockTaskMode(int taskId) {
7517        long ident = Binder.clearCallingIdentity();
7518        try {
7519            final TaskRecord task;
7520            synchronized (this) {
7521                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7522            }
7523            if (task != null) {
7524                startLockTaskMode(task);
7525            }
7526        } finally {
7527            Binder.restoreCallingIdentity(ident);
7528        }
7529    }
7530
7531    @Override
7532    public void startLockTaskMode(IBinder token) {
7533        long ident = Binder.clearCallingIdentity();
7534        try {
7535            final TaskRecord task;
7536            synchronized (this) {
7537                final ActivityRecord r = ActivityRecord.forToken(token);
7538                if (r == null) {
7539                    return;
7540                }
7541                task = r.task;
7542            }
7543            if (task != null) {
7544                startLockTaskMode(task);
7545            }
7546        } finally {
7547            Binder.restoreCallingIdentity(ident);
7548        }
7549    }
7550
7551    @Override
7552    public void stopLockTaskMode() {
7553//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7554//                "stopLockTaskMode()");
7555        synchronized (this) {
7556            mStackSupervisor.setLockTaskModeLocked(null);
7557        }
7558    }
7559
7560    @Override
7561    public boolean isInLockTaskMode() {
7562        synchronized (this) {
7563            return mStackSupervisor.isInLockTaskMode();
7564        }
7565    }
7566
7567    // =========================================================
7568    // THUMBNAILS
7569    // =========================================================
7570
7571    public void reportThumbnail(IBinder token,
7572            Bitmap thumbnail, CharSequence description) {
7573        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7574        final long origId = Binder.clearCallingIdentity();
7575        sendPendingThumbnail(null, token, thumbnail, description, true);
7576        Binder.restoreCallingIdentity(origId);
7577    }
7578
7579    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7580            Bitmap thumbnail, CharSequence description, boolean always) {
7581        TaskRecord task;
7582        ArrayList<PendingThumbnailsRecord> receivers = null;
7583
7584        //System.out.println("Send pending thumbnail: " + r);
7585
7586        synchronized(this) {
7587            if (r == null) {
7588                r = ActivityRecord.isInStackLocked(token);
7589                if (r == null) {
7590                    return;
7591                }
7592            }
7593            if (thumbnail == null && r.thumbHolder != null) {
7594                thumbnail = r.thumbHolder.lastThumbnail;
7595                description = r.thumbHolder.lastDescription;
7596            }
7597            if (thumbnail == null && !always) {
7598                // If there is no thumbnail, and this entry is not actually
7599                // going away, then abort for now and pick up the next
7600                // thumbnail we get.
7601                return;
7602            }
7603            task = r.task;
7604
7605            int N = mPendingThumbnails.size();
7606            int i=0;
7607            while (i<N) {
7608                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7609                //System.out.println("Looking in " + pr.pendingRecords);
7610                if (pr.pendingRecords.remove(r)) {
7611                    if (receivers == null) {
7612                        receivers = new ArrayList<PendingThumbnailsRecord>();
7613                    }
7614                    receivers.add(pr);
7615                    if (pr.pendingRecords.size() == 0) {
7616                        pr.finished = true;
7617                        mPendingThumbnails.remove(i);
7618                        N--;
7619                        continue;
7620                    }
7621                }
7622                i++;
7623            }
7624        }
7625
7626        if (receivers != null) {
7627            final int N = receivers.size();
7628            for (int i=0; i<N; i++) {
7629                try {
7630                    PendingThumbnailsRecord pr = receivers.get(i);
7631                    pr.receiver.newThumbnail(
7632                        task != null ? task.taskId : -1, thumbnail, description);
7633                    if (pr.finished) {
7634                        pr.receiver.finished();
7635                    }
7636                } catch (Exception e) {
7637                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7638                }
7639            }
7640        }
7641    }
7642
7643    // =========================================================
7644    // CONTENT PROVIDERS
7645    // =========================================================
7646
7647    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7648        List<ProviderInfo> providers = null;
7649        try {
7650            providers = AppGlobals.getPackageManager().
7651                queryContentProviders(app.processName, app.uid,
7652                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7653        } catch (RemoteException ex) {
7654        }
7655        if (DEBUG_MU)
7656            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7657        int userId = app.userId;
7658        if (providers != null) {
7659            int N = providers.size();
7660            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7661            for (int i=0; i<N; i++) {
7662                ProviderInfo cpi =
7663                    (ProviderInfo)providers.get(i);
7664                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7665                        cpi.name, cpi.flags);
7666                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7667                    // This is a singleton provider, but a user besides the
7668                    // default user is asking to initialize a process it runs
7669                    // in...  well, no, it doesn't actually run in this process,
7670                    // it runs in the process of the default user.  Get rid of it.
7671                    providers.remove(i);
7672                    N--;
7673                    i--;
7674                    continue;
7675                }
7676
7677                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7678                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7679                if (cpr == null) {
7680                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7681                    mProviderMap.putProviderByClass(comp, cpr);
7682                }
7683                if (DEBUG_MU)
7684                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7685                app.pubProviders.put(cpi.name, cpr);
7686                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7687                    // Don't add this if it is a platform component that is marked
7688                    // to run in multiple processes, because this is actually
7689                    // part of the framework so doesn't make sense to track as a
7690                    // separate apk in the process.
7691                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7692                }
7693                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7694            }
7695        }
7696        return providers;
7697    }
7698
7699    /**
7700     * Check if {@link ProcessRecord} has a possible chance at accessing the
7701     * given {@link ProviderInfo}. Final permission checking is always done
7702     * in {@link ContentProvider}.
7703     */
7704    private final String checkContentProviderPermissionLocked(
7705            ProviderInfo cpi, ProcessRecord r) {
7706        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7707        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7708        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7709                cpi.applicationInfo.uid, cpi.exported)
7710                == PackageManager.PERMISSION_GRANTED) {
7711            return null;
7712        }
7713        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7714                cpi.applicationInfo.uid, cpi.exported)
7715                == PackageManager.PERMISSION_GRANTED) {
7716            return null;
7717        }
7718
7719        PathPermission[] pps = cpi.pathPermissions;
7720        if (pps != null) {
7721            int i = pps.length;
7722            while (i > 0) {
7723                i--;
7724                PathPermission pp = pps[i];
7725                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7726                        cpi.applicationInfo.uid, cpi.exported)
7727                        == PackageManager.PERMISSION_GRANTED) {
7728                    return null;
7729                }
7730                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7731                        cpi.applicationInfo.uid, cpi.exported)
7732                        == PackageManager.PERMISSION_GRANTED) {
7733                    return null;
7734                }
7735            }
7736        }
7737
7738        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7739        if (perms != null) {
7740            for (GrantUri uri : perms.keySet()) {
7741                if (uri.uri.getAuthority().equals(cpi.authority)) {
7742                    return null;
7743                }
7744            }
7745        }
7746
7747        String msg;
7748        if (!cpi.exported) {
7749            msg = "Permission Denial: opening provider " + cpi.name
7750                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7751                    + ", uid=" + callingUid + ") that is not exported from uid "
7752                    + cpi.applicationInfo.uid;
7753        } else {
7754            msg = "Permission Denial: opening provider " + cpi.name
7755                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7756                    + ", uid=" + callingUid + ") requires "
7757                    + cpi.readPermission + " or " + cpi.writePermission;
7758        }
7759        Slog.w(TAG, msg);
7760        return msg;
7761    }
7762
7763    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7764            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7765        if (r != null) {
7766            for (int i=0; i<r.conProviders.size(); i++) {
7767                ContentProviderConnection conn = r.conProviders.get(i);
7768                if (conn.provider == cpr) {
7769                    if (DEBUG_PROVIDER) Slog.v(TAG,
7770                            "Adding provider requested by "
7771                            + r.processName + " from process "
7772                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7773                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7774                    if (stable) {
7775                        conn.stableCount++;
7776                        conn.numStableIncs++;
7777                    } else {
7778                        conn.unstableCount++;
7779                        conn.numUnstableIncs++;
7780                    }
7781                    return conn;
7782                }
7783            }
7784            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7785            if (stable) {
7786                conn.stableCount = 1;
7787                conn.numStableIncs = 1;
7788            } else {
7789                conn.unstableCount = 1;
7790                conn.numUnstableIncs = 1;
7791            }
7792            cpr.connections.add(conn);
7793            r.conProviders.add(conn);
7794            return conn;
7795        }
7796        cpr.addExternalProcessHandleLocked(externalProcessToken);
7797        return null;
7798    }
7799
7800    boolean decProviderCountLocked(ContentProviderConnection conn,
7801            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7802        if (conn != null) {
7803            cpr = conn.provider;
7804            if (DEBUG_PROVIDER) Slog.v(TAG,
7805                    "Removing provider requested by "
7806                    + conn.client.processName + " from process "
7807                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7808                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7809            if (stable) {
7810                conn.stableCount--;
7811            } else {
7812                conn.unstableCount--;
7813            }
7814            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7815                cpr.connections.remove(conn);
7816                conn.client.conProviders.remove(conn);
7817                return true;
7818            }
7819            return false;
7820        }
7821        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7822        return false;
7823    }
7824
7825    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7826            String name, IBinder token, boolean stable, int userId) {
7827        ContentProviderRecord cpr;
7828        ContentProviderConnection conn = null;
7829        ProviderInfo cpi = null;
7830
7831        synchronized(this) {
7832            ProcessRecord r = null;
7833            if (caller != null) {
7834                r = getRecordForAppLocked(caller);
7835                if (r == null) {
7836                    throw new SecurityException(
7837                            "Unable to find app for caller " + caller
7838                          + " (pid=" + Binder.getCallingPid()
7839                          + ") when getting content provider " + name);
7840                }
7841            }
7842
7843            // First check if this content provider has been published...
7844            cpr = mProviderMap.getProviderByName(name, userId);
7845            boolean providerRunning = cpr != null;
7846            if (providerRunning) {
7847                cpi = cpr.info;
7848                String msg;
7849                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7850                    throw new SecurityException(msg);
7851                }
7852
7853                if (r != null && cpr.canRunHere(r)) {
7854                    // This provider has been published or is in the process
7855                    // of being published...  but it is also allowed to run
7856                    // in the caller's process, so don't make a connection
7857                    // and just let the caller instantiate its own instance.
7858                    ContentProviderHolder holder = cpr.newHolder(null);
7859                    // don't give caller the provider object, it needs
7860                    // to make its own.
7861                    holder.provider = null;
7862                    return holder;
7863                }
7864
7865                final long origId = Binder.clearCallingIdentity();
7866
7867                // In this case the provider instance already exists, so we can
7868                // return it right away.
7869                conn = incProviderCountLocked(r, cpr, token, stable);
7870                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7871                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7872                        // If this is a perceptible app accessing the provider,
7873                        // make sure to count it as being accessed and thus
7874                        // back up on the LRU list.  This is good because
7875                        // content providers are often expensive to start.
7876                        updateLruProcessLocked(cpr.proc, false, null);
7877                    }
7878                }
7879
7880                if (cpr.proc != null) {
7881                    if (false) {
7882                        if (cpr.name.flattenToShortString().equals(
7883                                "com.android.providers.calendar/.CalendarProvider2")) {
7884                            Slog.v(TAG, "****************** KILLING "
7885                                + cpr.name.flattenToShortString());
7886                            Process.killProcess(cpr.proc.pid);
7887                        }
7888                    }
7889                    boolean success = updateOomAdjLocked(cpr.proc);
7890                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7891                    // NOTE: there is still a race here where a signal could be
7892                    // pending on the process even though we managed to update its
7893                    // adj level.  Not sure what to do about this, but at least
7894                    // the race is now smaller.
7895                    if (!success) {
7896                        // Uh oh...  it looks like the provider's process
7897                        // has been killed on us.  We need to wait for a new
7898                        // process to be started, and make sure its death
7899                        // doesn't kill our process.
7900                        Slog.i(TAG,
7901                                "Existing provider " + cpr.name.flattenToShortString()
7902                                + " is crashing; detaching " + r);
7903                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7904                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7905                        if (!lastRef) {
7906                            // This wasn't the last ref our process had on
7907                            // the provider...  we have now been killed, bail.
7908                            return null;
7909                        }
7910                        providerRunning = false;
7911                        conn = null;
7912                    }
7913                }
7914
7915                Binder.restoreCallingIdentity(origId);
7916            }
7917
7918            boolean singleton;
7919            if (!providerRunning) {
7920                try {
7921                    cpi = AppGlobals.getPackageManager().
7922                        resolveContentProvider(name,
7923                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7924                } catch (RemoteException ex) {
7925                }
7926                if (cpi == null) {
7927                    return null;
7928                }
7929                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7930                        cpi.name, cpi.flags);
7931                if (singleton) {
7932                    userId = 0;
7933                }
7934                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7935
7936                String msg;
7937                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7938                    throw new SecurityException(msg);
7939                }
7940
7941                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7942                        && !cpi.processName.equals("system")) {
7943                    // If this content provider does not run in the system
7944                    // process, and the system is not yet ready to run other
7945                    // processes, then fail fast instead of hanging.
7946                    throw new IllegalArgumentException(
7947                            "Attempt to launch content provider before system ready");
7948                }
7949
7950                // Make sure that the user who owns this provider is started.  If not,
7951                // we don't want to allow it to run.
7952                if (mStartedUsers.get(userId) == null) {
7953                    Slog.w(TAG, "Unable to launch app "
7954                            + cpi.applicationInfo.packageName + "/"
7955                            + cpi.applicationInfo.uid + " for provider "
7956                            + name + ": user " + userId + " is stopped");
7957                    return null;
7958                }
7959
7960                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7961                cpr = mProviderMap.getProviderByClass(comp, userId);
7962                final boolean firstClass = cpr == null;
7963                if (firstClass) {
7964                    try {
7965                        ApplicationInfo ai =
7966                            AppGlobals.getPackageManager().
7967                                getApplicationInfo(
7968                                        cpi.applicationInfo.packageName,
7969                                        STOCK_PM_FLAGS, userId);
7970                        if (ai == null) {
7971                            Slog.w(TAG, "No package info for content provider "
7972                                    + cpi.name);
7973                            return null;
7974                        }
7975                        ai = getAppInfoForUser(ai, userId);
7976                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7977                    } catch (RemoteException ex) {
7978                        // pm is in same process, this will never happen.
7979                    }
7980                }
7981
7982                if (r != null && cpr.canRunHere(r)) {
7983                    // If this is a multiprocess provider, then just return its
7984                    // info and allow the caller to instantiate it.  Only do
7985                    // this if the provider is the same user as the caller's
7986                    // process, or can run as root (so can be in any process).
7987                    return cpr.newHolder(null);
7988                }
7989
7990                if (DEBUG_PROVIDER) {
7991                    RuntimeException e = new RuntimeException("here");
7992                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7993                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7994                }
7995
7996                // This is single process, and our app is now connecting to it.
7997                // See if we are already in the process of launching this
7998                // provider.
7999                final int N = mLaunchingProviders.size();
8000                int i;
8001                for (i=0; i<N; i++) {
8002                    if (mLaunchingProviders.get(i) == cpr) {
8003                        break;
8004                    }
8005                }
8006
8007                // If the provider is not already being launched, then get it
8008                // started.
8009                if (i >= N) {
8010                    final long origId = Binder.clearCallingIdentity();
8011
8012                    try {
8013                        // Content provider is now in use, its package can't be stopped.
8014                        try {
8015                            AppGlobals.getPackageManager().setPackageStoppedState(
8016                                    cpr.appInfo.packageName, false, userId);
8017                        } catch (RemoteException e) {
8018                        } catch (IllegalArgumentException e) {
8019                            Slog.w(TAG, "Failed trying to unstop package "
8020                                    + cpr.appInfo.packageName + ": " + e);
8021                        }
8022
8023                        // Use existing process if already started
8024                        ProcessRecord proc = getProcessRecordLocked(
8025                                cpi.processName, cpr.appInfo.uid, false);
8026                        if (proc != null && proc.thread != null) {
8027                            if (DEBUG_PROVIDER) {
8028                                Slog.d(TAG, "Installing in existing process " + proc);
8029                            }
8030                            proc.pubProviders.put(cpi.name, cpr);
8031                            try {
8032                                proc.thread.scheduleInstallProvider(cpi);
8033                            } catch (RemoteException e) {
8034                            }
8035                        } else {
8036                            proc = startProcessLocked(cpi.processName,
8037                                    cpr.appInfo, false, 0, "content provider",
8038                                    new ComponentName(cpi.applicationInfo.packageName,
8039                                            cpi.name), false, false, false);
8040                            if (proc == null) {
8041                                Slog.w(TAG, "Unable to launch app "
8042                                        + cpi.applicationInfo.packageName + "/"
8043                                        + cpi.applicationInfo.uid + " for provider "
8044                                        + name + ": process is bad");
8045                                return null;
8046                            }
8047                        }
8048                        cpr.launchingApp = proc;
8049                        mLaunchingProviders.add(cpr);
8050                    } finally {
8051                        Binder.restoreCallingIdentity(origId);
8052                    }
8053                }
8054
8055                // Make sure the provider is published (the same provider class
8056                // may be published under multiple names).
8057                if (firstClass) {
8058                    mProviderMap.putProviderByClass(comp, cpr);
8059                }
8060
8061                mProviderMap.putProviderByName(name, cpr);
8062                conn = incProviderCountLocked(r, cpr, token, stable);
8063                if (conn != null) {
8064                    conn.waiting = true;
8065                }
8066            }
8067        }
8068
8069        // Wait for the provider to be published...
8070        synchronized (cpr) {
8071            while (cpr.provider == null) {
8072                if (cpr.launchingApp == null) {
8073                    Slog.w(TAG, "Unable to launch app "
8074                            + cpi.applicationInfo.packageName + "/"
8075                            + cpi.applicationInfo.uid + " for provider "
8076                            + name + ": launching app became null");
8077                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8078                            UserHandle.getUserId(cpi.applicationInfo.uid),
8079                            cpi.applicationInfo.packageName,
8080                            cpi.applicationInfo.uid, name);
8081                    return null;
8082                }
8083                try {
8084                    if (DEBUG_MU) {
8085                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8086                                + cpr.launchingApp);
8087                    }
8088                    if (conn != null) {
8089                        conn.waiting = true;
8090                    }
8091                    cpr.wait();
8092                } catch (InterruptedException ex) {
8093                } finally {
8094                    if (conn != null) {
8095                        conn.waiting = false;
8096                    }
8097                }
8098            }
8099        }
8100        return cpr != null ? cpr.newHolder(conn) : null;
8101    }
8102
8103    public final ContentProviderHolder getContentProvider(
8104            IApplicationThread caller, String name, int userId, boolean stable) {
8105        enforceNotIsolatedCaller("getContentProvider");
8106        if (caller == null) {
8107            String msg = "null IApplicationThread when getting content provider "
8108                    + name;
8109            Slog.w(TAG, msg);
8110            throw new SecurityException(msg);
8111        }
8112
8113        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8114                false, true, "getContentProvider", null);
8115        return getContentProviderImpl(caller, name, null, stable, userId);
8116    }
8117
8118    public ContentProviderHolder getContentProviderExternal(
8119            String name, int userId, IBinder token) {
8120        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8121            "Do not have permission in call getContentProviderExternal()");
8122        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8123                false, true, "getContentProvider", null);
8124        return getContentProviderExternalUnchecked(name, token, userId);
8125    }
8126
8127    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8128            IBinder token, int userId) {
8129        return getContentProviderImpl(null, name, token, true, userId);
8130    }
8131
8132    /**
8133     * Drop a content provider from a ProcessRecord's bookkeeping
8134     */
8135    public void removeContentProvider(IBinder connection, boolean stable) {
8136        enforceNotIsolatedCaller("removeContentProvider");
8137        long ident = Binder.clearCallingIdentity();
8138        try {
8139            synchronized (this) {
8140                ContentProviderConnection conn;
8141                try {
8142                    conn = (ContentProviderConnection)connection;
8143                } catch (ClassCastException e) {
8144                    String msg ="removeContentProvider: " + connection
8145                            + " not a ContentProviderConnection";
8146                    Slog.w(TAG, msg);
8147                    throw new IllegalArgumentException(msg);
8148                }
8149                if (conn == null) {
8150                    throw new NullPointerException("connection is null");
8151                }
8152                if (decProviderCountLocked(conn, null, null, stable)) {
8153                    updateOomAdjLocked();
8154                }
8155            }
8156        } finally {
8157            Binder.restoreCallingIdentity(ident);
8158        }
8159    }
8160
8161    public void removeContentProviderExternal(String name, IBinder token) {
8162        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8163            "Do not have permission in call removeContentProviderExternal()");
8164        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8165    }
8166
8167    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8168        synchronized (this) {
8169            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8170            if(cpr == null) {
8171                //remove from mProvidersByClass
8172                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8173                return;
8174            }
8175
8176            //update content provider record entry info
8177            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8178            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8179            if (localCpr.hasExternalProcessHandles()) {
8180                if (localCpr.removeExternalProcessHandleLocked(token)) {
8181                    updateOomAdjLocked();
8182                } else {
8183                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8184                            + " with no external reference for token: "
8185                            + token + ".");
8186                }
8187            } else {
8188                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8189                        + " with no external references.");
8190            }
8191        }
8192    }
8193
8194    public final void publishContentProviders(IApplicationThread caller,
8195            List<ContentProviderHolder> providers) {
8196        if (providers == null) {
8197            return;
8198        }
8199
8200        enforceNotIsolatedCaller("publishContentProviders");
8201        synchronized (this) {
8202            final ProcessRecord r = getRecordForAppLocked(caller);
8203            if (DEBUG_MU)
8204                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8205            if (r == null) {
8206                throw new SecurityException(
8207                        "Unable to find app for caller " + caller
8208                      + " (pid=" + Binder.getCallingPid()
8209                      + ") when publishing content providers");
8210            }
8211
8212            final long origId = Binder.clearCallingIdentity();
8213
8214            final int N = providers.size();
8215            for (int i=0; i<N; i++) {
8216                ContentProviderHolder src = providers.get(i);
8217                if (src == null || src.info == null || src.provider == null) {
8218                    continue;
8219                }
8220                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8221                if (DEBUG_MU)
8222                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8223                if (dst != null) {
8224                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8225                    mProviderMap.putProviderByClass(comp, dst);
8226                    String names[] = dst.info.authority.split(";");
8227                    for (int j = 0; j < names.length; j++) {
8228                        mProviderMap.putProviderByName(names[j], dst);
8229                    }
8230
8231                    int NL = mLaunchingProviders.size();
8232                    int j;
8233                    for (j=0; j<NL; j++) {
8234                        if (mLaunchingProviders.get(j) == dst) {
8235                            mLaunchingProviders.remove(j);
8236                            j--;
8237                            NL--;
8238                        }
8239                    }
8240                    synchronized (dst) {
8241                        dst.provider = src.provider;
8242                        dst.proc = r;
8243                        dst.notifyAll();
8244                    }
8245                    updateOomAdjLocked(r);
8246                }
8247            }
8248
8249            Binder.restoreCallingIdentity(origId);
8250        }
8251    }
8252
8253    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8254        ContentProviderConnection conn;
8255        try {
8256            conn = (ContentProviderConnection)connection;
8257        } catch (ClassCastException e) {
8258            String msg ="refContentProvider: " + connection
8259                    + " not a ContentProviderConnection";
8260            Slog.w(TAG, msg);
8261            throw new IllegalArgumentException(msg);
8262        }
8263        if (conn == null) {
8264            throw new NullPointerException("connection is null");
8265        }
8266
8267        synchronized (this) {
8268            if (stable > 0) {
8269                conn.numStableIncs += stable;
8270            }
8271            stable = conn.stableCount + stable;
8272            if (stable < 0) {
8273                throw new IllegalStateException("stableCount < 0: " + stable);
8274            }
8275
8276            if (unstable > 0) {
8277                conn.numUnstableIncs += unstable;
8278            }
8279            unstable = conn.unstableCount + unstable;
8280            if (unstable < 0) {
8281                throw new IllegalStateException("unstableCount < 0: " + unstable);
8282            }
8283
8284            if ((stable+unstable) <= 0) {
8285                throw new IllegalStateException("ref counts can't go to zero here: stable="
8286                        + stable + " unstable=" + unstable);
8287            }
8288            conn.stableCount = stable;
8289            conn.unstableCount = unstable;
8290            return !conn.dead;
8291        }
8292    }
8293
8294    public void unstableProviderDied(IBinder connection) {
8295        ContentProviderConnection conn;
8296        try {
8297            conn = (ContentProviderConnection)connection;
8298        } catch (ClassCastException e) {
8299            String msg ="refContentProvider: " + connection
8300                    + " not a ContentProviderConnection";
8301            Slog.w(TAG, msg);
8302            throw new IllegalArgumentException(msg);
8303        }
8304        if (conn == null) {
8305            throw new NullPointerException("connection is null");
8306        }
8307
8308        // Safely retrieve the content provider associated with the connection.
8309        IContentProvider provider;
8310        synchronized (this) {
8311            provider = conn.provider.provider;
8312        }
8313
8314        if (provider == null) {
8315            // Um, yeah, we're way ahead of you.
8316            return;
8317        }
8318
8319        // Make sure the caller is being honest with us.
8320        if (provider.asBinder().pingBinder()) {
8321            // Er, no, still looks good to us.
8322            synchronized (this) {
8323                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8324                        + " says " + conn + " died, but we don't agree");
8325                return;
8326            }
8327        }
8328
8329        // Well look at that!  It's dead!
8330        synchronized (this) {
8331            if (conn.provider.provider != provider) {
8332                // But something changed...  good enough.
8333                return;
8334            }
8335
8336            ProcessRecord proc = conn.provider.proc;
8337            if (proc == null || proc.thread == null) {
8338                // Seems like the process is already cleaned up.
8339                return;
8340            }
8341
8342            // As far as we're concerned, this is just like receiving a
8343            // death notification...  just a bit prematurely.
8344            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8345                    + ") early provider death");
8346            final long ident = Binder.clearCallingIdentity();
8347            try {
8348                appDiedLocked(proc, proc.pid, proc.thread);
8349            } finally {
8350                Binder.restoreCallingIdentity(ident);
8351            }
8352        }
8353    }
8354
8355    @Override
8356    public void appNotRespondingViaProvider(IBinder connection) {
8357        enforceCallingPermission(
8358                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8359
8360        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8361        if (conn == null) {
8362            Slog.w(TAG, "ContentProviderConnection is null");
8363            return;
8364        }
8365
8366        final ProcessRecord host = conn.provider.proc;
8367        if (host == null) {
8368            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8369            return;
8370        }
8371
8372        final long token = Binder.clearCallingIdentity();
8373        try {
8374            appNotResponding(host, null, null, false, "ContentProvider not responding");
8375        } finally {
8376            Binder.restoreCallingIdentity(token);
8377        }
8378    }
8379
8380    public final void installSystemProviders() {
8381        List<ProviderInfo> providers;
8382        synchronized (this) {
8383            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8384            providers = generateApplicationProvidersLocked(app);
8385            if (providers != null) {
8386                for (int i=providers.size()-1; i>=0; i--) {
8387                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8388                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8389                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8390                                + ": not system .apk");
8391                        providers.remove(i);
8392                    }
8393                }
8394            }
8395        }
8396        if (providers != null) {
8397            mSystemThread.installSystemProviders(providers);
8398        }
8399
8400        mCoreSettingsObserver = new CoreSettingsObserver(this);
8401
8402        mUsageStatsService.monitorPackages();
8403    }
8404
8405    /**
8406     * Allows app to retrieve the MIME type of a URI without having permission
8407     * to access its content provider.
8408     *
8409     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8410     *
8411     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8412     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8413     */
8414    public String getProviderMimeType(Uri uri, int userId) {
8415        enforceNotIsolatedCaller("getProviderMimeType");
8416        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8417                userId, false, true, "getProviderMimeType", null);
8418        final String name = uri.getAuthority();
8419        final long ident = Binder.clearCallingIdentity();
8420        ContentProviderHolder holder = null;
8421
8422        try {
8423            holder = getContentProviderExternalUnchecked(name, null, userId);
8424            if (holder != null) {
8425                return holder.provider.getType(uri);
8426            }
8427        } catch (RemoteException e) {
8428            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8429            return null;
8430        } finally {
8431            if (holder != null) {
8432                removeContentProviderExternalUnchecked(name, null, userId);
8433            }
8434            Binder.restoreCallingIdentity(ident);
8435        }
8436
8437        return null;
8438    }
8439
8440    // =========================================================
8441    // GLOBAL MANAGEMENT
8442    // =========================================================
8443
8444    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8445            boolean isolated) {
8446        String proc = customProcess != null ? customProcess : info.processName;
8447        BatteryStatsImpl.Uid.Proc ps = null;
8448        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8449        int uid = info.uid;
8450        if (isolated) {
8451            int userId = UserHandle.getUserId(uid);
8452            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8453            while (true) {
8454                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8455                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8456                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8457                }
8458                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8459                mNextIsolatedProcessUid++;
8460                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8461                    // No process for this uid, use it.
8462                    break;
8463                }
8464                stepsLeft--;
8465                if (stepsLeft <= 0) {
8466                    return null;
8467                }
8468            }
8469        }
8470        return new ProcessRecord(stats, info, proc, uid);
8471    }
8472
8473    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8474        ProcessRecord app;
8475        if (!isolated) {
8476            app = getProcessRecordLocked(info.processName, info.uid, true);
8477        } else {
8478            app = null;
8479        }
8480
8481        if (app == null) {
8482            app = newProcessRecordLocked(info, null, isolated);
8483            mProcessNames.put(info.processName, app.uid, app);
8484            if (isolated) {
8485                mIsolatedProcesses.put(app.uid, app);
8486            }
8487            updateLruProcessLocked(app, false, null);
8488            updateOomAdjLocked();
8489        }
8490
8491        // This package really, really can not be stopped.
8492        try {
8493            AppGlobals.getPackageManager().setPackageStoppedState(
8494                    info.packageName, false, UserHandle.getUserId(app.uid));
8495        } catch (RemoteException e) {
8496        } catch (IllegalArgumentException e) {
8497            Slog.w(TAG, "Failed trying to unstop package "
8498                    + info.packageName + ": " + e);
8499        }
8500
8501        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8502                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8503            app.persistent = true;
8504            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8505        }
8506        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8507            mPersistentStartingProcesses.add(app);
8508            startProcessLocked(app, "added application", app.processName);
8509        }
8510
8511        return app;
8512    }
8513
8514    public void unhandledBack() {
8515        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8516                "unhandledBack()");
8517
8518        synchronized(this) {
8519            final long origId = Binder.clearCallingIdentity();
8520            try {
8521                getFocusedStack().unhandledBackLocked();
8522            } finally {
8523                Binder.restoreCallingIdentity(origId);
8524            }
8525        }
8526    }
8527
8528    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8529        enforceNotIsolatedCaller("openContentUri");
8530        final int userId = UserHandle.getCallingUserId();
8531        String name = uri.getAuthority();
8532        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8533        ParcelFileDescriptor pfd = null;
8534        if (cph != null) {
8535            // We record the binder invoker's uid in thread-local storage before
8536            // going to the content provider to open the file.  Later, in the code
8537            // that handles all permissions checks, we look for this uid and use
8538            // that rather than the Activity Manager's own uid.  The effect is that
8539            // we do the check against the caller's permissions even though it looks
8540            // to the content provider like the Activity Manager itself is making
8541            // the request.
8542            sCallerIdentity.set(new Identity(
8543                    Binder.getCallingPid(), Binder.getCallingUid()));
8544            try {
8545                pfd = cph.provider.openFile(null, uri, "r", null);
8546            } catch (FileNotFoundException e) {
8547                // do nothing; pfd will be returned null
8548            } finally {
8549                // Ensure that whatever happens, we clean up the identity state
8550                sCallerIdentity.remove();
8551            }
8552
8553            // We've got the fd now, so we're done with the provider.
8554            removeContentProviderExternalUnchecked(name, null, userId);
8555        } else {
8556            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8557        }
8558        return pfd;
8559    }
8560
8561    // Actually is sleeping or shutting down or whatever else in the future
8562    // is an inactive state.
8563    public boolean isSleepingOrShuttingDown() {
8564        return mSleeping || mShuttingDown;
8565    }
8566
8567    void goingToSleep() {
8568        synchronized(this) {
8569            mWentToSleep = true;
8570            updateEventDispatchingLocked();
8571
8572            if (!mSleeping) {
8573                mSleeping = true;
8574                mStackSupervisor.goingToSleepLocked();
8575
8576                // Initialize the wake times of all processes.
8577                checkExcessivePowerUsageLocked(false);
8578                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8579                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8580                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8581            }
8582        }
8583    }
8584
8585    @Override
8586    public boolean shutdown(int timeout) {
8587        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8588                != PackageManager.PERMISSION_GRANTED) {
8589            throw new SecurityException("Requires permission "
8590                    + android.Manifest.permission.SHUTDOWN);
8591        }
8592
8593        boolean timedout = false;
8594
8595        synchronized(this) {
8596            mShuttingDown = true;
8597            updateEventDispatchingLocked();
8598            timedout = mStackSupervisor.shutdownLocked(timeout);
8599        }
8600
8601        mAppOpsService.shutdown();
8602        mUsageStatsService.shutdown();
8603        mBatteryStatsService.shutdown();
8604        synchronized (this) {
8605            mProcessStats.shutdownLocked();
8606        }
8607
8608        return timedout;
8609    }
8610
8611    public final void activitySlept(IBinder token) {
8612        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8613
8614        final long origId = Binder.clearCallingIdentity();
8615
8616        synchronized (this) {
8617            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8618            if (r != null) {
8619                mStackSupervisor.activitySleptLocked(r);
8620            }
8621        }
8622
8623        Binder.restoreCallingIdentity(origId);
8624    }
8625
8626    void logLockScreen(String msg) {
8627        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8628                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8629                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8630                mStackSupervisor.mDismissKeyguardOnNextActivity);
8631    }
8632
8633    private void comeOutOfSleepIfNeededLocked() {
8634        if (!mWentToSleep && !mLockScreenShown) {
8635            if (mSleeping) {
8636                mSleeping = false;
8637                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8638            }
8639        }
8640    }
8641
8642    void wakingUp() {
8643        synchronized(this) {
8644            mWentToSleep = false;
8645            updateEventDispatchingLocked();
8646            comeOutOfSleepIfNeededLocked();
8647        }
8648    }
8649
8650    private void updateEventDispatchingLocked() {
8651        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8652    }
8653
8654    public void setLockScreenShown(boolean shown) {
8655        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8656                != PackageManager.PERMISSION_GRANTED) {
8657            throw new SecurityException("Requires permission "
8658                    + android.Manifest.permission.DEVICE_POWER);
8659        }
8660
8661        synchronized(this) {
8662            long ident = Binder.clearCallingIdentity();
8663            try {
8664                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8665                mLockScreenShown = shown;
8666                comeOutOfSleepIfNeededLocked();
8667            } finally {
8668                Binder.restoreCallingIdentity(ident);
8669            }
8670        }
8671    }
8672
8673    public void stopAppSwitches() {
8674        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8675                != PackageManager.PERMISSION_GRANTED) {
8676            throw new SecurityException("Requires permission "
8677                    + android.Manifest.permission.STOP_APP_SWITCHES);
8678        }
8679
8680        synchronized(this) {
8681            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8682                    + APP_SWITCH_DELAY_TIME;
8683            mDidAppSwitch = false;
8684            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8685            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8686            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8687        }
8688    }
8689
8690    public void resumeAppSwitches() {
8691        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8692                != PackageManager.PERMISSION_GRANTED) {
8693            throw new SecurityException("Requires permission "
8694                    + android.Manifest.permission.STOP_APP_SWITCHES);
8695        }
8696
8697        synchronized(this) {
8698            // Note that we don't execute any pending app switches... we will
8699            // let those wait until either the timeout, or the next start
8700            // activity request.
8701            mAppSwitchesAllowedTime = 0;
8702        }
8703    }
8704
8705    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8706            String name) {
8707        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8708            return true;
8709        }
8710
8711        final int perm = checkComponentPermission(
8712                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8713                callingUid, -1, true);
8714        if (perm == PackageManager.PERMISSION_GRANTED) {
8715            return true;
8716        }
8717
8718        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8719        return false;
8720    }
8721
8722    public void setDebugApp(String packageName, boolean waitForDebugger,
8723            boolean persistent) {
8724        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8725                "setDebugApp()");
8726
8727        long ident = Binder.clearCallingIdentity();
8728        try {
8729            // Note that this is not really thread safe if there are multiple
8730            // callers into it at the same time, but that's not a situation we
8731            // care about.
8732            if (persistent) {
8733                final ContentResolver resolver = mContext.getContentResolver();
8734                Settings.Global.putString(
8735                    resolver, Settings.Global.DEBUG_APP,
8736                    packageName);
8737                Settings.Global.putInt(
8738                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8739                    waitForDebugger ? 1 : 0);
8740            }
8741
8742            synchronized (this) {
8743                if (!persistent) {
8744                    mOrigDebugApp = mDebugApp;
8745                    mOrigWaitForDebugger = mWaitForDebugger;
8746                }
8747                mDebugApp = packageName;
8748                mWaitForDebugger = waitForDebugger;
8749                mDebugTransient = !persistent;
8750                if (packageName != null) {
8751                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8752                            false, UserHandle.USER_ALL, "set debug app");
8753                }
8754            }
8755        } finally {
8756            Binder.restoreCallingIdentity(ident);
8757        }
8758    }
8759
8760    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8761        synchronized (this) {
8762            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8763            if (!isDebuggable) {
8764                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8765                    throw new SecurityException("Process not debuggable: " + app.packageName);
8766                }
8767            }
8768
8769            mOpenGlTraceApp = processName;
8770        }
8771    }
8772
8773    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8774            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8775        synchronized (this) {
8776            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8777            if (!isDebuggable) {
8778                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8779                    throw new SecurityException("Process not debuggable: " + app.packageName);
8780                }
8781            }
8782            mProfileApp = processName;
8783            mProfileFile = profileFile;
8784            if (mProfileFd != null) {
8785                try {
8786                    mProfileFd.close();
8787                } catch (IOException e) {
8788                }
8789                mProfileFd = null;
8790            }
8791            mProfileFd = profileFd;
8792            mProfileType = 0;
8793            mAutoStopProfiler = autoStopProfiler;
8794        }
8795    }
8796
8797    @Override
8798    public void setAlwaysFinish(boolean enabled) {
8799        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8800                "setAlwaysFinish()");
8801
8802        Settings.Global.putInt(
8803                mContext.getContentResolver(),
8804                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8805
8806        synchronized (this) {
8807            mAlwaysFinishActivities = enabled;
8808        }
8809    }
8810
8811    @Override
8812    public void setActivityController(IActivityController controller) {
8813        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8814                "setActivityController()");
8815        synchronized (this) {
8816            mController = controller;
8817            Watchdog.getInstance().setActivityController(controller);
8818        }
8819    }
8820
8821    @Override
8822    public void setUserIsMonkey(boolean userIsMonkey) {
8823        synchronized (this) {
8824            synchronized (mPidsSelfLocked) {
8825                final int callingPid = Binder.getCallingPid();
8826                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8827                if (precessRecord == null) {
8828                    throw new SecurityException("Unknown process: " + callingPid);
8829                }
8830                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8831                    throw new SecurityException("Only an instrumentation process "
8832                            + "with a UiAutomation can call setUserIsMonkey");
8833                }
8834            }
8835            mUserIsMonkey = userIsMonkey;
8836        }
8837    }
8838
8839    @Override
8840    public boolean isUserAMonkey() {
8841        synchronized (this) {
8842            // If there is a controller also implies the user is a monkey.
8843            return (mUserIsMonkey || mController != null);
8844        }
8845    }
8846
8847    public void requestBugReport() {
8848        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8849        SystemProperties.set("ctl.start", "bugreport");
8850    }
8851
8852    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8853        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8854    }
8855
8856    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8857        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8858            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8859        }
8860        return KEY_DISPATCHING_TIMEOUT;
8861    }
8862
8863    @Override
8864    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8865        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8866                != PackageManager.PERMISSION_GRANTED) {
8867            throw new SecurityException("Requires permission "
8868                    + android.Manifest.permission.FILTER_EVENTS);
8869        }
8870        ProcessRecord proc;
8871        long timeout;
8872        synchronized (this) {
8873            synchronized (mPidsSelfLocked) {
8874                proc = mPidsSelfLocked.get(pid);
8875            }
8876            timeout = getInputDispatchingTimeoutLocked(proc);
8877        }
8878
8879        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8880            return -1;
8881        }
8882
8883        return timeout;
8884    }
8885
8886    /**
8887     * Handle input dispatching timeouts.
8888     * Returns whether input dispatching should be aborted or not.
8889     */
8890    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8891            final ActivityRecord activity, final ActivityRecord parent,
8892            final boolean aboveSystem, String reason) {
8893        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8894                != PackageManager.PERMISSION_GRANTED) {
8895            throw new SecurityException("Requires permission "
8896                    + android.Manifest.permission.FILTER_EVENTS);
8897        }
8898
8899        final String annotation;
8900        if (reason == null) {
8901            annotation = "Input dispatching timed out";
8902        } else {
8903            annotation = "Input dispatching timed out (" + reason + ")";
8904        }
8905
8906        if (proc != null) {
8907            synchronized (this) {
8908                if (proc.debugging) {
8909                    return false;
8910                }
8911
8912                if (mDidDexOpt) {
8913                    // Give more time since we were dexopting.
8914                    mDidDexOpt = false;
8915                    return false;
8916                }
8917
8918                if (proc.instrumentationClass != null) {
8919                    Bundle info = new Bundle();
8920                    info.putString("shortMsg", "keyDispatchingTimedOut");
8921                    info.putString("longMsg", annotation);
8922                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8923                    return true;
8924                }
8925            }
8926            mHandler.post(new Runnable() {
8927                @Override
8928                public void run() {
8929                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8930                }
8931            });
8932        }
8933
8934        return true;
8935    }
8936
8937    public Bundle getAssistContextExtras(int requestType) {
8938        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8939                "getAssistContextExtras()");
8940        PendingAssistExtras pae;
8941        Bundle extras = new Bundle();
8942        synchronized (this) {
8943            ActivityRecord activity = getFocusedStack().mResumedActivity;
8944            if (activity == null) {
8945                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8946                return null;
8947            }
8948            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8949            if (activity.app == null || activity.app.thread == null) {
8950                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8951                return extras;
8952            }
8953            if (activity.app.pid == Binder.getCallingPid()) {
8954                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8955                return extras;
8956            }
8957            pae = new PendingAssistExtras(activity);
8958            try {
8959                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8960                        requestType);
8961                mPendingAssistExtras.add(pae);
8962                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8963            } catch (RemoteException e) {
8964                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8965                return extras;
8966            }
8967        }
8968        synchronized (pae) {
8969            while (!pae.haveResult) {
8970                try {
8971                    pae.wait();
8972                } catch (InterruptedException e) {
8973                }
8974            }
8975            if (pae.result != null) {
8976                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8977            }
8978        }
8979        synchronized (this) {
8980            mPendingAssistExtras.remove(pae);
8981            mHandler.removeCallbacks(pae);
8982        }
8983        return extras;
8984    }
8985
8986    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8987        PendingAssistExtras pae = (PendingAssistExtras)token;
8988        synchronized (pae) {
8989            pae.result = extras;
8990            pae.haveResult = true;
8991            pae.notifyAll();
8992        }
8993    }
8994
8995    public void registerProcessObserver(IProcessObserver observer) {
8996        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8997                "registerProcessObserver()");
8998        synchronized (this) {
8999            mProcessObservers.register(observer);
9000        }
9001    }
9002
9003    @Override
9004    public void unregisterProcessObserver(IProcessObserver observer) {
9005        synchronized (this) {
9006            mProcessObservers.unregister(observer);
9007        }
9008    }
9009
9010    @Override
9011    public boolean convertFromTranslucent(IBinder token) {
9012        final long origId = Binder.clearCallingIdentity();
9013        try {
9014            synchronized (this) {
9015                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9016                if (r == null) {
9017                    return false;
9018                }
9019                if (r.changeWindowTranslucency(true)) {
9020                    mWindowManager.setAppFullscreen(token, true);
9021                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9022                    return true;
9023                }
9024                return false;
9025            }
9026        } finally {
9027            Binder.restoreCallingIdentity(origId);
9028        }
9029    }
9030
9031    @Override
9032    public boolean convertToTranslucent(IBinder token) {
9033        final long origId = Binder.clearCallingIdentity();
9034        try {
9035            synchronized (this) {
9036                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9037                if (r == null) {
9038                    return false;
9039                }
9040                if (r.changeWindowTranslucency(false)) {
9041                    r.task.stack.convertToTranslucent(r);
9042                    mWindowManager.setAppFullscreen(token, false);
9043                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9044                    return true;
9045                }
9046                return false;
9047            }
9048        } finally {
9049            Binder.restoreCallingIdentity(origId);
9050        }
9051    }
9052
9053    @Override
9054    public void setImmersive(IBinder token, boolean immersive) {
9055        synchronized(this) {
9056            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9057            if (r == null) {
9058                throw new IllegalArgumentException();
9059            }
9060            r.immersive = immersive;
9061
9062            // update associated state if we're frontmost
9063            if (r == mFocusedActivity) {
9064                if (DEBUG_IMMERSIVE) {
9065                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9066                }
9067                applyUpdateLockStateLocked(r);
9068            }
9069        }
9070    }
9071
9072    @Override
9073    public boolean isImmersive(IBinder token) {
9074        synchronized (this) {
9075            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9076            if (r == null) {
9077                throw new IllegalArgumentException();
9078            }
9079            return r.immersive;
9080        }
9081    }
9082
9083    public boolean isTopActivityImmersive() {
9084        enforceNotIsolatedCaller("startActivity");
9085        synchronized (this) {
9086            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9087            return (r != null) ? r.immersive : false;
9088        }
9089    }
9090
9091    public final void enterSafeMode() {
9092        synchronized(this) {
9093            // It only makes sense to do this before the system is ready
9094            // and started launching other packages.
9095            if (!mSystemReady) {
9096                try {
9097                    AppGlobals.getPackageManager().enterSafeMode();
9098                } catch (RemoteException e) {
9099                }
9100            }
9101
9102            mSafeMode = true;
9103        }
9104    }
9105
9106    public final void showSafeModeOverlay() {
9107        View v = LayoutInflater.from(mContext).inflate(
9108                com.android.internal.R.layout.safe_mode, null);
9109        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9110        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9111        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9112        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9113        lp.gravity = Gravity.BOTTOM | Gravity.START;
9114        lp.format = v.getBackground().getOpacity();
9115        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9116                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9117        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9118        ((WindowManager)mContext.getSystemService(
9119                Context.WINDOW_SERVICE)).addView(v, lp);
9120    }
9121
9122    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9123        if (!(sender instanceof PendingIntentRecord)) {
9124            return;
9125        }
9126        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9127        synchronized (stats) {
9128            if (mBatteryStatsService.isOnBattery()) {
9129                mBatteryStatsService.enforceCallingPermission();
9130                PendingIntentRecord rec = (PendingIntentRecord)sender;
9131                int MY_UID = Binder.getCallingUid();
9132                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9133                BatteryStatsImpl.Uid.Pkg pkg =
9134                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9135                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9136                pkg.incWakeupsLocked();
9137            }
9138        }
9139    }
9140
9141    public boolean killPids(int[] pids, String pReason, boolean secure) {
9142        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9143            throw new SecurityException("killPids only available to the system");
9144        }
9145        String reason = (pReason == null) ? "Unknown" : pReason;
9146        // XXX Note: don't acquire main activity lock here, because the window
9147        // manager calls in with its locks held.
9148
9149        boolean killed = false;
9150        synchronized (mPidsSelfLocked) {
9151            int[] types = new int[pids.length];
9152            int worstType = 0;
9153            for (int i=0; i<pids.length; i++) {
9154                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9155                if (proc != null) {
9156                    int type = proc.setAdj;
9157                    types[i] = type;
9158                    if (type > worstType) {
9159                        worstType = type;
9160                    }
9161                }
9162            }
9163
9164            // If the worst oom_adj is somewhere in the cached proc LRU range,
9165            // then constrain it so we will kill all cached procs.
9166            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9167                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9168                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9169            }
9170
9171            // If this is not a secure call, don't let it kill processes that
9172            // are important.
9173            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9174                worstType = ProcessList.SERVICE_ADJ;
9175            }
9176
9177            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9178            for (int i=0; i<pids.length; i++) {
9179                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9180                if (proc == null) {
9181                    continue;
9182                }
9183                int adj = proc.setAdj;
9184                if (adj >= worstType && !proc.killedByAm) {
9185                    killUnneededProcessLocked(proc, reason);
9186                    killed = true;
9187                }
9188            }
9189        }
9190        return killed;
9191    }
9192
9193    @Override
9194    public void killUid(int uid, String reason) {
9195        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9196            throw new SecurityException("killUid only available to the system");
9197        }
9198        synchronized (this) {
9199            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9200                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9201                    reason != null ? reason : "kill uid");
9202        }
9203    }
9204
9205    @Override
9206    public boolean killProcessesBelowForeground(String reason) {
9207        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9208            throw new SecurityException("killProcessesBelowForeground() only available to system");
9209        }
9210
9211        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9212    }
9213
9214    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9215        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9216            throw new SecurityException("killProcessesBelowAdj() only available to system");
9217        }
9218
9219        boolean killed = false;
9220        synchronized (mPidsSelfLocked) {
9221            final int size = mPidsSelfLocked.size();
9222            for (int i = 0; i < size; i++) {
9223                final int pid = mPidsSelfLocked.keyAt(i);
9224                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9225                if (proc == null) continue;
9226
9227                final int adj = proc.setAdj;
9228                if (adj > belowAdj && !proc.killedByAm) {
9229                    killUnneededProcessLocked(proc, reason);
9230                    killed = true;
9231                }
9232            }
9233        }
9234        return killed;
9235    }
9236
9237    @Override
9238    public void hang(final IBinder who, boolean allowRestart) {
9239        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9240                != PackageManager.PERMISSION_GRANTED) {
9241            throw new SecurityException("Requires permission "
9242                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9243        }
9244
9245        final IBinder.DeathRecipient death = new DeathRecipient() {
9246            @Override
9247            public void binderDied() {
9248                synchronized (this) {
9249                    notifyAll();
9250                }
9251            }
9252        };
9253
9254        try {
9255            who.linkToDeath(death, 0);
9256        } catch (RemoteException e) {
9257            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9258            return;
9259        }
9260
9261        synchronized (this) {
9262            Watchdog.getInstance().setAllowRestart(allowRestart);
9263            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9264            synchronized (death) {
9265                while (who.isBinderAlive()) {
9266                    try {
9267                        death.wait();
9268                    } catch (InterruptedException e) {
9269                    }
9270                }
9271            }
9272            Watchdog.getInstance().setAllowRestart(true);
9273        }
9274    }
9275
9276    @Override
9277    public void restart() {
9278        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9279                != PackageManager.PERMISSION_GRANTED) {
9280            throw new SecurityException("Requires permission "
9281                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9282        }
9283
9284        Log.i(TAG, "Sending shutdown broadcast...");
9285
9286        BroadcastReceiver br = new BroadcastReceiver() {
9287            @Override public void onReceive(Context context, Intent intent) {
9288                // Now the broadcast is done, finish up the low-level shutdown.
9289                Log.i(TAG, "Shutting down activity manager...");
9290                shutdown(10000);
9291                Log.i(TAG, "Shutdown complete, restarting!");
9292                Process.killProcess(Process.myPid());
9293                System.exit(10);
9294            }
9295        };
9296
9297        // First send the high-level shut down broadcast.
9298        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9299        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9300        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9301        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9302        mContext.sendOrderedBroadcastAsUser(intent,
9303                UserHandle.ALL, null, br, mHandler, 0, null, null);
9304        */
9305        br.onReceive(mContext, intent);
9306    }
9307
9308    private long getLowRamTimeSinceIdle(long now) {
9309        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9310    }
9311
9312    @Override
9313    public void performIdleMaintenance() {
9314        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9315                != PackageManager.PERMISSION_GRANTED) {
9316            throw new SecurityException("Requires permission "
9317                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9318        }
9319
9320        synchronized (this) {
9321            final long now = SystemClock.uptimeMillis();
9322            final long timeSinceLastIdle = now - mLastIdleTime;
9323            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9324            mLastIdleTime = now;
9325            mLowRamTimeSinceLastIdle = 0;
9326            if (mLowRamStartTime != 0) {
9327                mLowRamStartTime = now;
9328            }
9329
9330            StringBuilder sb = new StringBuilder(128);
9331            sb.append("Idle maintenance over ");
9332            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9333            sb.append(" low RAM for ");
9334            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9335            Slog.i(TAG, sb.toString());
9336
9337            // If at least 1/3 of our time since the last idle period has been spent
9338            // with RAM low, then we want to kill processes.
9339            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9340
9341            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9342                ProcessRecord proc = mLruProcesses.get(i);
9343                if (proc.notCachedSinceIdle) {
9344                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9345                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9346                        if (doKilling && proc.initialIdlePss != 0
9347                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9348                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9349                                    + " from " + proc.initialIdlePss + ")");
9350                        }
9351                    }
9352                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9353                    proc.notCachedSinceIdle = true;
9354                    proc.initialIdlePss = 0;
9355                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9356                            mSleeping, now);
9357                }
9358            }
9359
9360            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9361            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9362        }
9363    }
9364
9365    private void retrieveSettings() {
9366        final ContentResolver resolver = mContext.getContentResolver();
9367        String debugApp = Settings.Global.getString(
9368            resolver, Settings.Global.DEBUG_APP);
9369        boolean waitForDebugger = Settings.Global.getInt(
9370            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9371        boolean alwaysFinishActivities = Settings.Global.getInt(
9372            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9373        boolean forceRtl = Settings.Global.getInt(
9374                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9375        // Transfer any global setting for forcing RTL layout, into a System Property
9376        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9377
9378        Configuration configuration = new Configuration();
9379        Settings.System.getConfiguration(resolver, configuration);
9380        if (forceRtl) {
9381            // This will take care of setting the correct layout direction flags
9382            configuration.setLayoutDirection(configuration.locale);
9383        }
9384
9385        synchronized (this) {
9386            mDebugApp = mOrigDebugApp = debugApp;
9387            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9388            mAlwaysFinishActivities = alwaysFinishActivities;
9389            // This happens before any activities are started, so we can
9390            // change mConfiguration in-place.
9391            updateConfigurationLocked(configuration, null, false, true);
9392            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9393        }
9394    }
9395
9396    public boolean testIsSystemReady() {
9397        // no need to synchronize(this) just to read & return the value
9398        return mSystemReady;
9399    }
9400
9401    private static File getCalledPreBootReceiversFile() {
9402        File dataDir = Environment.getDataDirectory();
9403        File systemDir = new File(dataDir, "system");
9404        File fname = new File(systemDir, "called_pre_boots.dat");
9405        return fname;
9406    }
9407
9408    static final int LAST_DONE_VERSION = 10000;
9409
9410    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9411        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9412        File file = getCalledPreBootReceiversFile();
9413        FileInputStream fis = null;
9414        try {
9415            fis = new FileInputStream(file);
9416            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9417            int fvers = dis.readInt();
9418            if (fvers == LAST_DONE_VERSION) {
9419                String vers = dis.readUTF();
9420                String codename = dis.readUTF();
9421                String build = dis.readUTF();
9422                if (android.os.Build.VERSION.RELEASE.equals(vers)
9423                        && android.os.Build.VERSION.CODENAME.equals(codename)
9424                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9425                    int num = dis.readInt();
9426                    while (num > 0) {
9427                        num--;
9428                        String pkg = dis.readUTF();
9429                        String cls = dis.readUTF();
9430                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9431                    }
9432                }
9433            }
9434        } catch (FileNotFoundException e) {
9435        } catch (IOException e) {
9436            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9437        } finally {
9438            if (fis != null) {
9439                try {
9440                    fis.close();
9441                } catch (IOException e) {
9442                }
9443            }
9444        }
9445        return lastDoneReceivers;
9446    }
9447
9448    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9449        File file = getCalledPreBootReceiversFile();
9450        FileOutputStream fos = null;
9451        DataOutputStream dos = null;
9452        try {
9453            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9454            fos = new FileOutputStream(file);
9455            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9456            dos.writeInt(LAST_DONE_VERSION);
9457            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9458            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9459            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9460            dos.writeInt(list.size());
9461            for (int i=0; i<list.size(); i++) {
9462                dos.writeUTF(list.get(i).getPackageName());
9463                dos.writeUTF(list.get(i).getClassName());
9464            }
9465        } catch (IOException e) {
9466            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9467            file.delete();
9468        } finally {
9469            FileUtils.sync(fos);
9470            if (dos != null) {
9471                try {
9472                    dos.close();
9473                } catch (IOException e) {
9474                    // TODO Auto-generated catch block
9475                    e.printStackTrace();
9476                }
9477            }
9478        }
9479    }
9480
9481    public void systemReady(final Runnable goingCallback) {
9482        synchronized(this) {
9483            if (mSystemReady) {
9484                if (goingCallback != null) goingCallback.run();
9485                return;
9486            }
9487
9488            // Check to see if there are any update receivers to run.
9489            if (!mDidUpdate) {
9490                if (mWaitingUpdate) {
9491                    return;
9492                }
9493                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9494                List<ResolveInfo> ris = null;
9495                try {
9496                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9497                            intent, null, 0, 0);
9498                } catch (RemoteException e) {
9499                }
9500                if (ris != null) {
9501                    for (int i=ris.size()-1; i>=0; i--) {
9502                        if ((ris.get(i).activityInfo.applicationInfo.flags
9503                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9504                            ris.remove(i);
9505                        }
9506                    }
9507                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9508
9509                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9510
9511                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9512                    for (int i=0; i<ris.size(); i++) {
9513                        ActivityInfo ai = ris.get(i).activityInfo;
9514                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9515                        if (lastDoneReceivers.contains(comp)) {
9516                            // We already did the pre boot receiver for this app with the current
9517                            // platform version, so don't do it again...
9518                            ris.remove(i);
9519                            i--;
9520                            // ...however, do keep it as one that has been done, so we don't
9521                            // forget about it when rewriting the file of last done receivers.
9522                            doneReceivers.add(comp);
9523                        }
9524                    }
9525
9526                    final int[] users = getUsersLocked();
9527                    for (int i=0; i<ris.size(); i++) {
9528                        ActivityInfo ai = ris.get(i).activityInfo;
9529                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9530                        doneReceivers.add(comp);
9531                        intent.setComponent(comp);
9532                        for (int j=0; j<users.length; j++) {
9533                            IIntentReceiver finisher = null;
9534                            if (i == ris.size()-1 && j == users.length-1) {
9535                                finisher = new IIntentReceiver.Stub() {
9536                                    public void performReceive(Intent intent, int resultCode,
9537                                            String data, Bundle extras, boolean ordered,
9538                                            boolean sticky, int sendingUser) {
9539                                        // The raw IIntentReceiver interface is called
9540                                        // with the AM lock held, so redispatch to
9541                                        // execute our code without the lock.
9542                                        mHandler.post(new Runnable() {
9543                                            public void run() {
9544                                                synchronized (ActivityManagerService.this) {
9545                                                    mDidUpdate = true;
9546                                                }
9547                                                writeLastDonePreBootReceivers(doneReceivers);
9548                                                showBootMessage(mContext.getText(
9549                                                        R.string.android_upgrading_complete),
9550                                                        false);
9551                                                systemReady(goingCallback);
9552                                            }
9553                                        });
9554                                    }
9555                                };
9556                            }
9557                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9558                                    + " for user " + users[j]);
9559                            broadcastIntentLocked(null, null, intent, null, finisher,
9560                                    0, null, null, null, AppOpsManager.OP_NONE,
9561                                    true, false, MY_PID, Process.SYSTEM_UID,
9562                                    users[j]);
9563                            if (finisher != null) {
9564                                mWaitingUpdate = true;
9565                            }
9566                        }
9567                    }
9568                }
9569                if (mWaitingUpdate) {
9570                    return;
9571                }
9572                mDidUpdate = true;
9573            }
9574
9575            mAppOpsService.systemReady();
9576            mSystemReady = true;
9577        }
9578
9579        ArrayList<ProcessRecord> procsToKill = null;
9580        synchronized(mPidsSelfLocked) {
9581            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9582                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9583                if (!isAllowedWhileBooting(proc.info)){
9584                    if (procsToKill == null) {
9585                        procsToKill = new ArrayList<ProcessRecord>();
9586                    }
9587                    procsToKill.add(proc);
9588                }
9589            }
9590        }
9591
9592        synchronized(this) {
9593            if (procsToKill != null) {
9594                for (int i=procsToKill.size()-1; i>=0; i--) {
9595                    ProcessRecord proc = procsToKill.get(i);
9596                    Slog.i(TAG, "Removing system update proc: " + proc);
9597                    removeProcessLocked(proc, true, false, "system update done");
9598                }
9599            }
9600
9601            // Now that we have cleaned up any update processes, we
9602            // are ready to start launching real processes and know that
9603            // we won't trample on them any more.
9604            mProcessesReady = true;
9605        }
9606
9607        Slog.i(TAG, "System now ready");
9608        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9609            SystemClock.uptimeMillis());
9610
9611        synchronized(this) {
9612            // Make sure we have no pre-ready processes sitting around.
9613
9614            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9615                ResolveInfo ri = mContext.getPackageManager()
9616                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9617                                STOCK_PM_FLAGS);
9618                CharSequence errorMsg = null;
9619                if (ri != null) {
9620                    ActivityInfo ai = ri.activityInfo;
9621                    ApplicationInfo app = ai.applicationInfo;
9622                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9623                        mTopAction = Intent.ACTION_FACTORY_TEST;
9624                        mTopData = null;
9625                        mTopComponent = new ComponentName(app.packageName,
9626                                ai.name);
9627                    } else {
9628                        errorMsg = mContext.getResources().getText(
9629                                com.android.internal.R.string.factorytest_not_system);
9630                    }
9631                } else {
9632                    errorMsg = mContext.getResources().getText(
9633                            com.android.internal.R.string.factorytest_no_action);
9634                }
9635                if (errorMsg != null) {
9636                    mTopAction = null;
9637                    mTopData = null;
9638                    mTopComponent = null;
9639                    Message msg = Message.obtain();
9640                    msg.what = SHOW_FACTORY_ERROR_MSG;
9641                    msg.getData().putCharSequence("msg", errorMsg);
9642                    mHandler.sendMessage(msg);
9643                }
9644            }
9645        }
9646
9647        retrieveSettings();
9648
9649        synchronized (this) {
9650            readGrantedUriPermissionsLocked();
9651        }
9652
9653        if (goingCallback != null) goingCallback.run();
9654
9655        synchronized (this) {
9656            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9657                try {
9658                    List apps = AppGlobals.getPackageManager().
9659                        getPersistentApplications(STOCK_PM_FLAGS);
9660                    if (apps != null) {
9661                        int N = apps.size();
9662                        int i;
9663                        for (i=0; i<N; i++) {
9664                            ApplicationInfo info
9665                                = (ApplicationInfo)apps.get(i);
9666                            if (info != null &&
9667                                    !info.packageName.equals("android")) {
9668                                addAppLocked(info, false);
9669                            }
9670                        }
9671                    }
9672                } catch (RemoteException ex) {
9673                    // pm is in same process, this will never happen.
9674                }
9675            }
9676
9677            // Start up initial activity.
9678            mBooting = true;
9679
9680            try {
9681                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9682                    Message msg = Message.obtain();
9683                    msg.what = SHOW_UID_ERROR_MSG;
9684                    mHandler.sendMessage(msg);
9685                }
9686            } catch (RemoteException e) {
9687            }
9688
9689            long ident = Binder.clearCallingIdentity();
9690            try {
9691                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9692                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9693                        | Intent.FLAG_RECEIVER_FOREGROUND);
9694                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9695                broadcastIntentLocked(null, null, intent,
9696                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9697                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9698                intent = new Intent(Intent.ACTION_USER_STARTING);
9699                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9700                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9701                broadcastIntentLocked(null, null, intent,
9702                        null, new IIntentReceiver.Stub() {
9703                            @Override
9704                            public void performReceive(Intent intent, int resultCode, String data,
9705                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9706                                    throws RemoteException {
9707                            }
9708                        }, 0, null, null,
9709                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9710                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9711            } finally {
9712                Binder.restoreCallingIdentity(ident);
9713            }
9714            mStackSupervisor.resumeTopActivitiesLocked();
9715            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9716        }
9717    }
9718
9719    private boolean makeAppCrashingLocked(ProcessRecord app,
9720            String shortMsg, String longMsg, String stackTrace) {
9721        app.crashing = true;
9722        app.crashingReport = generateProcessError(app,
9723                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9724        startAppProblemLocked(app);
9725        app.stopFreezingAllLocked();
9726        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9727    }
9728
9729    private void makeAppNotRespondingLocked(ProcessRecord app,
9730            String activity, String shortMsg, String longMsg) {
9731        app.notResponding = true;
9732        app.notRespondingReport = generateProcessError(app,
9733                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9734                activity, shortMsg, longMsg, null);
9735        startAppProblemLocked(app);
9736        app.stopFreezingAllLocked();
9737    }
9738
9739    /**
9740     * Generate a process error record, suitable for attachment to a ProcessRecord.
9741     *
9742     * @param app The ProcessRecord in which the error occurred.
9743     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9744     *                      ActivityManager.AppErrorStateInfo
9745     * @param activity The activity associated with the crash, if known.
9746     * @param shortMsg Short message describing the crash.
9747     * @param longMsg Long message describing the crash.
9748     * @param stackTrace Full crash stack trace, may be null.
9749     *
9750     * @return Returns a fully-formed AppErrorStateInfo record.
9751     */
9752    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9753            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9754        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9755
9756        report.condition = condition;
9757        report.processName = app.processName;
9758        report.pid = app.pid;
9759        report.uid = app.info.uid;
9760        report.tag = activity;
9761        report.shortMsg = shortMsg;
9762        report.longMsg = longMsg;
9763        report.stackTrace = stackTrace;
9764
9765        return report;
9766    }
9767
9768    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9769        synchronized (this) {
9770            app.crashing = false;
9771            app.crashingReport = null;
9772            app.notResponding = false;
9773            app.notRespondingReport = null;
9774            if (app.anrDialog == fromDialog) {
9775                app.anrDialog = null;
9776            }
9777            if (app.waitDialog == fromDialog) {
9778                app.waitDialog = null;
9779            }
9780            if (app.pid > 0 && app.pid != MY_PID) {
9781                handleAppCrashLocked(app, null, null, null);
9782                killUnneededProcessLocked(app, "user request after error");
9783            }
9784        }
9785    }
9786
9787    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9788            String stackTrace) {
9789        long now = SystemClock.uptimeMillis();
9790
9791        Long crashTime;
9792        if (!app.isolated) {
9793            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9794        } else {
9795            crashTime = null;
9796        }
9797        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9798            // This process loses!
9799            Slog.w(TAG, "Process " + app.info.processName
9800                    + " has crashed too many times: killing!");
9801            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9802                    app.userId, app.info.processName, app.uid);
9803            mStackSupervisor.handleAppCrashLocked(app);
9804            if (!app.persistent) {
9805                // We don't want to start this process again until the user
9806                // explicitly does so...  but for persistent process, we really
9807                // need to keep it running.  If a persistent process is actually
9808                // repeatedly crashing, then badness for everyone.
9809                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9810                        app.info.processName);
9811                if (!app.isolated) {
9812                    // XXX We don't have a way to mark isolated processes
9813                    // as bad, since they don't have a peristent identity.
9814                    mBadProcesses.put(app.info.processName, app.uid,
9815                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9816                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9817                }
9818                app.bad = true;
9819                app.removed = true;
9820                // Don't let services in this process be restarted and potentially
9821                // annoy the user repeatedly.  Unless it is persistent, since those
9822                // processes run critical code.
9823                removeProcessLocked(app, false, false, "crash");
9824                mStackSupervisor.resumeTopActivitiesLocked();
9825                return false;
9826            }
9827            mStackSupervisor.resumeTopActivitiesLocked();
9828        } else {
9829            mStackSupervisor.finishTopRunningActivityLocked(app);
9830        }
9831
9832        // Bump up the crash count of any services currently running in the proc.
9833        for (int i=app.services.size()-1; i>=0; i--) {
9834            // Any services running in the application need to be placed
9835            // back in the pending list.
9836            ServiceRecord sr = app.services.valueAt(i);
9837            sr.crashCount++;
9838        }
9839
9840        // If the crashing process is what we consider to be the "home process" and it has been
9841        // replaced by a third-party app, clear the package preferred activities from packages
9842        // with a home activity running in the process to prevent a repeatedly crashing app
9843        // from blocking the user to manually clear the list.
9844        final ArrayList<ActivityRecord> activities = app.activities;
9845        if (app == mHomeProcess && activities.size() > 0
9846                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9847            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9848                final ActivityRecord r = activities.get(activityNdx);
9849                if (r.isHomeActivity()) {
9850                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9851                    try {
9852                        ActivityThread.getPackageManager()
9853                                .clearPackagePreferredActivities(r.packageName);
9854                    } catch (RemoteException c) {
9855                        // pm is in same process, this will never happen.
9856                    }
9857                }
9858            }
9859        }
9860
9861        if (!app.isolated) {
9862            // XXX Can't keep track of crash times for isolated processes,
9863            // because they don't have a perisistent identity.
9864            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9865        }
9866
9867        return true;
9868    }
9869
9870    void startAppProblemLocked(ProcessRecord app) {
9871        if (app.userId == mCurrentUserId) {
9872            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9873                    mContext, app.info.packageName, app.info.flags);
9874        } else {
9875            // If this app is not running under the current user, then we
9876            // can't give it a report button because that would require
9877            // launching the report UI under a different user.
9878            app.errorReportReceiver = null;
9879        }
9880        skipCurrentReceiverLocked(app);
9881    }
9882
9883    void skipCurrentReceiverLocked(ProcessRecord app) {
9884        for (BroadcastQueue queue : mBroadcastQueues) {
9885            queue.skipCurrentReceiverLocked(app);
9886        }
9887    }
9888
9889    /**
9890     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9891     * The application process will exit immediately after this call returns.
9892     * @param app object of the crashing app, null for the system server
9893     * @param crashInfo describing the exception
9894     */
9895    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9896        ProcessRecord r = findAppProcess(app, "Crash");
9897        final String processName = app == null ? "system_server"
9898                : (r == null ? "unknown" : r.processName);
9899
9900        handleApplicationCrashInner("crash", r, processName, crashInfo);
9901    }
9902
9903    /* Native crash reporting uses this inner version because it needs to be somewhat
9904     * decoupled from the AM-managed cleanup lifecycle
9905     */
9906    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9907            ApplicationErrorReport.CrashInfo crashInfo) {
9908        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9909                UserHandle.getUserId(Binder.getCallingUid()), processName,
9910                r == null ? -1 : r.info.flags,
9911                crashInfo.exceptionClassName,
9912                crashInfo.exceptionMessage,
9913                crashInfo.throwFileName,
9914                crashInfo.throwLineNumber);
9915
9916        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9917
9918        crashApplication(r, crashInfo);
9919    }
9920
9921    public void handleApplicationStrictModeViolation(
9922            IBinder app,
9923            int violationMask,
9924            StrictMode.ViolationInfo info) {
9925        ProcessRecord r = findAppProcess(app, "StrictMode");
9926        if (r == null) {
9927            return;
9928        }
9929
9930        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9931            Integer stackFingerprint = info.hashCode();
9932            boolean logIt = true;
9933            synchronized (mAlreadyLoggedViolatedStacks) {
9934                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9935                    logIt = false;
9936                    // TODO: sub-sample into EventLog for these, with
9937                    // the info.durationMillis?  Then we'd get
9938                    // the relative pain numbers, without logging all
9939                    // the stack traces repeatedly.  We'd want to do
9940                    // likewise in the client code, which also does
9941                    // dup suppression, before the Binder call.
9942                } else {
9943                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9944                        mAlreadyLoggedViolatedStacks.clear();
9945                    }
9946                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9947                }
9948            }
9949            if (logIt) {
9950                logStrictModeViolationToDropBox(r, info);
9951            }
9952        }
9953
9954        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9955            AppErrorResult result = new AppErrorResult();
9956            synchronized (this) {
9957                final long origId = Binder.clearCallingIdentity();
9958
9959                Message msg = Message.obtain();
9960                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9961                HashMap<String, Object> data = new HashMap<String, Object>();
9962                data.put("result", result);
9963                data.put("app", r);
9964                data.put("violationMask", violationMask);
9965                data.put("info", info);
9966                msg.obj = data;
9967                mHandler.sendMessage(msg);
9968
9969                Binder.restoreCallingIdentity(origId);
9970            }
9971            int res = result.get();
9972            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9973        }
9974    }
9975
9976    // Depending on the policy in effect, there could be a bunch of
9977    // these in quick succession so we try to batch these together to
9978    // minimize disk writes, number of dropbox entries, and maximize
9979    // compression, by having more fewer, larger records.
9980    private void logStrictModeViolationToDropBox(
9981            ProcessRecord process,
9982            StrictMode.ViolationInfo info) {
9983        if (info == null) {
9984            return;
9985        }
9986        final boolean isSystemApp = process == null ||
9987                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9988                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9989        final String processName = process == null ? "unknown" : process.processName;
9990        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9991        final DropBoxManager dbox = (DropBoxManager)
9992                mContext.getSystemService(Context.DROPBOX_SERVICE);
9993
9994        // Exit early if the dropbox isn't configured to accept this report type.
9995        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9996
9997        boolean bufferWasEmpty;
9998        boolean needsFlush;
9999        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10000        synchronized (sb) {
10001            bufferWasEmpty = sb.length() == 0;
10002            appendDropBoxProcessHeaders(process, processName, sb);
10003            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10004            sb.append("System-App: ").append(isSystemApp).append("\n");
10005            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10006            if (info.violationNumThisLoop != 0) {
10007                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10008            }
10009            if (info.numAnimationsRunning != 0) {
10010                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10011            }
10012            if (info.broadcastIntentAction != null) {
10013                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10014            }
10015            if (info.durationMillis != -1) {
10016                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10017            }
10018            if (info.numInstances != -1) {
10019                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10020            }
10021            if (info.tags != null) {
10022                for (String tag : info.tags) {
10023                    sb.append("Span-Tag: ").append(tag).append("\n");
10024                }
10025            }
10026            sb.append("\n");
10027            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10028                sb.append(info.crashInfo.stackTrace);
10029            }
10030            sb.append("\n");
10031
10032            // Only buffer up to ~64k.  Various logging bits truncate
10033            // things at 128k.
10034            needsFlush = (sb.length() > 64 * 1024);
10035        }
10036
10037        // Flush immediately if the buffer's grown too large, or this
10038        // is a non-system app.  Non-system apps are isolated with a
10039        // different tag & policy and not batched.
10040        //
10041        // Batching is useful during internal testing with
10042        // StrictMode settings turned up high.  Without batching,
10043        // thousands of separate files could be created on boot.
10044        if (!isSystemApp || needsFlush) {
10045            new Thread("Error dump: " + dropboxTag) {
10046                @Override
10047                public void run() {
10048                    String report;
10049                    synchronized (sb) {
10050                        report = sb.toString();
10051                        sb.delete(0, sb.length());
10052                        sb.trimToSize();
10053                    }
10054                    if (report.length() != 0) {
10055                        dbox.addText(dropboxTag, report);
10056                    }
10057                }
10058            }.start();
10059            return;
10060        }
10061
10062        // System app batching:
10063        if (!bufferWasEmpty) {
10064            // An existing dropbox-writing thread is outstanding, so
10065            // we don't need to start it up.  The existing thread will
10066            // catch the buffer appends we just did.
10067            return;
10068        }
10069
10070        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10071        // (After this point, we shouldn't access AMS internal data structures.)
10072        new Thread("Error dump: " + dropboxTag) {
10073            @Override
10074            public void run() {
10075                // 5 second sleep to let stacks arrive and be batched together
10076                try {
10077                    Thread.sleep(5000);  // 5 seconds
10078                } catch (InterruptedException e) {}
10079
10080                String errorReport;
10081                synchronized (mStrictModeBuffer) {
10082                    errorReport = mStrictModeBuffer.toString();
10083                    if (errorReport.length() == 0) {
10084                        return;
10085                    }
10086                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10087                    mStrictModeBuffer.trimToSize();
10088                }
10089                dbox.addText(dropboxTag, errorReport);
10090            }
10091        }.start();
10092    }
10093
10094    /**
10095     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10096     * @param app object of the crashing app, null for the system server
10097     * @param tag reported by the caller
10098     * @param crashInfo describing the context of the error
10099     * @return true if the process should exit immediately (WTF is fatal)
10100     */
10101    public boolean handleApplicationWtf(IBinder app, String tag,
10102            ApplicationErrorReport.CrashInfo crashInfo) {
10103        ProcessRecord r = findAppProcess(app, "WTF");
10104        final String processName = app == null ? "system_server"
10105                : (r == null ? "unknown" : r.processName);
10106
10107        EventLog.writeEvent(EventLogTags.AM_WTF,
10108                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10109                processName,
10110                r == null ? -1 : r.info.flags,
10111                tag, crashInfo.exceptionMessage);
10112
10113        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10114
10115        if (r != null && r.pid != Process.myPid() &&
10116                Settings.Global.getInt(mContext.getContentResolver(),
10117                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10118            crashApplication(r, crashInfo);
10119            return true;
10120        } else {
10121            return false;
10122        }
10123    }
10124
10125    /**
10126     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10127     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10128     */
10129    private ProcessRecord findAppProcess(IBinder app, String reason) {
10130        if (app == null) {
10131            return null;
10132        }
10133
10134        synchronized (this) {
10135            final int NP = mProcessNames.getMap().size();
10136            for (int ip=0; ip<NP; ip++) {
10137                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10138                final int NA = apps.size();
10139                for (int ia=0; ia<NA; ia++) {
10140                    ProcessRecord p = apps.valueAt(ia);
10141                    if (p.thread != null && p.thread.asBinder() == app) {
10142                        return p;
10143                    }
10144                }
10145            }
10146
10147            Slog.w(TAG, "Can't find mystery application for " + reason
10148                    + " from pid=" + Binder.getCallingPid()
10149                    + " uid=" + Binder.getCallingUid() + ": " + app);
10150            return null;
10151        }
10152    }
10153
10154    /**
10155     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10156     * to append various headers to the dropbox log text.
10157     */
10158    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10159            StringBuilder sb) {
10160        // Watchdog thread ends up invoking this function (with
10161        // a null ProcessRecord) to add the stack file to dropbox.
10162        // Do not acquire a lock on this (am) in such cases, as it
10163        // could cause a potential deadlock, if and when watchdog
10164        // is invoked due to unavailability of lock on am and it
10165        // would prevent watchdog from killing system_server.
10166        if (process == null) {
10167            sb.append("Process: ").append(processName).append("\n");
10168            return;
10169        }
10170        // Note: ProcessRecord 'process' is guarded by the service
10171        // instance.  (notably process.pkgList, which could otherwise change
10172        // concurrently during execution of this method)
10173        synchronized (this) {
10174            sb.append("Process: ").append(processName).append("\n");
10175            int flags = process.info.flags;
10176            IPackageManager pm = AppGlobals.getPackageManager();
10177            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10178            for (int ip=0; ip<process.pkgList.size(); ip++) {
10179                String pkg = process.pkgList.keyAt(ip);
10180                sb.append("Package: ").append(pkg);
10181                try {
10182                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10183                    if (pi != null) {
10184                        sb.append(" v").append(pi.versionCode);
10185                        if (pi.versionName != null) {
10186                            sb.append(" (").append(pi.versionName).append(")");
10187                        }
10188                    }
10189                } catch (RemoteException e) {
10190                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10191                }
10192                sb.append("\n");
10193            }
10194        }
10195    }
10196
10197    private static String processClass(ProcessRecord process) {
10198        if (process == null || process.pid == MY_PID) {
10199            return "system_server";
10200        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10201            return "system_app";
10202        } else {
10203            return "data_app";
10204        }
10205    }
10206
10207    /**
10208     * Write a description of an error (crash, WTF, ANR) to the drop box.
10209     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10210     * @param process which caused the error, null means the system server
10211     * @param activity which triggered the error, null if unknown
10212     * @param parent activity related to the error, null if unknown
10213     * @param subject line related to the error, null if absent
10214     * @param report in long form describing the error, null if absent
10215     * @param logFile to include in the report, null if none
10216     * @param crashInfo giving an application stack trace, null if absent
10217     */
10218    public void addErrorToDropBox(String eventType,
10219            ProcessRecord process, String processName, ActivityRecord activity,
10220            ActivityRecord parent, String subject,
10221            final String report, final File logFile,
10222            final ApplicationErrorReport.CrashInfo crashInfo) {
10223        // NOTE -- this must never acquire the ActivityManagerService lock,
10224        // otherwise the watchdog may be prevented from resetting the system.
10225
10226        final String dropboxTag = processClass(process) + "_" + eventType;
10227        final DropBoxManager dbox = (DropBoxManager)
10228                mContext.getSystemService(Context.DROPBOX_SERVICE);
10229
10230        // Exit early if the dropbox isn't configured to accept this report type.
10231        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10232
10233        final StringBuilder sb = new StringBuilder(1024);
10234        appendDropBoxProcessHeaders(process, processName, sb);
10235        if (activity != null) {
10236            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10237        }
10238        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10239            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10240        }
10241        if (parent != null && parent != activity) {
10242            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10243        }
10244        if (subject != null) {
10245            sb.append("Subject: ").append(subject).append("\n");
10246        }
10247        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10248        if (Debug.isDebuggerConnected()) {
10249            sb.append("Debugger: Connected\n");
10250        }
10251        sb.append("\n");
10252
10253        // Do the rest in a worker thread to avoid blocking the caller on I/O
10254        // (After this point, we shouldn't access AMS internal data structures.)
10255        Thread worker = new Thread("Error dump: " + dropboxTag) {
10256            @Override
10257            public void run() {
10258                if (report != null) {
10259                    sb.append(report);
10260                }
10261                if (logFile != null) {
10262                    try {
10263                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10264                                    "\n\n[[TRUNCATED]]"));
10265                    } catch (IOException e) {
10266                        Slog.e(TAG, "Error reading " + logFile, e);
10267                    }
10268                }
10269                if (crashInfo != null && crashInfo.stackTrace != null) {
10270                    sb.append(crashInfo.stackTrace);
10271                }
10272
10273                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10274                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10275                if (lines > 0) {
10276                    sb.append("\n");
10277
10278                    // Merge several logcat streams, and take the last N lines
10279                    InputStreamReader input = null;
10280                    try {
10281                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10282                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10283                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10284
10285                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10286                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10287                        input = new InputStreamReader(logcat.getInputStream());
10288
10289                        int num;
10290                        char[] buf = new char[8192];
10291                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10292                    } catch (IOException e) {
10293                        Slog.e(TAG, "Error running logcat", e);
10294                    } finally {
10295                        if (input != null) try { input.close(); } catch (IOException e) {}
10296                    }
10297                }
10298
10299                dbox.addText(dropboxTag, sb.toString());
10300            }
10301        };
10302
10303        if (process == null) {
10304            // If process is null, we are being called from some internal code
10305            // and may be about to die -- run this synchronously.
10306            worker.run();
10307        } else {
10308            worker.start();
10309        }
10310    }
10311
10312    /**
10313     * Bring up the "unexpected error" dialog box for a crashing app.
10314     * Deal with edge cases (intercepts from instrumented applications,
10315     * ActivityController, error intent receivers, that sort of thing).
10316     * @param r the application crashing
10317     * @param crashInfo describing the failure
10318     */
10319    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10320        long timeMillis = System.currentTimeMillis();
10321        String shortMsg = crashInfo.exceptionClassName;
10322        String longMsg = crashInfo.exceptionMessage;
10323        String stackTrace = crashInfo.stackTrace;
10324        if (shortMsg != null && longMsg != null) {
10325            longMsg = shortMsg + ": " + longMsg;
10326        } else if (shortMsg != null) {
10327            longMsg = shortMsg;
10328        }
10329
10330        AppErrorResult result = new AppErrorResult();
10331        synchronized (this) {
10332            if (mController != null) {
10333                try {
10334                    String name = r != null ? r.processName : null;
10335                    int pid = r != null ? r.pid : Binder.getCallingPid();
10336                    if (!mController.appCrashed(name, pid,
10337                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10338                        Slog.w(TAG, "Force-killing crashed app " + name
10339                                + " at watcher's request");
10340                        Process.killProcess(pid);
10341                        return;
10342                    }
10343                } catch (RemoteException e) {
10344                    mController = null;
10345                    Watchdog.getInstance().setActivityController(null);
10346                }
10347            }
10348
10349            final long origId = Binder.clearCallingIdentity();
10350
10351            // If this process is running instrumentation, finish it.
10352            if (r != null && r.instrumentationClass != null) {
10353                Slog.w(TAG, "Error in app " + r.processName
10354                      + " running instrumentation " + r.instrumentationClass + ":");
10355                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10356                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10357                Bundle info = new Bundle();
10358                info.putString("shortMsg", shortMsg);
10359                info.putString("longMsg", longMsg);
10360                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10361                Binder.restoreCallingIdentity(origId);
10362                return;
10363            }
10364
10365            // If we can't identify the process or it's already exceeded its crash quota,
10366            // quit right away without showing a crash dialog.
10367            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10368                Binder.restoreCallingIdentity(origId);
10369                return;
10370            }
10371
10372            Message msg = Message.obtain();
10373            msg.what = SHOW_ERROR_MSG;
10374            HashMap data = new HashMap();
10375            data.put("result", result);
10376            data.put("app", r);
10377            msg.obj = data;
10378            mHandler.sendMessage(msg);
10379
10380            Binder.restoreCallingIdentity(origId);
10381        }
10382
10383        int res = result.get();
10384
10385        Intent appErrorIntent = null;
10386        synchronized (this) {
10387            if (r != null && !r.isolated) {
10388                // XXX Can't keep track of crash time for isolated processes,
10389                // since they don't have a persistent identity.
10390                mProcessCrashTimes.put(r.info.processName, r.uid,
10391                        SystemClock.uptimeMillis());
10392            }
10393            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10394                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10395            }
10396        }
10397
10398        if (appErrorIntent != null) {
10399            try {
10400                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10401            } catch (ActivityNotFoundException e) {
10402                Slog.w(TAG, "bug report receiver dissappeared", e);
10403            }
10404        }
10405    }
10406
10407    Intent createAppErrorIntentLocked(ProcessRecord r,
10408            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10409        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10410        if (report == null) {
10411            return null;
10412        }
10413        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10414        result.setComponent(r.errorReportReceiver);
10415        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10416        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10417        return result;
10418    }
10419
10420    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10421            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10422        if (r.errorReportReceiver == null) {
10423            return null;
10424        }
10425
10426        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10427            return null;
10428        }
10429
10430        ApplicationErrorReport report = new ApplicationErrorReport();
10431        report.packageName = r.info.packageName;
10432        report.installerPackageName = r.errorReportReceiver.getPackageName();
10433        report.processName = r.processName;
10434        report.time = timeMillis;
10435        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10436
10437        if (r.crashing || r.forceCrashReport) {
10438            report.type = ApplicationErrorReport.TYPE_CRASH;
10439            report.crashInfo = crashInfo;
10440        } else if (r.notResponding) {
10441            report.type = ApplicationErrorReport.TYPE_ANR;
10442            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10443
10444            report.anrInfo.activity = r.notRespondingReport.tag;
10445            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10446            report.anrInfo.info = r.notRespondingReport.longMsg;
10447        }
10448
10449        return report;
10450    }
10451
10452    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10453        enforceNotIsolatedCaller("getProcessesInErrorState");
10454        // assume our apps are happy - lazy create the list
10455        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10456
10457        final boolean allUsers = ActivityManager.checkUidPermission(
10458                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10459                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10460        int userId = UserHandle.getUserId(Binder.getCallingUid());
10461
10462        synchronized (this) {
10463
10464            // iterate across all processes
10465            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10466                ProcessRecord app = mLruProcesses.get(i);
10467                if (!allUsers && app.userId != userId) {
10468                    continue;
10469                }
10470                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10471                    // This one's in trouble, so we'll generate a report for it
10472                    // crashes are higher priority (in case there's a crash *and* an anr)
10473                    ActivityManager.ProcessErrorStateInfo report = null;
10474                    if (app.crashing) {
10475                        report = app.crashingReport;
10476                    } else if (app.notResponding) {
10477                        report = app.notRespondingReport;
10478                    }
10479
10480                    if (report != null) {
10481                        if (errList == null) {
10482                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10483                        }
10484                        errList.add(report);
10485                    } else {
10486                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10487                                " crashing = " + app.crashing +
10488                                " notResponding = " + app.notResponding);
10489                    }
10490                }
10491            }
10492        }
10493
10494        return errList;
10495    }
10496
10497    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10498        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10499            if (currApp != null) {
10500                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10501            }
10502            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10503        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10504            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10505        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10506            if (currApp != null) {
10507                currApp.lru = 0;
10508            }
10509            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10510        } else if (adj >= ProcessList.SERVICE_ADJ) {
10511            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10512        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10513            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10514        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10515            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10516        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10517            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10518        } else {
10519            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10520        }
10521    }
10522
10523    private void fillInProcMemInfo(ProcessRecord app,
10524            ActivityManager.RunningAppProcessInfo outInfo) {
10525        outInfo.pid = app.pid;
10526        outInfo.uid = app.info.uid;
10527        if (mHeavyWeightProcess == app) {
10528            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10529        }
10530        if (app.persistent) {
10531            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10532        }
10533        if (app.activities.size() > 0) {
10534            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10535        }
10536        outInfo.lastTrimLevel = app.trimMemoryLevel;
10537        int adj = app.curAdj;
10538        outInfo.importance = oomAdjToImportance(adj, outInfo);
10539        outInfo.importanceReasonCode = app.adjTypeCode;
10540    }
10541
10542    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10543        enforceNotIsolatedCaller("getRunningAppProcesses");
10544        // Lazy instantiation of list
10545        List<ActivityManager.RunningAppProcessInfo> runList = null;
10546        final boolean allUsers = ActivityManager.checkUidPermission(
10547                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10548                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10549        int userId = UserHandle.getUserId(Binder.getCallingUid());
10550        synchronized (this) {
10551            // Iterate across all processes
10552            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10553                ProcessRecord app = mLruProcesses.get(i);
10554                if (!allUsers && app.userId != userId) {
10555                    continue;
10556                }
10557                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10558                    // Generate process state info for running application
10559                    ActivityManager.RunningAppProcessInfo currApp =
10560                        new ActivityManager.RunningAppProcessInfo(app.processName,
10561                                app.pid, app.getPackageList());
10562                    fillInProcMemInfo(app, currApp);
10563                    if (app.adjSource instanceof ProcessRecord) {
10564                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10565                        currApp.importanceReasonImportance = oomAdjToImportance(
10566                                app.adjSourceOom, null);
10567                    } else if (app.adjSource instanceof ActivityRecord) {
10568                        ActivityRecord r = (ActivityRecord)app.adjSource;
10569                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10570                    }
10571                    if (app.adjTarget instanceof ComponentName) {
10572                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10573                    }
10574                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10575                    //        + " lru=" + currApp.lru);
10576                    if (runList == null) {
10577                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10578                    }
10579                    runList.add(currApp);
10580                }
10581            }
10582        }
10583        return runList;
10584    }
10585
10586    public List<ApplicationInfo> getRunningExternalApplications() {
10587        enforceNotIsolatedCaller("getRunningExternalApplications");
10588        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10589        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10590        if (runningApps != null && runningApps.size() > 0) {
10591            Set<String> extList = new HashSet<String>();
10592            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10593                if (app.pkgList != null) {
10594                    for (String pkg : app.pkgList) {
10595                        extList.add(pkg);
10596                    }
10597                }
10598            }
10599            IPackageManager pm = AppGlobals.getPackageManager();
10600            for (String pkg : extList) {
10601                try {
10602                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10603                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10604                        retList.add(info);
10605                    }
10606                } catch (RemoteException e) {
10607                }
10608            }
10609        }
10610        return retList;
10611    }
10612
10613    @Override
10614    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10615        enforceNotIsolatedCaller("getMyMemoryState");
10616        synchronized (this) {
10617            ProcessRecord proc;
10618            synchronized (mPidsSelfLocked) {
10619                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10620            }
10621            fillInProcMemInfo(proc, outInfo);
10622        }
10623    }
10624
10625    @Override
10626    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10627        if (checkCallingPermission(android.Manifest.permission.DUMP)
10628                != PackageManager.PERMISSION_GRANTED) {
10629            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10630                    + Binder.getCallingPid()
10631                    + ", uid=" + Binder.getCallingUid()
10632                    + " without permission "
10633                    + android.Manifest.permission.DUMP);
10634            return;
10635        }
10636
10637        boolean dumpAll = false;
10638        boolean dumpClient = false;
10639        String dumpPackage = null;
10640
10641        int opti = 0;
10642        while (opti < args.length) {
10643            String opt = args[opti];
10644            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10645                break;
10646            }
10647            opti++;
10648            if ("-a".equals(opt)) {
10649                dumpAll = true;
10650            } else if ("-c".equals(opt)) {
10651                dumpClient = true;
10652            } else if ("-h".equals(opt)) {
10653                pw.println("Activity manager dump options:");
10654                pw.println("  [-a] [-c] [-h] [cmd] ...");
10655                pw.println("  cmd may be one of:");
10656                pw.println("    a[ctivities]: activity stack state");
10657                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10658                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10659                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10660                pw.println("    o[om]: out of memory management");
10661                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10662                pw.println("    provider [COMP_SPEC]: provider client-side state");
10663                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10664                pw.println("    service [COMP_SPEC]: service client-side state");
10665                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10666                pw.println("    all: dump all activities");
10667                pw.println("    top: dump the top activity");
10668                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10669                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10670                pw.println("    a partial substring in a component name, a");
10671                pw.println("    hex object identifier.");
10672                pw.println("  -a: include all available server state.");
10673                pw.println("  -c: include client state.");
10674                return;
10675            } else {
10676                pw.println("Unknown argument: " + opt + "; use -h for help");
10677            }
10678        }
10679
10680        long origId = Binder.clearCallingIdentity();
10681        boolean more = false;
10682        // Is the caller requesting to dump a particular piece of data?
10683        if (opti < args.length) {
10684            String cmd = args[opti];
10685            opti++;
10686            if ("activities".equals(cmd) || "a".equals(cmd)) {
10687                synchronized (this) {
10688                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10689                }
10690            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10691                String[] newArgs;
10692                String name;
10693                if (opti >= args.length) {
10694                    name = null;
10695                    newArgs = EMPTY_STRING_ARRAY;
10696                } else {
10697                    name = args[opti];
10698                    opti++;
10699                    newArgs = new String[args.length - opti];
10700                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10701                            args.length - opti);
10702                }
10703                synchronized (this) {
10704                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10705                }
10706            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10707                String[] newArgs;
10708                String name;
10709                if (opti >= args.length) {
10710                    name = null;
10711                    newArgs = EMPTY_STRING_ARRAY;
10712                } else {
10713                    name = args[opti];
10714                    opti++;
10715                    newArgs = new String[args.length - opti];
10716                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10717                            args.length - opti);
10718                }
10719                synchronized (this) {
10720                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10721                }
10722            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10723                String[] newArgs;
10724                String name;
10725                if (opti >= args.length) {
10726                    name = null;
10727                    newArgs = EMPTY_STRING_ARRAY;
10728                } else {
10729                    name = args[opti];
10730                    opti++;
10731                    newArgs = new String[args.length - opti];
10732                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10733                            args.length - opti);
10734                }
10735                synchronized (this) {
10736                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10737                }
10738            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10739                synchronized (this) {
10740                    dumpOomLocked(fd, pw, args, opti, true);
10741                }
10742            } else if ("provider".equals(cmd)) {
10743                String[] newArgs;
10744                String name;
10745                if (opti >= args.length) {
10746                    name = null;
10747                    newArgs = EMPTY_STRING_ARRAY;
10748                } else {
10749                    name = args[opti];
10750                    opti++;
10751                    newArgs = new String[args.length - opti];
10752                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10753                }
10754                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10755                    pw.println("No providers match: " + name);
10756                    pw.println("Use -h for help.");
10757                }
10758            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10759                synchronized (this) {
10760                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10761                }
10762            } else if ("service".equals(cmd)) {
10763                String[] newArgs;
10764                String name;
10765                if (opti >= args.length) {
10766                    name = null;
10767                    newArgs = EMPTY_STRING_ARRAY;
10768                } else {
10769                    name = args[opti];
10770                    opti++;
10771                    newArgs = new String[args.length - opti];
10772                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10773                            args.length - opti);
10774                }
10775                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10776                    pw.println("No services match: " + name);
10777                    pw.println("Use -h for help.");
10778                }
10779            } else if ("package".equals(cmd)) {
10780                String[] newArgs;
10781                if (opti >= args.length) {
10782                    pw.println("package: no package name specified");
10783                    pw.println("Use -h for help.");
10784                } else {
10785                    dumpPackage = args[opti];
10786                    opti++;
10787                    newArgs = new String[args.length - opti];
10788                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10789                            args.length - opti);
10790                    args = newArgs;
10791                    opti = 0;
10792                    more = true;
10793                }
10794            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10795                synchronized (this) {
10796                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10797                }
10798            } else {
10799                // Dumping a single activity?
10800                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10801                    pw.println("Bad activity command, or no activities match: " + cmd);
10802                    pw.println("Use -h for help.");
10803                }
10804            }
10805            if (!more) {
10806                Binder.restoreCallingIdentity(origId);
10807                return;
10808            }
10809        }
10810
10811        // No piece of data specified, dump everything.
10812        synchronized (this) {
10813            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10814            pw.println();
10815            if (dumpAll) {
10816                pw.println("-------------------------------------------------------------------------------");
10817            }
10818            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10819            pw.println();
10820            if (dumpAll) {
10821                pw.println("-------------------------------------------------------------------------------");
10822            }
10823            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10824            pw.println();
10825            if (dumpAll) {
10826                pw.println("-------------------------------------------------------------------------------");
10827            }
10828            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10829            pw.println();
10830            if (dumpAll) {
10831                pw.println("-------------------------------------------------------------------------------");
10832            }
10833            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10834            pw.println();
10835            if (dumpAll) {
10836                pw.println("-------------------------------------------------------------------------------");
10837            }
10838            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10839        }
10840        Binder.restoreCallingIdentity(origId);
10841    }
10842
10843    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10844            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10845        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10846
10847        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10848                dumpPackage);
10849        boolean needSep = printedAnything;
10850
10851        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10852                dumpPackage, needSep, "  mFocusedActivity: ");
10853        if (printed) {
10854            printedAnything = true;
10855            needSep = false;
10856        }
10857
10858        if (dumpPackage == null) {
10859            if (needSep) {
10860                pw.println();
10861            }
10862            needSep = true;
10863            printedAnything = true;
10864            mStackSupervisor.dump(pw, "  ");
10865        }
10866
10867        if (mRecentTasks.size() > 0) {
10868            boolean printedHeader = false;
10869
10870            final int N = mRecentTasks.size();
10871            for (int i=0; i<N; i++) {
10872                TaskRecord tr = mRecentTasks.get(i);
10873                if (dumpPackage != null) {
10874                    if (tr.realActivity == null ||
10875                            !dumpPackage.equals(tr.realActivity)) {
10876                        continue;
10877                    }
10878                }
10879                if (!printedHeader) {
10880                    if (needSep) {
10881                        pw.println();
10882                    }
10883                    pw.println("  Recent tasks:");
10884                    printedHeader = true;
10885                    printedAnything = true;
10886                }
10887                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10888                        pw.println(tr);
10889                if (dumpAll) {
10890                    mRecentTasks.get(i).dump(pw, "    ");
10891                }
10892            }
10893        }
10894
10895        if (!printedAnything) {
10896            pw.println("  (nothing)");
10897        }
10898    }
10899
10900    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10901            int opti, boolean dumpAll, String dumpPackage) {
10902        boolean needSep = false;
10903        boolean printedAnything = false;
10904        int numPers = 0;
10905
10906        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10907
10908        if (dumpAll) {
10909            final int NP = mProcessNames.getMap().size();
10910            for (int ip=0; ip<NP; ip++) {
10911                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10912                final int NA = procs.size();
10913                for (int ia=0; ia<NA; ia++) {
10914                    ProcessRecord r = procs.valueAt(ia);
10915                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10916                        continue;
10917                    }
10918                    if (!needSep) {
10919                        pw.println("  All known processes:");
10920                        needSep = true;
10921                        printedAnything = true;
10922                    }
10923                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10924                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10925                        pw.print(" "); pw.println(r);
10926                    r.dump(pw, "    ");
10927                    if (r.persistent) {
10928                        numPers++;
10929                    }
10930                }
10931            }
10932        }
10933
10934        if (mIsolatedProcesses.size() > 0) {
10935            boolean printed = false;
10936            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10937                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10938                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10939                    continue;
10940                }
10941                if (!printed) {
10942                    if (needSep) {
10943                        pw.println();
10944                    }
10945                    pw.println("  Isolated process list (sorted by uid):");
10946                    printedAnything = true;
10947                    printed = true;
10948                    needSep = true;
10949                }
10950                pw.println(String.format("%sIsolated #%2d: %s",
10951                        "    ", i, r.toString()));
10952            }
10953        }
10954
10955        if (mLruProcesses.size() > 0) {
10956            if (needSep) {
10957                pw.println();
10958            }
10959            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10960                    pw.print(" total, non-act at ");
10961                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10962                    pw.print(", non-svc at ");
10963                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10964                    pw.println("):");
10965            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10966            needSep = true;
10967            printedAnything = true;
10968        }
10969
10970        if (dumpAll || dumpPackage != null) {
10971            synchronized (mPidsSelfLocked) {
10972                boolean printed = false;
10973                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10974                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10975                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10976                        continue;
10977                    }
10978                    if (!printed) {
10979                        if (needSep) pw.println();
10980                        needSep = true;
10981                        pw.println("  PID mappings:");
10982                        printed = true;
10983                        printedAnything = true;
10984                    }
10985                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10986                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10987                }
10988            }
10989        }
10990
10991        if (mForegroundProcesses.size() > 0) {
10992            synchronized (mPidsSelfLocked) {
10993                boolean printed = false;
10994                for (int i=0; i<mForegroundProcesses.size(); i++) {
10995                    ProcessRecord r = mPidsSelfLocked.get(
10996                            mForegroundProcesses.valueAt(i).pid);
10997                    if (dumpPackage != null && (r == null
10998                            || !r.pkgList.containsKey(dumpPackage))) {
10999                        continue;
11000                    }
11001                    if (!printed) {
11002                        if (needSep) pw.println();
11003                        needSep = true;
11004                        pw.println("  Foreground Processes:");
11005                        printed = true;
11006                        printedAnything = true;
11007                    }
11008                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11009                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11010                }
11011            }
11012        }
11013
11014        if (mPersistentStartingProcesses.size() > 0) {
11015            if (needSep) pw.println();
11016            needSep = true;
11017            printedAnything = true;
11018            pw.println("  Persisent processes that are starting:");
11019            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11020                    "Starting Norm", "Restarting PERS", dumpPackage);
11021        }
11022
11023        if (mRemovedProcesses.size() > 0) {
11024            if (needSep) pw.println();
11025            needSep = true;
11026            printedAnything = true;
11027            pw.println("  Processes that are being removed:");
11028            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11029                    "Removed Norm", "Removed PERS", dumpPackage);
11030        }
11031
11032        if (mProcessesOnHold.size() > 0) {
11033            if (needSep) pw.println();
11034            needSep = true;
11035            printedAnything = true;
11036            pw.println("  Processes that are on old until the system is ready:");
11037            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11038                    "OnHold Norm", "OnHold PERS", dumpPackage);
11039        }
11040
11041        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11042
11043        if (mProcessCrashTimes.getMap().size() > 0) {
11044            boolean printed = false;
11045            long now = SystemClock.uptimeMillis();
11046            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11047            final int NP = pmap.size();
11048            for (int ip=0; ip<NP; ip++) {
11049                String pname = pmap.keyAt(ip);
11050                SparseArray<Long> uids = pmap.valueAt(ip);
11051                final int N = uids.size();
11052                for (int i=0; i<N; i++) {
11053                    int puid = uids.keyAt(i);
11054                    ProcessRecord r = mProcessNames.get(pname, puid);
11055                    if (dumpPackage != null && (r == null
11056                            || !r.pkgList.containsKey(dumpPackage))) {
11057                        continue;
11058                    }
11059                    if (!printed) {
11060                        if (needSep) pw.println();
11061                        needSep = true;
11062                        pw.println("  Time since processes crashed:");
11063                        printed = true;
11064                        printedAnything = true;
11065                    }
11066                    pw.print("    Process "); pw.print(pname);
11067                            pw.print(" uid "); pw.print(puid);
11068                            pw.print(": last crashed ");
11069                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11070                            pw.println(" ago");
11071                }
11072            }
11073        }
11074
11075        if (mBadProcesses.getMap().size() > 0) {
11076            boolean printed = false;
11077            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11078            final int NP = pmap.size();
11079            for (int ip=0; ip<NP; ip++) {
11080                String pname = pmap.keyAt(ip);
11081                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11082                final int N = uids.size();
11083                for (int i=0; i<N; i++) {
11084                    int puid = uids.keyAt(i);
11085                    ProcessRecord r = mProcessNames.get(pname, puid);
11086                    if (dumpPackage != null && (r == null
11087                            || !r.pkgList.containsKey(dumpPackage))) {
11088                        continue;
11089                    }
11090                    if (!printed) {
11091                        if (needSep) pw.println();
11092                        needSep = true;
11093                        pw.println("  Bad processes:");
11094                        printedAnything = true;
11095                    }
11096                    BadProcessInfo info = uids.valueAt(i);
11097                    pw.print("    Bad process "); pw.print(pname);
11098                            pw.print(" uid "); pw.print(puid);
11099                            pw.print(": crashed at time "); pw.println(info.time);
11100                    if (info.shortMsg != null) {
11101                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11102                    }
11103                    if (info.longMsg != null) {
11104                        pw.print("      Long msg: "); pw.println(info.longMsg);
11105                    }
11106                    if (info.stack != null) {
11107                        pw.println("      Stack:");
11108                        int lastPos = 0;
11109                        for (int pos=0; pos<info.stack.length(); pos++) {
11110                            if (info.stack.charAt(pos) == '\n') {
11111                                pw.print("        ");
11112                                pw.write(info.stack, lastPos, pos-lastPos);
11113                                pw.println();
11114                                lastPos = pos+1;
11115                            }
11116                        }
11117                        if (lastPos < info.stack.length()) {
11118                            pw.print("        ");
11119                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11120                            pw.println();
11121                        }
11122                    }
11123                }
11124            }
11125        }
11126
11127        if (dumpPackage == null) {
11128            pw.println();
11129            needSep = false;
11130            pw.println("  mStartedUsers:");
11131            for (int i=0; i<mStartedUsers.size(); i++) {
11132                UserStartedState uss = mStartedUsers.valueAt(i);
11133                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11134                        pw.print(": "); uss.dump("", pw);
11135            }
11136            pw.print("  mStartedUserArray: [");
11137            for (int i=0; i<mStartedUserArray.length; i++) {
11138                if (i > 0) pw.print(", ");
11139                pw.print(mStartedUserArray[i]);
11140            }
11141            pw.println("]");
11142            pw.print("  mUserLru: [");
11143            for (int i=0; i<mUserLru.size(); i++) {
11144                if (i > 0) pw.print(", ");
11145                pw.print(mUserLru.get(i));
11146            }
11147            pw.println("]");
11148            if (dumpAll) {
11149                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11150            }
11151        }
11152        if (mHomeProcess != null && (dumpPackage == null
11153                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11154            if (needSep) {
11155                pw.println();
11156                needSep = false;
11157            }
11158            pw.println("  mHomeProcess: " + mHomeProcess);
11159        }
11160        if (mPreviousProcess != null && (dumpPackage == null
11161                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11162            if (needSep) {
11163                pw.println();
11164                needSep = false;
11165            }
11166            pw.println("  mPreviousProcess: " + mPreviousProcess);
11167        }
11168        if (dumpAll) {
11169            StringBuilder sb = new StringBuilder(128);
11170            sb.append("  mPreviousProcessVisibleTime: ");
11171            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11172            pw.println(sb);
11173        }
11174        if (mHeavyWeightProcess != null && (dumpPackage == null
11175                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11176            if (needSep) {
11177                pw.println();
11178                needSep = false;
11179            }
11180            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11181        }
11182        if (dumpPackage == null) {
11183            pw.println("  mConfiguration: " + mConfiguration);
11184        }
11185        if (dumpAll) {
11186            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11187            if (mCompatModePackages.getPackages().size() > 0) {
11188                boolean printed = false;
11189                for (Map.Entry<String, Integer> entry
11190                        : mCompatModePackages.getPackages().entrySet()) {
11191                    String pkg = entry.getKey();
11192                    int mode = entry.getValue();
11193                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11194                        continue;
11195                    }
11196                    if (!printed) {
11197                        pw.println("  mScreenCompatPackages:");
11198                        printed = true;
11199                    }
11200                    pw.print("    "); pw.print(pkg); pw.print(": ");
11201                            pw.print(mode); pw.println();
11202                }
11203            }
11204        }
11205        if (dumpPackage == null) {
11206            if (mSleeping || mWentToSleep || mLockScreenShown) {
11207                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11208                        + " mLockScreenShown " + mLockScreenShown);
11209            }
11210            if (mShuttingDown) {
11211                pw.println("  mShuttingDown=" + mShuttingDown);
11212            }
11213        }
11214        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11215                || mOrigWaitForDebugger) {
11216            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11217                    || dumpPackage.equals(mOrigDebugApp)) {
11218                if (needSep) {
11219                    pw.println();
11220                    needSep = false;
11221                }
11222                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11223                        + " mDebugTransient=" + mDebugTransient
11224                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11225            }
11226        }
11227        if (mOpenGlTraceApp != null) {
11228            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11229                if (needSep) {
11230                    pw.println();
11231                    needSep = false;
11232                }
11233                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11234            }
11235        }
11236        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11237                || mProfileFd != null) {
11238            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11239                if (needSep) {
11240                    pw.println();
11241                    needSep = false;
11242                }
11243                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11244                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11245                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11246                        + mAutoStopProfiler);
11247            }
11248        }
11249        if (dumpPackage == null) {
11250            if (mAlwaysFinishActivities || mController != null) {
11251                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11252                        + " mController=" + mController);
11253            }
11254            if (dumpAll) {
11255                pw.println("  Total persistent processes: " + numPers);
11256                pw.println("  mProcessesReady=" + mProcessesReady
11257                        + " mSystemReady=" + mSystemReady);
11258                pw.println("  mBooting=" + mBooting
11259                        + " mBooted=" + mBooted
11260                        + " mFactoryTest=" + mFactoryTest);
11261                pw.print("  mLastPowerCheckRealtime=");
11262                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11263                        pw.println("");
11264                pw.print("  mLastPowerCheckUptime=");
11265                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11266                        pw.println("");
11267                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11268                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11269                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11270                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11271                        + " (" + mLruProcesses.size() + " total)"
11272                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11273                        + " mNumServiceProcs=" + mNumServiceProcs
11274                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11275                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11276                        + " mLastMemoryLevel" + mLastMemoryLevel
11277                        + " mLastNumProcesses" + mLastNumProcesses);
11278                long now = SystemClock.uptimeMillis();
11279                pw.print("  mLastIdleTime=");
11280                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11281                        pw.print(" mLowRamSinceLastIdle=");
11282                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11283                        pw.println();
11284            }
11285        }
11286
11287        if (!printedAnything) {
11288            pw.println("  (nothing)");
11289        }
11290    }
11291
11292    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11293            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11294        if (mProcessesToGc.size() > 0) {
11295            boolean printed = false;
11296            long now = SystemClock.uptimeMillis();
11297            for (int i=0; i<mProcessesToGc.size(); i++) {
11298                ProcessRecord proc = mProcessesToGc.get(i);
11299                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11300                    continue;
11301                }
11302                if (!printed) {
11303                    if (needSep) pw.println();
11304                    needSep = true;
11305                    pw.println("  Processes that are waiting to GC:");
11306                    printed = true;
11307                }
11308                pw.print("    Process "); pw.println(proc);
11309                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11310                        pw.print(", last gced=");
11311                        pw.print(now-proc.lastRequestedGc);
11312                        pw.print(" ms ago, last lowMem=");
11313                        pw.print(now-proc.lastLowMemory);
11314                        pw.println(" ms ago");
11315
11316            }
11317        }
11318        return needSep;
11319    }
11320
11321    void printOomLevel(PrintWriter pw, String name, int adj) {
11322        pw.print("    ");
11323        if (adj >= 0) {
11324            pw.print(' ');
11325            if (adj < 10) pw.print(' ');
11326        } else {
11327            if (adj > -10) pw.print(' ');
11328        }
11329        pw.print(adj);
11330        pw.print(": ");
11331        pw.print(name);
11332        pw.print(" (");
11333        pw.print(mProcessList.getMemLevel(adj)/1024);
11334        pw.println(" kB)");
11335    }
11336
11337    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11338            int opti, boolean dumpAll) {
11339        boolean needSep = false;
11340
11341        if (mLruProcesses.size() > 0) {
11342            if (needSep) pw.println();
11343            needSep = true;
11344            pw.println("  OOM levels:");
11345            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11346            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11347            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11348            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11349            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11350            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11351            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11352            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11353            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11354            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11355            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11356            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11357            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11358
11359            if (needSep) pw.println();
11360            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11361                    pw.print(" total, non-act at ");
11362                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11363                    pw.print(", non-svc at ");
11364                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11365                    pw.println("):");
11366            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11367            needSep = true;
11368        }
11369
11370        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11371
11372        pw.println();
11373        pw.println("  mHomeProcess: " + mHomeProcess);
11374        pw.println("  mPreviousProcess: " + mPreviousProcess);
11375        if (mHeavyWeightProcess != null) {
11376            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11377        }
11378
11379        return true;
11380    }
11381
11382    /**
11383     * There are three ways to call this:
11384     *  - no provider specified: dump all the providers
11385     *  - a flattened component name that matched an existing provider was specified as the
11386     *    first arg: dump that one provider
11387     *  - the first arg isn't the flattened component name of an existing provider:
11388     *    dump all providers whose component contains the first arg as a substring
11389     */
11390    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11391            int opti, boolean dumpAll) {
11392        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11393    }
11394
11395    static class ItemMatcher {
11396        ArrayList<ComponentName> components;
11397        ArrayList<String> strings;
11398        ArrayList<Integer> objects;
11399        boolean all;
11400
11401        ItemMatcher() {
11402            all = true;
11403        }
11404
11405        void build(String name) {
11406            ComponentName componentName = ComponentName.unflattenFromString(name);
11407            if (componentName != null) {
11408                if (components == null) {
11409                    components = new ArrayList<ComponentName>();
11410                }
11411                components.add(componentName);
11412                all = false;
11413            } else {
11414                int objectId = 0;
11415                // Not a '/' separated full component name; maybe an object ID?
11416                try {
11417                    objectId = Integer.parseInt(name, 16);
11418                    if (objects == null) {
11419                        objects = new ArrayList<Integer>();
11420                    }
11421                    objects.add(objectId);
11422                    all = false;
11423                } catch (RuntimeException e) {
11424                    // Not an integer; just do string match.
11425                    if (strings == null) {
11426                        strings = new ArrayList<String>();
11427                    }
11428                    strings.add(name);
11429                    all = false;
11430                }
11431            }
11432        }
11433
11434        int build(String[] args, int opti) {
11435            for (; opti<args.length; opti++) {
11436                String name = args[opti];
11437                if ("--".equals(name)) {
11438                    return opti+1;
11439                }
11440                build(name);
11441            }
11442            return opti;
11443        }
11444
11445        boolean match(Object object, ComponentName comp) {
11446            if (all) {
11447                return true;
11448            }
11449            if (components != null) {
11450                for (int i=0; i<components.size(); i++) {
11451                    if (components.get(i).equals(comp)) {
11452                        return true;
11453                    }
11454                }
11455            }
11456            if (objects != null) {
11457                for (int i=0; i<objects.size(); i++) {
11458                    if (System.identityHashCode(object) == objects.get(i)) {
11459                        return true;
11460                    }
11461                }
11462            }
11463            if (strings != null) {
11464                String flat = comp.flattenToString();
11465                for (int i=0; i<strings.size(); i++) {
11466                    if (flat.contains(strings.get(i))) {
11467                        return true;
11468                    }
11469                }
11470            }
11471            return false;
11472        }
11473    }
11474
11475    /**
11476     * There are three things that cmd can be:
11477     *  - a flattened component name that matches an existing activity
11478     *  - the cmd arg isn't the flattened component name of an existing activity:
11479     *    dump all activity whose component contains the cmd as a substring
11480     *  - A hex number of the ActivityRecord object instance.
11481     */
11482    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11483            int opti, boolean dumpAll) {
11484        ArrayList<ActivityRecord> activities;
11485
11486        synchronized (this) {
11487            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11488        }
11489
11490        if (activities.size() <= 0) {
11491            return false;
11492        }
11493
11494        String[] newArgs = new String[args.length - opti];
11495        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11496
11497        TaskRecord lastTask = null;
11498        boolean needSep = false;
11499        for (int i=activities.size()-1; i>=0; i--) {
11500            ActivityRecord r = activities.get(i);
11501            if (needSep) {
11502                pw.println();
11503            }
11504            needSep = true;
11505            synchronized (this) {
11506                if (lastTask != r.task) {
11507                    lastTask = r.task;
11508                    pw.print("TASK "); pw.print(lastTask.affinity);
11509                            pw.print(" id="); pw.println(lastTask.taskId);
11510                    if (dumpAll) {
11511                        lastTask.dump(pw, "  ");
11512                    }
11513                }
11514            }
11515            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11516        }
11517        return true;
11518    }
11519
11520    /**
11521     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11522     * there is a thread associated with the activity.
11523     */
11524    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11525            final ActivityRecord r, String[] args, boolean dumpAll) {
11526        String innerPrefix = prefix + "  ";
11527        synchronized (this) {
11528            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11529                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11530                    pw.print(" pid=");
11531                    if (r.app != null) pw.println(r.app.pid);
11532                    else pw.println("(not running)");
11533            if (dumpAll) {
11534                r.dump(pw, innerPrefix);
11535            }
11536        }
11537        if (r.app != null && r.app.thread != null) {
11538            // flush anything that is already in the PrintWriter since the thread is going
11539            // to write to the file descriptor directly
11540            pw.flush();
11541            try {
11542                TransferPipe tp = new TransferPipe();
11543                try {
11544                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11545                            r.appToken, innerPrefix, args);
11546                    tp.go(fd);
11547                } finally {
11548                    tp.kill();
11549                }
11550            } catch (IOException e) {
11551                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11552            } catch (RemoteException e) {
11553                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11554            }
11555        }
11556    }
11557
11558    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11559            int opti, boolean dumpAll, String dumpPackage) {
11560        boolean needSep = false;
11561        boolean onlyHistory = false;
11562        boolean printedAnything = false;
11563
11564        if ("history".equals(dumpPackage)) {
11565            if (opti < args.length && "-s".equals(args[opti])) {
11566                dumpAll = false;
11567            }
11568            onlyHistory = true;
11569            dumpPackage = null;
11570        }
11571
11572        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11573        if (!onlyHistory && dumpAll) {
11574            if (mRegisteredReceivers.size() > 0) {
11575                boolean printed = false;
11576                Iterator it = mRegisteredReceivers.values().iterator();
11577                while (it.hasNext()) {
11578                    ReceiverList r = (ReceiverList)it.next();
11579                    if (dumpPackage != null && (r.app == null ||
11580                            !dumpPackage.equals(r.app.info.packageName))) {
11581                        continue;
11582                    }
11583                    if (!printed) {
11584                        pw.println("  Registered Receivers:");
11585                        needSep = true;
11586                        printed = true;
11587                        printedAnything = true;
11588                    }
11589                    pw.print("  * "); pw.println(r);
11590                    r.dump(pw, "    ");
11591                }
11592            }
11593
11594            if (mReceiverResolver.dump(pw, needSep ?
11595                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11596                    "    ", dumpPackage, false)) {
11597                needSep = true;
11598                printedAnything = true;
11599            }
11600        }
11601
11602        for (BroadcastQueue q : mBroadcastQueues) {
11603            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11604            printedAnything |= needSep;
11605        }
11606
11607        needSep = true;
11608
11609        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11610            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11611                if (needSep) {
11612                    pw.println();
11613                }
11614                needSep = true;
11615                printedAnything = true;
11616                pw.print("  Sticky broadcasts for user ");
11617                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11618                StringBuilder sb = new StringBuilder(128);
11619                for (Map.Entry<String, ArrayList<Intent>> ent
11620                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11621                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11622                    if (dumpAll) {
11623                        pw.println(":");
11624                        ArrayList<Intent> intents = ent.getValue();
11625                        final int N = intents.size();
11626                        for (int i=0; i<N; i++) {
11627                            sb.setLength(0);
11628                            sb.append("    Intent: ");
11629                            intents.get(i).toShortString(sb, false, true, false, false);
11630                            pw.println(sb.toString());
11631                            Bundle bundle = intents.get(i).getExtras();
11632                            if (bundle != null) {
11633                                pw.print("      ");
11634                                pw.println(bundle.toString());
11635                            }
11636                        }
11637                    } else {
11638                        pw.println("");
11639                    }
11640                }
11641            }
11642        }
11643
11644        if (!onlyHistory && dumpAll) {
11645            pw.println();
11646            for (BroadcastQueue queue : mBroadcastQueues) {
11647                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11648                        + queue.mBroadcastsScheduled);
11649            }
11650            pw.println("  mHandler:");
11651            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11652            needSep = true;
11653            printedAnything = true;
11654        }
11655
11656        if (!printedAnything) {
11657            pw.println("  (nothing)");
11658        }
11659    }
11660
11661    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11662            int opti, boolean dumpAll, String dumpPackage) {
11663        boolean needSep;
11664        boolean printedAnything = false;
11665
11666        ItemMatcher matcher = new ItemMatcher();
11667        matcher.build(args, opti);
11668
11669        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11670
11671        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11672        printedAnything |= needSep;
11673
11674        if (mLaunchingProviders.size() > 0) {
11675            boolean printed = false;
11676            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11677                ContentProviderRecord r = mLaunchingProviders.get(i);
11678                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11679                    continue;
11680                }
11681                if (!printed) {
11682                    if (needSep) pw.println();
11683                    needSep = true;
11684                    pw.println("  Launching content providers:");
11685                    printed = true;
11686                    printedAnything = true;
11687                }
11688                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11689                        pw.println(r);
11690            }
11691        }
11692
11693        if (mGrantedUriPermissions.size() > 0) {
11694            boolean printed = false;
11695            int dumpUid = -2;
11696            if (dumpPackage != null) {
11697                try {
11698                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11699                } catch (NameNotFoundException e) {
11700                    dumpUid = -1;
11701                }
11702            }
11703            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11704                int uid = mGrantedUriPermissions.keyAt(i);
11705                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11706                    continue;
11707                }
11708                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11709                if (!printed) {
11710                    if (needSep) pw.println();
11711                    needSep = true;
11712                    pw.println("  Granted Uri Permissions:");
11713                    printed = true;
11714                    printedAnything = true;
11715                }
11716                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11717                for (UriPermission perm : perms.values()) {
11718                    pw.print("    "); pw.println(perm);
11719                    if (dumpAll) {
11720                        perm.dump(pw, "      ");
11721                    }
11722                }
11723            }
11724        }
11725
11726        if (!printedAnything) {
11727            pw.println("  (nothing)");
11728        }
11729    }
11730
11731    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11732            int opti, boolean dumpAll, String dumpPackage) {
11733        boolean printed = false;
11734
11735        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11736
11737        if (mIntentSenderRecords.size() > 0) {
11738            Iterator<WeakReference<PendingIntentRecord>> it
11739                    = mIntentSenderRecords.values().iterator();
11740            while (it.hasNext()) {
11741                WeakReference<PendingIntentRecord> ref = it.next();
11742                PendingIntentRecord rec = ref != null ? ref.get(): null;
11743                if (dumpPackage != null && (rec == null
11744                        || !dumpPackage.equals(rec.key.packageName))) {
11745                    continue;
11746                }
11747                printed = true;
11748                if (rec != null) {
11749                    pw.print("  * "); pw.println(rec);
11750                    if (dumpAll) {
11751                        rec.dump(pw, "    ");
11752                    }
11753                } else {
11754                    pw.print("  * "); pw.println(ref);
11755                }
11756            }
11757        }
11758
11759        if (!printed) {
11760            pw.println("  (nothing)");
11761        }
11762    }
11763
11764    private static final int dumpProcessList(PrintWriter pw,
11765            ActivityManagerService service, List list,
11766            String prefix, String normalLabel, String persistentLabel,
11767            String dumpPackage) {
11768        int numPers = 0;
11769        final int N = list.size()-1;
11770        for (int i=N; i>=0; i--) {
11771            ProcessRecord r = (ProcessRecord)list.get(i);
11772            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11773                continue;
11774            }
11775            pw.println(String.format("%s%s #%2d: %s",
11776                    prefix, (r.persistent ? persistentLabel : normalLabel),
11777                    i, r.toString()));
11778            if (r.persistent) {
11779                numPers++;
11780            }
11781        }
11782        return numPers;
11783    }
11784
11785    private static final boolean dumpProcessOomList(PrintWriter pw,
11786            ActivityManagerService service, List<ProcessRecord> origList,
11787            String prefix, String normalLabel, String persistentLabel,
11788            boolean inclDetails, String dumpPackage) {
11789
11790        ArrayList<Pair<ProcessRecord, Integer>> list
11791                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11792        for (int i=0; i<origList.size(); i++) {
11793            ProcessRecord r = origList.get(i);
11794            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11795                continue;
11796            }
11797            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11798        }
11799
11800        if (list.size() <= 0) {
11801            return false;
11802        }
11803
11804        Comparator<Pair<ProcessRecord, Integer>> comparator
11805                = new Comparator<Pair<ProcessRecord, Integer>>() {
11806            @Override
11807            public int compare(Pair<ProcessRecord, Integer> object1,
11808                    Pair<ProcessRecord, Integer> object2) {
11809                if (object1.first.setAdj != object2.first.setAdj) {
11810                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11811                }
11812                if (object1.second.intValue() != object2.second.intValue()) {
11813                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11814                }
11815                return 0;
11816            }
11817        };
11818
11819        Collections.sort(list, comparator);
11820
11821        final long curRealtime = SystemClock.elapsedRealtime();
11822        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11823        final long curUptime = SystemClock.uptimeMillis();
11824        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11825
11826        for (int i=list.size()-1; i>=0; i--) {
11827            ProcessRecord r = list.get(i).first;
11828            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11829            char schedGroup;
11830            switch (r.setSchedGroup) {
11831                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11832                    schedGroup = 'B';
11833                    break;
11834                case Process.THREAD_GROUP_DEFAULT:
11835                    schedGroup = 'F';
11836                    break;
11837                default:
11838                    schedGroup = '?';
11839                    break;
11840            }
11841            char foreground;
11842            if (r.foregroundActivities) {
11843                foreground = 'A';
11844            } else if (r.foregroundServices) {
11845                foreground = 'S';
11846            } else {
11847                foreground = ' ';
11848            }
11849            String procState = ProcessList.makeProcStateString(r.curProcState);
11850            pw.print(prefix);
11851            pw.print(r.persistent ? persistentLabel : normalLabel);
11852            pw.print(" #");
11853            int num = (origList.size()-1)-list.get(i).second;
11854            if (num < 10) pw.print(' ');
11855            pw.print(num);
11856            pw.print(": ");
11857            pw.print(oomAdj);
11858            pw.print(' ');
11859            pw.print(schedGroup);
11860            pw.print('/');
11861            pw.print(foreground);
11862            pw.print('/');
11863            pw.print(procState);
11864            pw.print(" trm:");
11865            if (r.trimMemoryLevel < 10) pw.print(' ');
11866            pw.print(r.trimMemoryLevel);
11867            pw.print(' ');
11868            pw.print(r.toShortString());
11869            pw.print(" (");
11870            pw.print(r.adjType);
11871            pw.println(')');
11872            if (r.adjSource != null || r.adjTarget != null) {
11873                pw.print(prefix);
11874                pw.print("    ");
11875                if (r.adjTarget instanceof ComponentName) {
11876                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11877                } else if (r.adjTarget != null) {
11878                    pw.print(r.adjTarget.toString());
11879                } else {
11880                    pw.print("{null}");
11881                }
11882                pw.print("<=");
11883                if (r.adjSource instanceof ProcessRecord) {
11884                    pw.print("Proc{");
11885                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11886                    pw.println("}");
11887                } else if (r.adjSource != null) {
11888                    pw.println(r.adjSource.toString());
11889                } else {
11890                    pw.println("{null}");
11891                }
11892            }
11893            if (inclDetails) {
11894                pw.print(prefix);
11895                pw.print("    ");
11896                pw.print("oom: max="); pw.print(r.maxAdj);
11897                pw.print(" curRaw="); pw.print(r.curRawAdj);
11898                pw.print(" setRaw="); pw.print(r.setRawAdj);
11899                pw.print(" cur="); pw.print(r.curAdj);
11900                pw.print(" set="); pw.println(r.setAdj);
11901                pw.print(prefix);
11902                pw.print("    ");
11903                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11904                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11905                pw.print(" lastPss="); pw.print(r.lastPss);
11906                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11907                pw.print(prefix);
11908                pw.print("    ");
11909                pw.print("keeping="); pw.print(r.keeping);
11910                pw.print(" cached="); pw.print(r.cached);
11911                pw.print(" empty="); pw.print(r.empty);
11912                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11913
11914                if (!r.keeping) {
11915                    if (r.lastWakeTime != 0) {
11916                        long wtime;
11917                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11918                        synchronized (stats) {
11919                            wtime = stats.getProcessWakeTime(r.info.uid,
11920                                    r.pid, curRealtime);
11921                        }
11922                        long timeUsed = wtime - r.lastWakeTime;
11923                        pw.print(prefix);
11924                        pw.print("    ");
11925                        pw.print("keep awake over ");
11926                        TimeUtils.formatDuration(realtimeSince, pw);
11927                        pw.print(" used ");
11928                        TimeUtils.formatDuration(timeUsed, pw);
11929                        pw.print(" (");
11930                        pw.print((timeUsed*100)/realtimeSince);
11931                        pw.println("%)");
11932                    }
11933                    if (r.lastCpuTime != 0) {
11934                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11935                        pw.print(prefix);
11936                        pw.print("    ");
11937                        pw.print("run cpu over ");
11938                        TimeUtils.formatDuration(uptimeSince, pw);
11939                        pw.print(" used ");
11940                        TimeUtils.formatDuration(timeUsed, pw);
11941                        pw.print(" (");
11942                        pw.print((timeUsed*100)/uptimeSince);
11943                        pw.println("%)");
11944                    }
11945                }
11946            }
11947        }
11948        return true;
11949    }
11950
11951    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11952        ArrayList<ProcessRecord> procs;
11953        synchronized (this) {
11954            if (args != null && args.length > start
11955                    && args[start].charAt(0) != '-') {
11956                procs = new ArrayList<ProcessRecord>();
11957                int pid = -1;
11958                try {
11959                    pid = Integer.parseInt(args[start]);
11960                } catch (NumberFormatException e) {
11961                }
11962                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11963                    ProcessRecord proc = mLruProcesses.get(i);
11964                    if (proc.pid == pid) {
11965                        procs.add(proc);
11966                    } else if (proc.processName.equals(args[start])) {
11967                        procs.add(proc);
11968                    }
11969                }
11970                if (procs.size() <= 0) {
11971                    return null;
11972                }
11973            } else {
11974                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11975            }
11976        }
11977        return procs;
11978    }
11979
11980    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11981            PrintWriter pw, String[] args) {
11982        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11983        if (procs == null) {
11984            pw.println("No process found for: " + args[0]);
11985            return;
11986        }
11987
11988        long uptime = SystemClock.uptimeMillis();
11989        long realtime = SystemClock.elapsedRealtime();
11990        pw.println("Applications Graphics Acceleration Info:");
11991        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11992
11993        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11994            ProcessRecord r = procs.get(i);
11995            if (r.thread != null) {
11996                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11997                pw.flush();
11998                try {
11999                    TransferPipe tp = new TransferPipe();
12000                    try {
12001                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12002                        tp.go(fd);
12003                    } finally {
12004                        tp.kill();
12005                    }
12006                } catch (IOException e) {
12007                    pw.println("Failure while dumping the app: " + r);
12008                    pw.flush();
12009                } catch (RemoteException e) {
12010                    pw.println("Got a RemoteException while dumping the app " + r);
12011                    pw.flush();
12012                }
12013            }
12014        }
12015    }
12016
12017    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12018        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12019        if (procs == null) {
12020            pw.println("No process found for: " + args[0]);
12021            return;
12022        }
12023
12024        pw.println("Applications Database Info:");
12025
12026        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12027            ProcessRecord r = procs.get(i);
12028            if (r.thread != null) {
12029                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12030                pw.flush();
12031                try {
12032                    TransferPipe tp = new TransferPipe();
12033                    try {
12034                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12035                        tp.go(fd);
12036                    } finally {
12037                        tp.kill();
12038                    }
12039                } catch (IOException e) {
12040                    pw.println("Failure while dumping the app: " + r);
12041                    pw.flush();
12042                } catch (RemoteException e) {
12043                    pw.println("Got a RemoteException while dumping the app " + r);
12044                    pw.flush();
12045                }
12046            }
12047        }
12048    }
12049
12050    final static class MemItem {
12051        final boolean isProc;
12052        final String label;
12053        final String shortLabel;
12054        final long pss;
12055        final int id;
12056        final boolean hasActivities;
12057        ArrayList<MemItem> subitems;
12058
12059        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12060                boolean _hasActivities) {
12061            isProc = true;
12062            label = _label;
12063            shortLabel = _shortLabel;
12064            pss = _pss;
12065            id = _id;
12066            hasActivities = _hasActivities;
12067        }
12068
12069        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12070            isProc = false;
12071            label = _label;
12072            shortLabel = _shortLabel;
12073            pss = _pss;
12074            id = _id;
12075            hasActivities = false;
12076        }
12077    }
12078
12079    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12080            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12081        if (sort && !isCompact) {
12082            Collections.sort(items, new Comparator<MemItem>() {
12083                @Override
12084                public int compare(MemItem lhs, MemItem rhs) {
12085                    if (lhs.pss < rhs.pss) {
12086                        return 1;
12087                    } else if (lhs.pss > rhs.pss) {
12088                        return -1;
12089                    }
12090                    return 0;
12091                }
12092            });
12093        }
12094
12095        for (int i=0; i<items.size(); i++) {
12096            MemItem mi = items.get(i);
12097            if (!isCompact) {
12098                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12099            } else if (mi.isProc) {
12100                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12101                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12102                pw.println(mi.hasActivities ? ",a" : ",e");
12103            } else {
12104                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12105                pw.println(mi.pss);
12106            }
12107            if (mi.subitems != null) {
12108                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12109                        true, isCompact);
12110            }
12111        }
12112    }
12113
12114    // These are in KB.
12115    static final long[] DUMP_MEM_BUCKETS = new long[] {
12116        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12117        120*1024, 160*1024, 200*1024,
12118        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12119        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12120    };
12121
12122    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12123            boolean stackLike) {
12124        int start = label.lastIndexOf('.');
12125        if (start >= 0) start++;
12126        else start = 0;
12127        int end = label.length();
12128        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12129            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12130                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12131                out.append(bucket);
12132                out.append(stackLike ? "MB." : "MB ");
12133                out.append(label, start, end);
12134                return;
12135            }
12136        }
12137        out.append(memKB/1024);
12138        out.append(stackLike ? "MB." : "MB ");
12139        out.append(label, start, end);
12140    }
12141
12142    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12143            ProcessList.NATIVE_ADJ,
12144            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12145            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12146            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12147            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12148            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12149    };
12150    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12151            "Native",
12152            "System", "Persistent", "Foreground",
12153            "Visible", "Perceptible",
12154            "Heavy Weight", "Backup",
12155            "A Services", "Home",
12156            "Previous", "B Services", "Cached"
12157    };
12158    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12159            "native",
12160            "sys", "pers", "fore",
12161            "vis", "percept",
12162            "heavy", "backup",
12163            "servicea", "home",
12164            "prev", "serviceb", "cached"
12165    };
12166
12167    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12168            long realtime, boolean isCheckinRequest, boolean isCompact) {
12169        if (isCheckinRequest || isCompact) {
12170            // short checkin version
12171            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12172        } else {
12173            pw.println("Applications Memory Usage (kB):");
12174            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12175        }
12176    }
12177
12178    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12179            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12180        boolean dumpDetails = false;
12181        boolean dumpFullDetails = false;
12182        boolean dumpDalvik = false;
12183        boolean oomOnly = false;
12184        boolean isCompact = false;
12185        boolean localOnly = false;
12186
12187        int opti = 0;
12188        while (opti < args.length) {
12189            String opt = args[opti];
12190            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12191                break;
12192            }
12193            opti++;
12194            if ("-a".equals(opt)) {
12195                dumpDetails = true;
12196                dumpFullDetails = true;
12197                dumpDalvik = true;
12198            } else if ("-d".equals(opt)) {
12199                dumpDalvik = true;
12200            } else if ("-c".equals(opt)) {
12201                isCompact = true;
12202            } else if ("--oom".equals(opt)) {
12203                oomOnly = true;
12204            } else if ("--local".equals(opt)) {
12205                localOnly = true;
12206            } else if ("-h".equals(opt)) {
12207                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12208                pw.println("  -a: include all available information for each process.");
12209                pw.println("  -d: include dalvik details when dumping process details.");
12210                pw.println("  -c: dump in a compact machine-parseable representation.");
12211                pw.println("  --oom: only show processes organized by oom adj.");
12212                pw.println("  --local: only collect details locally, don't call process.");
12213                pw.println("If [process] is specified it can be the name or ");
12214                pw.println("pid of a specific process to dump.");
12215                return;
12216            } else {
12217                pw.println("Unknown argument: " + opt + "; use -h for help");
12218            }
12219        }
12220
12221        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12222        long uptime = SystemClock.uptimeMillis();
12223        long realtime = SystemClock.elapsedRealtime();
12224        final long[] tmpLong = new long[1];
12225
12226        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12227        if (procs == null) {
12228            // No Java processes.  Maybe they want to print a native process.
12229            if (args != null && args.length > opti
12230                    && args[opti].charAt(0) != '-') {
12231                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12232                        = new ArrayList<ProcessCpuTracker.Stats>();
12233                updateCpuStatsNow();
12234                int findPid = -1;
12235                try {
12236                    findPid = Integer.parseInt(args[opti]);
12237                } catch (NumberFormatException e) {
12238                }
12239                synchronized (mProcessCpuThread) {
12240                    final int N = mProcessCpuTracker.countStats();
12241                    for (int i=0; i<N; i++) {
12242                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12243                        if (st.pid == findPid || (st.baseName != null
12244                                && st.baseName.equals(args[opti]))) {
12245                            nativeProcs.add(st);
12246                        }
12247                    }
12248                }
12249                if (nativeProcs.size() > 0) {
12250                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12251                            isCompact);
12252                    Debug.MemoryInfo mi = null;
12253                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12254                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12255                        final int pid = r.pid;
12256                        if (!isCheckinRequest && dumpDetails) {
12257                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12258                        }
12259                        if (mi == null) {
12260                            mi = new Debug.MemoryInfo();
12261                        }
12262                        if (dumpDetails || (!brief && !oomOnly)) {
12263                            Debug.getMemoryInfo(pid, mi);
12264                        } else {
12265                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12266                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12267                        }
12268                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12269                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12270                        if (isCheckinRequest) {
12271                            pw.println();
12272                        }
12273                    }
12274                    return;
12275                }
12276            }
12277            pw.println("No process found for: " + args[opti]);
12278            return;
12279        }
12280
12281        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12282            dumpDetails = true;
12283        }
12284
12285        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12286
12287        String[] innerArgs = new String[args.length-opti];
12288        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12289
12290        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12291        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12292        long nativePss=0, dalvikPss=0, otherPss=0;
12293        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12294
12295        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12296        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12297                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12298
12299        long totalPss = 0;
12300        long cachedPss = 0;
12301
12302        Debug.MemoryInfo mi = null;
12303        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12304            final ProcessRecord r = procs.get(i);
12305            final IApplicationThread thread;
12306            final int pid;
12307            final int oomAdj;
12308            final boolean hasActivities;
12309            synchronized (this) {
12310                thread = r.thread;
12311                pid = r.pid;
12312                oomAdj = r.getSetAdjWithServices();
12313                hasActivities = r.activities.size() > 0;
12314            }
12315            if (thread != null) {
12316                if (!isCheckinRequest && dumpDetails) {
12317                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12318                }
12319                if (mi == null) {
12320                    mi = new Debug.MemoryInfo();
12321                }
12322                if (dumpDetails || (!brief && !oomOnly)) {
12323                    Debug.getMemoryInfo(pid, mi);
12324                } else {
12325                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12326                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12327                }
12328                if (dumpDetails) {
12329                    if (localOnly) {
12330                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12331                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12332                        if (isCheckinRequest) {
12333                            pw.println();
12334                        }
12335                    } else {
12336                        try {
12337                            pw.flush();
12338                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12339                                    dumpDalvik, innerArgs);
12340                        } catch (RemoteException e) {
12341                            if (!isCheckinRequest) {
12342                                pw.println("Got RemoteException!");
12343                                pw.flush();
12344                            }
12345                        }
12346                    }
12347                }
12348
12349                final long myTotalPss = mi.getTotalPss();
12350                final long myTotalUss = mi.getTotalUss();
12351
12352                synchronized (this) {
12353                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12354                        // Record this for posterity if the process has been stable.
12355                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12356                    }
12357                }
12358
12359                if (!isCheckinRequest && mi != null) {
12360                    totalPss += myTotalPss;
12361                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12362                            (hasActivities ? " / activities)" : ")"),
12363                            r.processName, myTotalPss, pid, hasActivities);
12364                    procMems.add(pssItem);
12365                    procMemsMap.put(pid, pssItem);
12366
12367                    nativePss += mi.nativePss;
12368                    dalvikPss += mi.dalvikPss;
12369                    otherPss += mi.otherPss;
12370                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12371                        long mem = mi.getOtherPss(j);
12372                        miscPss[j] += mem;
12373                        otherPss -= mem;
12374                    }
12375
12376                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12377                        cachedPss += myTotalPss;
12378                    }
12379
12380                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12381                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12382                                || oomIndex == (oomPss.length-1)) {
12383                            oomPss[oomIndex] += myTotalPss;
12384                            if (oomProcs[oomIndex] == null) {
12385                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12386                            }
12387                            oomProcs[oomIndex].add(pssItem);
12388                            break;
12389                        }
12390                    }
12391                }
12392            }
12393        }
12394
12395        if (!isCheckinRequest && procs.size() > 1) {
12396            // If we are showing aggregations, also look for native processes to
12397            // include so that our aggregations are more accurate.
12398            updateCpuStatsNow();
12399            synchronized (mProcessCpuThread) {
12400                final int N = mProcessCpuTracker.countStats();
12401                for (int i=0; i<N; i++) {
12402                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12403                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12404                        if (mi == null) {
12405                            mi = new Debug.MemoryInfo();
12406                        }
12407                        if (!brief && !oomOnly) {
12408                            Debug.getMemoryInfo(st.pid, mi);
12409                        } else {
12410                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12411                            mi.nativePrivateDirty = (int)tmpLong[0];
12412                        }
12413
12414                        final long myTotalPss = mi.getTotalPss();
12415                        totalPss += myTotalPss;
12416
12417                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12418                                st.name, myTotalPss, st.pid, false);
12419                        procMems.add(pssItem);
12420
12421                        nativePss += mi.nativePss;
12422                        dalvikPss += mi.dalvikPss;
12423                        otherPss += mi.otherPss;
12424                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12425                            long mem = mi.getOtherPss(j);
12426                            miscPss[j] += mem;
12427                            otherPss -= mem;
12428                        }
12429                        oomPss[0] += myTotalPss;
12430                        if (oomProcs[0] == null) {
12431                            oomProcs[0] = new ArrayList<MemItem>();
12432                        }
12433                        oomProcs[0].add(pssItem);
12434                    }
12435                }
12436            }
12437
12438            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12439
12440            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12441            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12442            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12443            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12444                String label = Debug.MemoryInfo.getOtherLabel(j);
12445                catMems.add(new MemItem(label, label, miscPss[j], j));
12446            }
12447
12448            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12449            for (int j=0; j<oomPss.length; j++) {
12450                if (oomPss[j] != 0) {
12451                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12452                            : DUMP_MEM_OOM_LABEL[j];
12453                    MemItem item = new MemItem(label, label, oomPss[j],
12454                            DUMP_MEM_OOM_ADJ[j]);
12455                    item.subitems = oomProcs[j];
12456                    oomMems.add(item);
12457                }
12458            }
12459
12460            if (!brief && !oomOnly && !isCompact) {
12461                pw.println();
12462                pw.println("Total PSS by process:");
12463                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12464                pw.println();
12465            }
12466            if (!isCompact) {
12467                pw.println("Total PSS by OOM adjustment:");
12468            }
12469            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12470            if (!brief && !oomOnly) {
12471                PrintWriter out = categoryPw != null ? categoryPw : pw;
12472                if (!isCompact) {
12473                    out.println();
12474                    out.println("Total PSS by category:");
12475                }
12476                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12477            }
12478            if (!isCompact) {
12479                pw.println();
12480            }
12481            MemInfoReader memInfo = new MemInfoReader();
12482            memInfo.readMemInfo();
12483            if (!brief) {
12484                if (!isCompact) {
12485                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12486                    pw.print(" kB (status ");
12487                    switch (mLastMemoryLevel) {
12488                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12489                            pw.println("normal)");
12490                            break;
12491                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12492                            pw.println("moderate)");
12493                            break;
12494                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12495                            pw.println("low)");
12496                            break;
12497                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12498                            pw.println("critical)");
12499                            break;
12500                        default:
12501                            pw.print(mLastMemoryLevel);
12502                            pw.println(")");
12503                            break;
12504                    }
12505                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12506                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12507                            pw.print(cachedPss); pw.print(" cached pss + ");
12508                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12509                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12510                } else {
12511                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12512                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12513                            + memInfo.getFreeSizeKb()); pw.print(",");
12514                    pw.println(totalPss - cachedPss);
12515                }
12516            }
12517            if (!isCompact) {
12518                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12519                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12520                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12521                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12522                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12523                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12524                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12525                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12526                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12527                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12528                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12529            }
12530            if (!brief) {
12531                if (memInfo.getZramTotalSizeKb() != 0) {
12532                    if (!isCompact) {
12533                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12534                                pw.print(" kB physical used for ");
12535                                pw.print(memInfo.getSwapTotalSizeKb()
12536                                        - memInfo.getSwapFreeSizeKb());
12537                                pw.print(" kB in swap (");
12538                                pw.print(memInfo.getSwapTotalSizeKb());
12539                                pw.println(" kB total swap)");
12540                    } else {
12541                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12542                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12543                                pw.println(memInfo.getSwapFreeSizeKb());
12544                    }
12545                }
12546                final int[] SINGLE_LONG_FORMAT = new int[] {
12547                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12548                };
12549                long[] longOut = new long[1];
12550                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12551                        SINGLE_LONG_FORMAT, null, longOut, null);
12552                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12553                longOut[0] = 0;
12554                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12555                        SINGLE_LONG_FORMAT, null, longOut, null);
12556                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12557                longOut[0] = 0;
12558                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12559                        SINGLE_LONG_FORMAT, null, longOut, null);
12560                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12561                longOut[0] = 0;
12562                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12563                        SINGLE_LONG_FORMAT, null, longOut, null);
12564                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12565                if (!isCompact) {
12566                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12567                        pw.print("      KSM: "); pw.print(sharing);
12568                                pw.print(" kB saved from shared ");
12569                                pw.print(shared); pw.println(" kB");
12570                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12571                                pw.print(voltile); pw.println(" kB volatile");
12572                    }
12573                    pw.print("   Tuning: ");
12574                    pw.print(ActivityManager.staticGetMemoryClass());
12575                    pw.print(" (large ");
12576                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12577                    pw.print("), oom ");
12578                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12579                    pw.print(" kB");
12580                    pw.print(", restore limit ");
12581                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12582                    pw.print(" kB");
12583                    if (ActivityManager.isLowRamDeviceStatic()) {
12584                        pw.print(" (low-ram)");
12585                    }
12586                    if (ActivityManager.isHighEndGfx()) {
12587                        pw.print(" (high-end-gfx)");
12588                    }
12589                    pw.println();
12590                } else {
12591                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12592                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12593                    pw.println(voltile);
12594                    pw.print("tuning,");
12595                    pw.print(ActivityManager.staticGetMemoryClass());
12596                    pw.print(',');
12597                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12598                    pw.print(',');
12599                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12600                    if (ActivityManager.isLowRamDeviceStatic()) {
12601                        pw.print(",low-ram");
12602                    }
12603                    if (ActivityManager.isHighEndGfx()) {
12604                        pw.print(",high-end-gfx");
12605                    }
12606                    pw.println();
12607                }
12608            }
12609        }
12610    }
12611
12612    /**
12613     * Searches array of arguments for the specified string
12614     * @param args array of argument strings
12615     * @param value value to search for
12616     * @return true if the value is contained in the array
12617     */
12618    private static boolean scanArgs(String[] args, String value) {
12619        if (args != null) {
12620            for (String arg : args) {
12621                if (value.equals(arg)) {
12622                    return true;
12623                }
12624            }
12625        }
12626        return false;
12627    }
12628
12629    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12630            ContentProviderRecord cpr, boolean always) {
12631        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12632
12633        if (!inLaunching || always) {
12634            synchronized (cpr) {
12635                cpr.launchingApp = null;
12636                cpr.notifyAll();
12637            }
12638            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12639            String names[] = cpr.info.authority.split(";");
12640            for (int j = 0; j < names.length; j++) {
12641                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12642            }
12643        }
12644
12645        for (int i=0; i<cpr.connections.size(); i++) {
12646            ContentProviderConnection conn = cpr.connections.get(i);
12647            if (conn.waiting) {
12648                // If this connection is waiting for the provider, then we don't
12649                // need to mess with its process unless we are always removing
12650                // or for some reason the provider is not currently launching.
12651                if (inLaunching && !always) {
12652                    continue;
12653                }
12654            }
12655            ProcessRecord capp = conn.client;
12656            conn.dead = true;
12657            if (conn.stableCount > 0) {
12658                if (!capp.persistent && capp.thread != null
12659                        && capp.pid != 0
12660                        && capp.pid != MY_PID) {
12661                    killUnneededProcessLocked(capp, "depends on provider "
12662                            + cpr.name.flattenToShortString()
12663                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12664                }
12665            } else if (capp.thread != null && conn.provider.provider != null) {
12666                try {
12667                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12668                } catch (RemoteException e) {
12669                }
12670                // In the protocol here, we don't expect the client to correctly
12671                // clean up this connection, we'll just remove it.
12672                cpr.connections.remove(i);
12673                conn.client.conProviders.remove(conn);
12674            }
12675        }
12676
12677        if (inLaunching && always) {
12678            mLaunchingProviders.remove(cpr);
12679        }
12680        return inLaunching;
12681    }
12682
12683    /**
12684     * Main code for cleaning up a process when it has gone away.  This is
12685     * called both as a result of the process dying, or directly when stopping
12686     * a process when running in single process mode.
12687     */
12688    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12689            boolean restarting, boolean allowRestart, int index) {
12690        if (index >= 0) {
12691            removeLruProcessLocked(app);
12692            ProcessList.remove(app.pid);
12693        }
12694
12695        mProcessesToGc.remove(app);
12696        mPendingPssProcesses.remove(app);
12697
12698        // Dismiss any open dialogs.
12699        if (app.crashDialog != null && !app.forceCrashReport) {
12700            app.crashDialog.dismiss();
12701            app.crashDialog = null;
12702        }
12703        if (app.anrDialog != null) {
12704            app.anrDialog.dismiss();
12705            app.anrDialog = null;
12706        }
12707        if (app.waitDialog != null) {
12708            app.waitDialog.dismiss();
12709            app.waitDialog = null;
12710        }
12711
12712        app.crashing = false;
12713        app.notResponding = false;
12714
12715        app.resetPackageList(mProcessStats);
12716        app.unlinkDeathRecipient();
12717        app.makeInactive(mProcessStats);
12718        app.forcingToForeground = null;
12719        updateProcessForegroundLocked(app, false, false);
12720        app.foregroundActivities = false;
12721        app.hasShownUi = false;
12722        app.treatLikeActivity = false;
12723        app.hasAboveClient = false;
12724        app.hasClientActivities = false;
12725
12726        mServices.killServicesLocked(app, allowRestart);
12727
12728        boolean restart = false;
12729
12730        // Remove published content providers.
12731        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12732            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12733            final boolean always = app.bad || !allowRestart;
12734            if (removeDyingProviderLocked(app, cpr, always) || always) {
12735                // We left the provider in the launching list, need to
12736                // restart it.
12737                restart = true;
12738            }
12739
12740            cpr.provider = null;
12741            cpr.proc = null;
12742        }
12743        app.pubProviders.clear();
12744
12745        // Take care of any launching providers waiting for this process.
12746        if (checkAppInLaunchingProvidersLocked(app, false)) {
12747            restart = true;
12748        }
12749
12750        // Unregister from connected content providers.
12751        if (!app.conProviders.isEmpty()) {
12752            for (int i=0; i<app.conProviders.size(); i++) {
12753                ContentProviderConnection conn = app.conProviders.get(i);
12754                conn.provider.connections.remove(conn);
12755            }
12756            app.conProviders.clear();
12757        }
12758
12759        // At this point there may be remaining entries in mLaunchingProviders
12760        // where we were the only one waiting, so they are no longer of use.
12761        // Look for these and clean up if found.
12762        // XXX Commented out for now.  Trying to figure out a way to reproduce
12763        // the actual situation to identify what is actually going on.
12764        if (false) {
12765            for (int i=0; i<mLaunchingProviders.size(); i++) {
12766                ContentProviderRecord cpr = (ContentProviderRecord)
12767                        mLaunchingProviders.get(i);
12768                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12769                    synchronized (cpr) {
12770                        cpr.launchingApp = null;
12771                        cpr.notifyAll();
12772                    }
12773                }
12774            }
12775        }
12776
12777        skipCurrentReceiverLocked(app);
12778
12779        // Unregister any receivers.
12780        for (int i=app.receivers.size()-1; i>=0; i--) {
12781            removeReceiverLocked(app.receivers.valueAt(i));
12782        }
12783        app.receivers.clear();
12784
12785        // If the app is undergoing backup, tell the backup manager about it
12786        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12787            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12788                    + mBackupTarget.appInfo + " died during backup");
12789            try {
12790                IBackupManager bm = IBackupManager.Stub.asInterface(
12791                        ServiceManager.getService(Context.BACKUP_SERVICE));
12792                bm.agentDisconnected(app.info.packageName);
12793            } catch (RemoteException e) {
12794                // can't happen; backup manager is local
12795            }
12796        }
12797
12798        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12799            ProcessChangeItem item = mPendingProcessChanges.get(i);
12800            if (item.pid == app.pid) {
12801                mPendingProcessChanges.remove(i);
12802                mAvailProcessChanges.add(item);
12803            }
12804        }
12805        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12806
12807        // If the caller is restarting this app, then leave it in its
12808        // current lists and let the caller take care of it.
12809        if (restarting) {
12810            return;
12811        }
12812
12813        if (!app.persistent || app.isolated) {
12814            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12815                    "Removing non-persistent process during cleanup: " + app);
12816            mProcessNames.remove(app.processName, app.uid);
12817            mIsolatedProcesses.remove(app.uid);
12818            if (mHeavyWeightProcess == app) {
12819                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12820                        mHeavyWeightProcess.userId, 0));
12821                mHeavyWeightProcess = null;
12822            }
12823        } else if (!app.removed) {
12824            // This app is persistent, so we need to keep its record around.
12825            // If it is not already on the pending app list, add it there
12826            // and start a new process for it.
12827            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12828                mPersistentStartingProcesses.add(app);
12829                restart = true;
12830            }
12831        }
12832        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12833                "Clean-up removing on hold: " + app);
12834        mProcessesOnHold.remove(app);
12835
12836        if (app == mHomeProcess) {
12837            mHomeProcess = null;
12838        }
12839        if (app == mPreviousProcess) {
12840            mPreviousProcess = null;
12841        }
12842
12843        if (restart && !app.isolated) {
12844            // We have components that still need to be running in the
12845            // process, so re-launch it.
12846            mProcessNames.put(app.processName, app.uid, app);
12847            startProcessLocked(app, "restart", app.processName);
12848        } else if (app.pid > 0 && app.pid != MY_PID) {
12849            // Goodbye!
12850            boolean removed;
12851            synchronized (mPidsSelfLocked) {
12852                mPidsSelfLocked.remove(app.pid);
12853                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12854            }
12855            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12856                    app.processName, app.info.uid);
12857            if (app.isolated) {
12858                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12859            }
12860            app.setPid(0);
12861        }
12862    }
12863
12864    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12865        // Look through the content providers we are waiting to have launched,
12866        // and if any run in this process then either schedule a restart of
12867        // the process or kill the client waiting for it if this process has
12868        // gone bad.
12869        int NL = mLaunchingProviders.size();
12870        boolean restart = false;
12871        for (int i=0; i<NL; i++) {
12872            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12873            if (cpr.launchingApp == app) {
12874                if (!alwaysBad && !app.bad) {
12875                    restart = true;
12876                } else {
12877                    removeDyingProviderLocked(app, cpr, true);
12878                    // cpr should have been removed from mLaunchingProviders
12879                    NL = mLaunchingProviders.size();
12880                    i--;
12881                }
12882            }
12883        }
12884        return restart;
12885    }
12886
12887    // =========================================================
12888    // SERVICES
12889    // =========================================================
12890
12891    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12892            int flags) {
12893        enforceNotIsolatedCaller("getServices");
12894        synchronized (this) {
12895            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12896        }
12897    }
12898
12899    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12900        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12901        synchronized (this) {
12902            return mServices.getRunningServiceControlPanelLocked(name);
12903        }
12904    }
12905
12906    public ComponentName startService(IApplicationThread caller, Intent service,
12907            String resolvedType, int userId) {
12908        enforceNotIsolatedCaller("startService");
12909        // Refuse possible leaked file descriptors
12910        if (service != null && service.hasFileDescriptors() == true) {
12911            throw new IllegalArgumentException("File descriptors passed in Intent");
12912        }
12913
12914        if (DEBUG_SERVICE)
12915            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12916        synchronized(this) {
12917            final int callingPid = Binder.getCallingPid();
12918            final int callingUid = Binder.getCallingUid();
12919            final long origId = Binder.clearCallingIdentity();
12920            ComponentName res = mServices.startServiceLocked(caller, service,
12921                    resolvedType, callingPid, callingUid, userId);
12922            Binder.restoreCallingIdentity(origId);
12923            return res;
12924        }
12925    }
12926
12927    ComponentName startServiceInPackage(int uid,
12928            Intent service, String resolvedType, int userId) {
12929        synchronized(this) {
12930            if (DEBUG_SERVICE)
12931                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12932            final long origId = Binder.clearCallingIdentity();
12933            ComponentName res = mServices.startServiceLocked(null, service,
12934                    resolvedType, -1, uid, userId);
12935            Binder.restoreCallingIdentity(origId);
12936            return res;
12937        }
12938    }
12939
12940    public int stopService(IApplicationThread caller, Intent service,
12941            String resolvedType, int userId) {
12942        enforceNotIsolatedCaller("stopService");
12943        // Refuse possible leaked file descriptors
12944        if (service != null && service.hasFileDescriptors() == true) {
12945            throw new IllegalArgumentException("File descriptors passed in Intent");
12946        }
12947
12948        synchronized(this) {
12949            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12950        }
12951    }
12952
12953    public IBinder peekService(Intent service, String resolvedType) {
12954        enforceNotIsolatedCaller("peekService");
12955        // Refuse possible leaked file descriptors
12956        if (service != null && service.hasFileDescriptors() == true) {
12957            throw new IllegalArgumentException("File descriptors passed in Intent");
12958        }
12959        synchronized(this) {
12960            return mServices.peekServiceLocked(service, resolvedType);
12961        }
12962    }
12963
12964    public boolean stopServiceToken(ComponentName className, IBinder token,
12965            int startId) {
12966        synchronized(this) {
12967            return mServices.stopServiceTokenLocked(className, token, startId);
12968        }
12969    }
12970
12971    public void setServiceForeground(ComponentName className, IBinder token,
12972            int id, Notification notification, boolean removeNotification) {
12973        synchronized(this) {
12974            mServices.setServiceForegroundLocked(className, token, id, notification,
12975                    removeNotification);
12976        }
12977    }
12978
12979    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12980            boolean requireFull, String name, String callerPackage) {
12981        final int callingUserId = UserHandle.getUserId(callingUid);
12982        if (callingUserId != userId) {
12983            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12984                if ((requireFull || checkComponentPermission(
12985                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12986                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12987                        && checkComponentPermission(
12988                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12989                                callingPid, callingUid, -1, true)
12990                                != PackageManager.PERMISSION_GRANTED) {
12991                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12992                        // In this case, they would like to just execute as their
12993                        // owner user instead of failing.
12994                        userId = callingUserId;
12995                    } else {
12996                        StringBuilder builder = new StringBuilder(128);
12997                        builder.append("Permission Denial: ");
12998                        builder.append(name);
12999                        if (callerPackage != null) {
13000                            builder.append(" from ");
13001                            builder.append(callerPackage);
13002                        }
13003                        builder.append(" asks to run as user ");
13004                        builder.append(userId);
13005                        builder.append(" but is calling from user ");
13006                        builder.append(UserHandle.getUserId(callingUid));
13007                        builder.append("; this requires ");
13008                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13009                        if (!requireFull) {
13010                            builder.append(" or ");
13011                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13012                        }
13013                        String msg = builder.toString();
13014                        Slog.w(TAG, msg);
13015                        throw new SecurityException(msg);
13016                    }
13017                }
13018            }
13019            if (userId == UserHandle.USER_CURRENT
13020                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13021                // Note that we may be accessing this outside of a lock...
13022                // shouldn't be a big deal, if this is being called outside
13023                // of a locked context there is intrinsically a race with
13024                // the value the caller will receive and someone else changing it.
13025                userId = mCurrentUserId;
13026            }
13027            if (!allowAll && userId < 0) {
13028                throw new IllegalArgumentException(
13029                        "Call does not support special user #" + userId);
13030            }
13031        }
13032        return userId;
13033    }
13034
13035    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13036            String className, int flags) {
13037        boolean result = false;
13038        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13039            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13040                if (ActivityManager.checkUidPermission(
13041                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13042                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13043                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13044                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13045                            + " requests FLAG_SINGLE_USER, but app does not hold "
13046                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13047                    Slog.w(TAG, msg);
13048                    throw new SecurityException(msg);
13049                }
13050                result = true;
13051            }
13052        } else if (componentProcessName == aInfo.packageName) {
13053            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13054        } else if ("system".equals(componentProcessName)) {
13055            result = true;
13056        }
13057        if (DEBUG_MU) {
13058            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13059                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13060        }
13061        return result;
13062    }
13063
13064    public int bindService(IApplicationThread caller, IBinder token,
13065            Intent service, String resolvedType,
13066            IServiceConnection connection, int flags, int userId) {
13067        enforceNotIsolatedCaller("bindService");
13068        // Refuse possible leaked file descriptors
13069        if (service != null && service.hasFileDescriptors() == true) {
13070            throw new IllegalArgumentException("File descriptors passed in Intent");
13071        }
13072
13073        synchronized(this) {
13074            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13075                    connection, flags, userId);
13076        }
13077    }
13078
13079    public boolean unbindService(IServiceConnection connection) {
13080        synchronized (this) {
13081            return mServices.unbindServiceLocked(connection);
13082        }
13083    }
13084
13085    public void publishService(IBinder token, Intent intent, IBinder service) {
13086        // Refuse possible leaked file descriptors
13087        if (intent != null && intent.hasFileDescriptors() == true) {
13088            throw new IllegalArgumentException("File descriptors passed in Intent");
13089        }
13090
13091        synchronized(this) {
13092            if (!(token instanceof ServiceRecord)) {
13093                throw new IllegalArgumentException("Invalid service token");
13094            }
13095            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13096        }
13097    }
13098
13099    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13100        // Refuse possible leaked file descriptors
13101        if (intent != null && intent.hasFileDescriptors() == true) {
13102            throw new IllegalArgumentException("File descriptors passed in Intent");
13103        }
13104
13105        synchronized(this) {
13106            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13107        }
13108    }
13109
13110    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13111        synchronized(this) {
13112            if (!(token instanceof ServiceRecord)) {
13113                throw new IllegalArgumentException("Invalid service token");
13114            }
13115            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13116        }
13117    }
13118
13119    // =========================================================
13120    // BACKUP AND RESTORE
13121    // =========================================================
13122
13123    // Cause the target app to be launched if necessary and its backup agent
13124    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13125    // activity manager to announce its creation.
13126    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13127        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13128        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13129
13130        synchronized(this) {
13131            // !!! TODO: currently no check here that we're already bound
13132            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13133            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13134            synchronized (stats) {
13135                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13136            }
13137
13138            // Backup agent is now in use, its package can't be stopped.
13139            try {
13140                AppGlobals.getPackageManager().setPackageStoppedState(
13141                        app.packageName, false, UserHandle.getUserId(app.uid));
13142            } catch (RemoteException e) {
13143            } catch (IllegalArgumentException e) {
13144                Slog.w(TAG, "Failed trying to unstop package "
13145                        + app.packageName + ": " + e);
13146            }
13147
13148            BackupRecord r = new BackupRecord(ss, app, backupMode);
13149            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13150                    ? new ComponentName(app.packageName, app.backupAgentName)
13151                    : new ComponentName("android", "FullBackupAgent");
13152            // startProcessLocked() returns existing proc's record if it's already running
13153            ProcessRecord proc = startProcessLocked(app.processName, app,
13154                    false, 0, "backup", hostingName, false, false, false);
13155            if (proc == null) {
13156                Slog.e(TAG, "Unable to start backup agent process " + r);
13157                return false;
13158            }
13159
13160            r.app = proc;
13161            mBackupTarget = r;
13162            mBackupAppName = app.packageName;
13163
13164            // Try not to kill the process during backup
13165            updateOomAdjLocked(proc);
13166
13167            // If the process is already attached, schedule the creation of the backup agent now.
13168            // If it is not yet live, this will be done when it attaches to the framework.
13169            if (proc.thread != null) {
13170                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13171                try {
13172                    proc.thread.scheduleCreateBackupAgent(app,
13173                            compatibilityInfoForPackageLocked(app), backupMode);
13174                } catch (RemoteException e) {
13175                    // Will time out on the backup manager side
13176                }
13177            } else {
13178                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13179            }
13180            // Invariants: at this point, the target app process exists and the application
13181            // is either already running or in the process of coming up.  mBackupTarget and
13182            // mBackupAppName describe the app, so that when it binds back to the AM we
13183            // know that it's scheduled for a backup-agent operation.
13184        }
13185
13186        return true;
13187    }
13188
13189    @Override
13190    public void clearPendingBackup() {
13191        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13192        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13193
13194        synchronized (this) {
13195            mBackupTarget = null;
13196            mBackupAppName = null;
13197        }
13198    }
13199
13200    // A backup agent has just come up
13201    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13202        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13203                + " = " + agent);
13204
13205        synchronized(this) {
13206            if (!agentPackageName.equals(mBackupAppName)) {
13207                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13208                return;
13209            }
13210        }
13211
13212        long oldIdent = Binder.clearCallingIdentity();
13213        try {
13214            IBackupManager bm = IBackupManager.Stub.asInterface(
13215                    ServiceManager.getService(Context.BACKUP_SERVICE));
13216            bm.agentConnected(agentPackageName, agent);
13217        } catch (RemoteException e) {
13218            // can't happen; the backup manager service is local
13219        } catch (Exception e) {
13220            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13221            e.printStackTrace();
13222        } finally {
13223            Binder.restoreCallingIdentity(oldIdent);
13224        }
13225    }
13226
13227    // done with this agent
13228    public void unbindBackupAgent(ApplicationInfo appInfo) {
13229        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13230        if (appInfo == null) {
13231            Slog.w(TAG, "unbind backup agent for null app");
13232            return;
13233        }
13234
13235        synchronized(this) {
13236            try {
13237                if (mBackupAppName == null) {
13238                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13239                    return;
13240                }
13241
13242                if (!mBackupAppName.equals(appInfo.packageName)) {
13243                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13244                    return;
13245                }
13246
13247                // Not backing this app up any more; reset its OOM adjustment
13248                final ProcessRecord proc = mBackupTarget.app;
13249                updateOomAdjLocked(proc);
13250
13251                // If the app crashed during backup, 'thread' will be null here
13252                if (proc.thread != null) {
13253                    try {
13254                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13255                                compatibilityInfoForPackageLocked(appInfo));
13256                    } catch (Exception e) {
13257                        Slog.e(TAG, "Exception when unbinding backup agent:");
13258                        e.printStackTrace();
13259                    }
13260                }
13261            } finally {
13262                mBackupTarget = null;
13263                mBackupAppName = null;
13264            }
13265        }
13266    }
13267    // =========================================================
13268    // BROADCASTS
13269    // =========================================================
13270
13271    private final List getStickiesLocked(String action, IntentFilter filter,
13272            List cur, int userId) {
13273        final ContentResolver resolver = mContext.getContentResolver();
13274        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13275        if (stickies == null) {
13276            return cur;
13277        }
13278        final ArrayList<Intent> list = stickies.get(action);
13279        if (list == null) {
13280            return cur;
13281        }
13282        int N = list.size();
13283        for (int i=0; i<N; i++) {
13284            Intent intent = list.get(i);
13285            if (filter.match(resolver, intent, true, TAG) >= 0) {
13286                if (cur == null) {
13287                    cur = new ArrayList<Intent>();
13288                }
13289                cur.add(intent);
13290            }
13291        }
13292        return cur;
13293    }
13294
13295    boolean isPendingBroadcastProcessLocked(int pid) {
13296        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13297                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13298    }
13299
13300    void skipPendingBroadcastLocked(int pid) {
13301            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13302            for (BroadcastQueue queue : mBroadcastQueues) {
13303                queue.skipPendingBroadcastLocked(pid);
13304            }
13305    }
13306
13307    // The app just attached; send any pending broadcasts that it should receive
13308    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13309        boolean didSomething = false;
13310        for (BroadcastQueue queue : mBroadcastQueues) {
13311            didSomething |= queue.sendPendingBroadcastsLocked(app);
13312        }
13313        return didSomething;
13314    }
13315
13316    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13317            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13318        enforceNotIsolatedCaller("registerReceiver");
13319        int callingUid;
13320        int callingPid;
13321        synchronized(this) {
13322            ProcessRecord callerApp = null;
13323            if (caller != null) {
13324                callerApp = getRecordForAppLocked(caller);
13325                if (callerApp == null) {
13326                    throw new SecurityException(
13327                            "Unable to find app for caller " + caller
13328                            + " (pid=" + Binder.getCallingPid()
13329                            + ") when registering receiver " + receiver);
13330                }
13331                if (callerApp.info.uid != Process.SYSTEM_UID &&
13332                        !callerApp.pkgList.containsKey(callerPackage) &&
13333                        !"android".equals(callerPackage)) {
13334                    throw new SecurityException("Given caller package " + callerPackage
13335                            + " is not running in process " + callerApp);
13336                }
13337                callingUid = callerApp.info.uid;
13338                callingPid = callerApp.pid;
13339            } else {
13340                callerPackage = null;
13341                callingUid = Binder.getCallingUid();
13342                callingPid = Binder.getCallingPid();
13343            }
13344
13345            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13346                    true, true, "registerReceiver", callerPackage);
13347
13348            List allSticky = null;
13349
13350            // Look for any matching sticky broadcasts...
13351            Iterator actions = filter.actionsIterator();
13352            if (actions != null) {
13353                while (actions.hasNext()) {
13354                    String action = (String)actions.next();
13355                    allSticky = getStickiesLocked(action, filter, allSticky,
13356                            UserHandle.USER_ALL);
13357                    allSticky = getStickiesLocked(action, filter, allSticky,
13358                            UserHandle.getUserId(callingUid));
13359                }
13360            } else {
13361                allSticky = getStickiesLocked(null, filter, allSticky,
13362                        UserHandle.USER_ALL);
13363                allSticky = getStickiesLocked(null, filter, allSticky,
13364                        UserHandle.getUserId(callingUid));
13365            }
13366
13367            // The first sticky in the list is returned directly back to
13368            // the client.
13369            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13370
13371            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13372                    + ": " + sticky);
13373
13374            if (receiver == null) {
13375                return sticky;
13376            }
13377
13378            ReceiverList rl
13379                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13380            if (rl == null) {
13381                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13382                        userId, receiver);
13383                if (rl.app != null) {
13384                    rl.app.receivers.add(rl);
13385                } else {
13386                    try {
13387                        receiver.asBinder().linkToDeath(rl, 0);
13388                    } catch (RemoteException e) {
13389                        return sticky;
13390                    }
13391                    rl.linkedToDeath = true;
13392                }
13393                mRegisteredReceivers.put(receiver.asBinder(), rl);
13394            } else if (rl.uid != callingUid) {
13395                throw new IllegalArgumentException(
13396                        "Receiver requested to register for uid " + callingUid
13397                        + " was previously registered for uid " + rl.uid);
13398            } else if (rl.pid != callingPid) {
13399                throw new IllegalArgumentException(
13400                        "Receiver requested to register for pid " + callingPid
13401                        + " was previously registered for pid " + rl.pid);
13402            } else if (rl.userId != userId) {
13403                throw new IllegalArgumentException(
13404                        "Receiver requested to register for user " + userId
13405                        + " was previously registered for user " + rl.userId);
13406            }
13407            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13408                    permission, callingUid, userId);
13409            rl.add(bf);
13410            if (!bf.debugCheck()) {
13411                Slog.w(TAG, "==> For Dynamic broadast");
13412            }
13413            mReceiverResolver.addFilter(bf);
13414
13415            // Enqueue broadcasts for all existing stickies that match
13416            // this filter.
13417            if (allSticky != null) {
13418                ArrayList receivers = new ArrayList();
13419                receivers.add(bf);
13420
13421                int N = allSticky.size();
13422                for (int i=0; i<N; i++) {
13423                    Intent intent = (Intent)allSticky.get(i);
13424                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13425                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13426                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13427                            null, null, false, true, true, -1);
13428                    queue.enqueueParallelBroadcastLocked(r);
13429                    queue.scheduleBroadcastsLocked();
13430                }
13431            }
13432
13433            return sticky;
13434        }
13435    }
13436
13437    public void unregisterReceiver(IIntentReceiver receiver) {
13438        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13439
13440        final long origId = Binder.clearCallingIdentity();
13441        try {
13442            boolean doTrim = false;
13443
13444            synchronized(this) {
13445                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13446                if (rl != null) {
13447                    if (rl.curBroadcast != null) {
13448                        BroadcastRecord r = rl.curBroadcast;
13449                        final boolean doNext = finishReceiverLocked(
13450                                receiver.asBinder(), r.resultCode, r.resultData,
13451                                r.resultExtras, r.resultAbort);
13452                        if (doNext) {
13453                            doTrim = true;
13454                            r.queue.processNextBroadcast(false);
13455                        }
13456                    }
13457
13458                    if (rl.app != null) {
13459                        rl.app.receivers.remove(rl);
13460                    }
13461                    removeReceiverLocked(rl);
13462                    if (rl.linkedToDeath) {
13463                        rl.linkedToDeath = false;
13464                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13465                    }
13466                }
13467            }
13468
13469            // If we actually concluded any broadcasts, we might now be able
13470            // to trim the recipients' apps from our working set
13471            if (doTrim) {
13472                trimApplications();
13473                return;
13474            }
13475
13476        } finally {
13477            Binder.restoreCallingIdentity(origId);
13478        }
13479    }
13480
13481    void removeReceiverLocked(ReceiverList rl) {
13482        mRegisteredReceivers.remove(rl.receiver.asBinder());
13483        int N = rl.size();
13484        for (int i=0; i<N; i++) {
13485            mReceiverResolver.removeFilter(rl.get(i));
13486        }
13487    }
13488
13489    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13490        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13491            ProcessRecord r = mLruProcesses.get(i);
13492            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13493                try {
13494                    r.thread.dispatchPackageBroadcast(cmd, packages);
13495                } catch (RemoteException ex) {
13496                }
13497            }
13498        }
13499    }
13500
13501    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13502            int[] users) {
13503        List<ResolveInfo> receivers = null;
13504        try {
13505            HashSet<ComponentName> singleUserReceivers = null;
13506            boolean scannedFirstReceivers = false;
13507            for (int user : users) {
13508                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13509                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13510                if (user != 0 && newReceivers != null) {
13511                    // If this is not the primary user, we need to check for
13512                    // any receivers that should be filtered out.
13513                    for (int i=0; i<newReceivers.size(); i++) {
13514                        ResolveInfo ri = newReceivers.get(i);
13515                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13516                            newReceivers.remove(i);
13517                            i--;
13518                        }
13519                    }
13520                }
13521                if (newReceivers != null && newReceivers.size() == 0) {
13522                    newReceivers = null;
13523                }
13524                if (receivers == null) {
13525                    receivers = newReceivers;
13526                } else if (newReceivers != null) {
13527                    // We need to concatenate the additional receivers
13528                    // found with what we have do far.  This would be easy,
13529                    // but we also need to de-dup any receivers that are
13530                    // singleUser.
13531                    if (!scannedFirstReceivers) {
13532                        // Collect any single user receivers we had already retrieved.
13533                        scannedFirstReceivers = true;
13534                        for (int i=0; i<receivers.size(); i++) {
13535                            ResolveInfo ri = receivers.get(i);
13536                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13537                                ComponentName cn = new ComponentName(
13538                                        ri.activityInfo.packageName, ri.activityInfo.name);
13539                                if (singleUserReceivers == null) {
13540                                    singleUserReceivers = new HashSet<ComponentName>();
13541                                }
13542                                singleUserReceivers.add(cn);
13543                            }
13544                        }
13545                    }
13546                    // Add the new results to the existing results, tracking
13547                    // and de-dupping single user receivers.
13548                    for (int i=0; i<newReceivers.size(); i++) {
13549                        ResolveInfo ri = newReceivers.get(i);
13550                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13551                            ComponentName cn = new ComponentName(
13552                                    ri.activityInfo.packageName, ri.activityInfo.name);
13553                            if (singleUserReceivers == null) {
13554                                singleUserReceivers = new HashSet<ComponentName>();
13555                            }
13556                            if (!singleUserReceivers.contains(cn)) {
13557                                singleUserReceivers.add(cn);
13558                                receivers.add(ri);
13559                            }
13560                        } else {
13561                            receivers.add(ri);
13562                        }
13563                    }
13564                }
13565            }
13566        } catch (RemoteException ex) {
13567            // pm is in same process, this will never happen.
13568        }
13569        return receivers;
13570    }
13571
13572    private final int broadcastIntentLocked(ProcessRecord callerApp,
13573            String callerPackage, Intent intent, String resolvedType,
13574            IIntentReceiver resultTo, int resultCode, String resultData,
13575            Bundle map, String requiredPermission, int appOp,
13576            boolean ordered, boolean sticky, int callingPid, int callingUid,
13577            int userId) {
13578        intent = new Intent(intent);
13579
13580        // By default broadcasts do not go to stopped apps.
13581        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13582
13583        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13584            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13585            + " ordered=" + ordered + " userid=" + userId);
13586        if ((resultTo != null) && !ordered) {
13587            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13588        }
13589
13590        userId = handleIncomingUser(callingPid, callingUid, userId,
13591                true, false, "broadcast", callerPackage);
13592
13593        // Make sure that the user who is receiving this broadcast is started.
13594        // If not, we will just skip it.
13595        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13596            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13597                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13598                Slog.w(TAG, "Skipping broadcast of " + intent
13599                        + ": user " + userId + " is stopped");
13600                return ActivityManager.BROADCAST_SUCCESS;
13601            }
13602        }
13603
13604        /*
13605         * Prevent non-system code (defined here to be non-persistent
13606         * processes) from sending protected broadcasts.
13607         */
13608        int callingAppId = UserHandle.getAppId(callingUid);
13609        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13610            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13611            callingUid == 0) {
13612            // Always okay.
13613        } else if (callerApp == null || !callerApp.persistent) {
13614            try {
13615                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13616                        intent.getAction())) {
13617                    String msg = "Permission Denial: not allowed to send broadcast "
13618                            + intent.getAction() + " from pid="
13619                            + callingPid + ", uid=" + callingUid;
13620                    Slog.w(TAG, msg);
13621                    throw new SecurityException(msg);
13622                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13623                    // Special case for compatibility: we don't want apps to send this,
13624                    // but historically it has not been protected and apps may be using it
13625                    // to poke their own app widget.  So, instead of making it protected,
13626                    // just limit it to the caller.
13627                    if (callerApp == null) {
13628                        String msg = "Permission Denial: not allowed to send broadcast "
13629                                + intent.getAction() + " from unknown caller.";
13630                        Slog.w(TAG, msg);
13631                        throw new SecurityException(msg);
13632                    } else if (intent.getComponent() != null) {
13633                        // They are good enough to send to an explicit component...  verify
13634                        // it is being sent to the calling app.
13635                        if (!intent.getComponent().getPackageName().equals(
13636                                callerApp.info.packageName)) {
13637                            String msg = "Permission Denial: not allowed to send broadcast "
13638                                    + intent.getAction() + " to "
13639                                    + intent.getComponent().getPackageName() + " from "
13640                                    + callerApp.info.packageName;
13641                            Slog.w(TAG, msg);
13642                            throw new SecurityException(msg);
13643                        }
13644                    } else {
13645                        // Limit broadcast to their own package.
13646                        intent.setPackage(callerApp.info.packageName);
13647                    }
13648                }
13649            } catch (RemoteException e) {
13650                Slog.w(TAG, "Remote exception", e);
13651                return ActivityManager.BROADCAST_SUCCESS;
13652            }
13653        }
13654
13655        // Handle special intents: if this broadcast is from the package
13656        // manager about a package being removed, we need to remove all of
13657        // its activities from the history stack.
13658        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13659                intent.getAction());
13660        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13661                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13662                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13663                || uidRemoved) {
13664            if (checkComponentPermission(
13665                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13666                    callingPid, callingUid, -1, true)
13667                    == PackageManager.PERMISSION_GRANTED) {
13668                if (uidRemoved) {
13669                    final Bundle intentExtras = intent.getExtras();
13670                    final int uid = intentExtras != null
13671                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13672                    if (uid >= 0) {
13673                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13674                        synchronized (bs) {
13675                            bs.removeUidStatsLocked(uid);
13676                        }
13677                        mAppOpsService.uidRemoved(uid);
13678                    }
13679                } else {
13680                    // If resources are unavailable just force stop all
13681                    // those packages and flush the attribute cache as well.
13682                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13683                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13684                        if (list != null && (list.length > 0)) {
13685                            for (String pkg : list) {
13686                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13687                                        "storage unmount");
13688                            }
13689                            sendPackageBroadcastLocked(
13690                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13691                        }
13692                    } else {
13693                        Uri data = intent.getData();
13694                        String ssp;
13695                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13696                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13697                                    intent.getAction());
13698                            boolean fullUninstall = removed &&
13699                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13700                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13701                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13702                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13703                                        false, fullUninstall, userId,
13704                                        removed ? "pkg removed" : "pkg changed");
13705                            }
13706                            if (removed) {
13707                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13708                                        new String[] {ssp}, userId);
13709                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13710                                    mAppOpsService.packageRemoved(
13711                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13712
13713                                    // Remove all permissions granted from/to this package
13714                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13715                                }
13716                            }
13717                        }
13718                    }
13719                }
13720            } else {
13721                String msg = "Permission Denial: " + intent.getAction()
13722                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13723                        + ", uid=" + callingUid + ")"
13724                        + " requires "
13725                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13726                Slog.w(TAG, msg);
13727                throw new SecurityException(msg);
13728            }
13729
13730        // Special case for adding a package: by default turn on compatibility
13731        // mode.
13732        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13733            Uri data = intent.getData();
13734            String ssp;
13735            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13736                mCompatModePackages.handlePackageAddedLocked(ssp,
13737                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13738            }
13739        }
13740
13741        /*
13742         * If this is the time zone changed action, queue up a message that will reset the timezone
13743         * of all currently running processes. This message will get queued up before the broadcast
13744         * happens.
13745         */
13746        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13747            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13748        }
13749
13750        /*
13751         * If the user set the time, let all running processes know.
13752         */
13753        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13754            final int is24Hour = intent.getBooleanExtra(
13755                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13756            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13757        }
13758
13759        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13760            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13761        }
13762
13763        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13764            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13765            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13766        }
13767
13768        // Add to the sticky list if requested.
13769        if (sticky) {
13770            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13771                    callingPid, callingUid)
13772                    != PackageManager.PERMISSION_GRANTED) {
13773                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13774                        + callingPid + ", uid=" + callingUid
13775                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13776                Slog.w(TAG, msg);
13777                throw new SecurityException(msg);
13778            }
13779            if (requiredPermission != null) {
13780                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13781                        + " and enforce permission " + requiredPermission);
13782                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13783            }
13784            if (intent.getComponent() != null) {
13785                throw new SecurityException(
13786                        "Sticky broadcasts can't target a specific component");
13787            }
13788            // We use userId directly here, since the "all" target is maintained
13789            // as a separate set of sticky broadcasts.
13790            if (userId != UserHandle.USER_ALL) {
13791                // But first, if this is not a broadcast to all users, then
13792                // make sure it doesn't conflict with an existing broadcast to
13793                // all users.
13794                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13795                        UserHandle.USER_ALL);
13796                if (stickies != null) {
13797                    ArrayList<Intent> list = stickies.get(intent.getAction());
13798                    if (list != null) {
13799                        int N = list.size();
13800                        int i;
13801                        for (i=0; i<N; i++) {
13802                            if (intent.filterEquals(list.get(i))) {
13803                                throw new IllegalArgumentException(
13804                                        "Sticky broadcast " + intent + " for user "
13805                                        + userId + " conflicts with existing global broadcast");
13806                            }
13807                        }
13808                    }
13809                }
13810            }
13811            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13812            if (stickies == null) {
13813                stickies = new ArrayMap<String, ArrayList<Intent>>();
13814                mStickyBroadcasts.put(userId, stickies);
13815            }
13816            ArrayList<Intent> list = stickies.get(intent.getAction());
13817            if (list == null) {
13818                list = new ArrayList<Intent>();
13819                stickies.put(intent.getAction(), list);
13820            }
13821            int N = list.size();
13822            int i;
13823            for (i=0; i<N; i++) {
13824                if (intent.filterEquals(list.get(i))) {
13825                    // This sticky already exists, replace it.
13826                    list.set(i, new Intent(intent));
13827                    break;
13828                }
13829            }
13830            if (i >= N) {
13831                list.add(new Intent(intent));
13832            }
13833        }
13834
13835        int[] users;
13836        if (userId == UserHandle.USER_ALL) {
13837            // Caller wants broadcast to go to all started users.
13838            users = mStartedUserArray;
13839        } else {
13840            // Caller wants broadcast to go to one specific user.
13841            users = new int[] {userId};
13842        }
13843
13844        // Figure out who all will receive this broadcast.
13845        List receivers = null;
13846        List<BroadcastFilter> registeredReceivers = null;
13847        // Need to resolve the intent to interested receivers...
13848        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13849                 == 0) {
13850            receivers = collectReceiverComponents(intent, resolvedType, users);
13851        }
13852        if (intent.getComponent() == null) {
13853            registeredReceivers = mReceiverResolver.queryIntent(intent,
13854                    resolvedType, false, userId);
13855        }
13856
13857        final boolean replacePending =
13858                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13859
13860        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13861                + " replacePending=" + replacePending);
13862
13863        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13864        if (!ordered && NR > 0) {
13865            // If we are not serializing this broadcast, then send the
13866            // registered receivers separately so they don't wait for the
13867            // components to be launched.
13868            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13869            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13870                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13871                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13872                    ordered, sticky, false, userId);
13873            if (DEBUG_BROADCAST) Slog.v(
13874                    TAG, "Enqueueing parallel broadcast " + r);
13875            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13876            if (!replaced) {
13877                queue.enqueueParallelBroadcastLocked(r);
13878                queue.scheduleBroadcastsLocked();
13879            }
13880            registeredReceivers = null;
13881            NR = 0;
13882        }
13883
13884        // Merge into one list.
13885        int ir = 0;
13886        if (receivers != null) {
13887            // A special case for PACKAGE_ADDED: do not allow the package
13888            // being added to see this broadcast.  This prevents them from
13889            // using this as a back door to get run as soon as they are
13890            // installed.  Maybe in the future we want to have a special install
13891            // broadcast or such for apps, but we'd like to deliberately make
13892            // this decision.
13893            String skipPackages[] = null;
13894            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13895                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13896                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13897                Uri data = intent.getData();
13898                if (data != null) {
13899                    String pkgName = data.getSchemeSpecificPart();
13900                    if (pkgName != null) {
13901                        skipPackages = new String[] { pkgName };
13902                    }
13903                }
13904            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13905                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13906            }
13907            if (skipPackages != null && (skipPackages.length > 0)) {
13908                for (String skipPackage : skipPackages) {
13909                    if (skipPackage != null) {
13910                        int NT = receivers.size();
13911                        for (int it=0; it<NT; it++) {
13912                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13913                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13914                                receivers.remove(it);
13915                                it--;
13916                                NT--;
13917                            }
13918                        }
13919                    }
13920                }
13921            }
13922
13923            int NT = receivers != null ? receivers.size() : 0;
13924            int it = 0;
13925            ResolveInfo curt = null;
13926            BroadcastFilter curr = null;
13927            while (it < NT && ir < NR) {
13928                if (curt == null) {
13929                    curt = (ResolveInfo)receivers.get(it);
13930                }
13931                if (curr == null) {
13932                    curr = registeredReceivers.get(ir);
13933                }
13934                if (curr.getPriority() >= curt.priority) {
13935                    // Insert this broadcast record into the final list.
13936                    receivers.add(it, curr);
13937                    ir++;
13938                    curr = null;
13939                    it++;
13940                    NT++;
13941                } else {
13942                    // Skip to the next ResolveInfo in the final list.
13943                    it++;
13944                    curt = null;
13945                }
13946            }
13947        }
13948        while (ir < NR) {
13949            if (receivers == null) {
13950                receivers = new ArrayList();
13951            }
13952            receivers.add(registeredReceivers.get(ir));
13953            ir++;
13954        }
13955
13956        if ((receivers != null && receivers.size() > 0)
13957                || resultTo != null) {
13958            BroadcastQueue queue = broadcastQueueForIntent(intent);
13959            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13960                    callerPackage, callingPid, callingUid, resolvedType,
13961                    requiredPermission, appOp, receivers, resultTo, resultCode,
13962                    resultData, map, ordered, sticky, false, userId);
13963            if (DEBUG_BROADCAST) Slog.v(
13964                    TAG, "Enqueueing ordered broadcast " + r
13965                    + ": prev had " + queue.mOrderedBroadcasts.size());
13966            if (DEBUG_BROADCAST) {
13967                int seq = r.intent.getIntExtra("seq", -1);
13968                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13969            }
13970            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13971            if (!replaced) {
13972                queue.enqueueOrderedBroadcastLocked(r);
13973                queue.scheduleBroadcastsLocked();
13974            }
13975        }
13976
13977        return ActivityManager.BROADCAST_SUCCESS;
13978    }
13979
13980    final Intent verifyBroadcastLocked(Intent intent) {
13981        // Refuse possible leaked file descriptors
13982        if (intent != null && intent.hasFileDescriptors() == true) {
13983            throw new IllegalArgumentException("File descriptors passed in Intent");
13984        }
13985
13986        int flags = intent.getFlags();
13987
13988        if (!mProcessesReady) {
13989            // if the caller really truly claims to know what they're doing, go
13990            // ahead and allow the broadcast without launching any receivers
13991            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13992                intent = new Intent(intent);
13993                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13994            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13995                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13996                        + " before boot completion");
13997                throw new IllegalStateException("Cannot broadcast before boot completed");
13998            }
13999        }
14000
14001        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14002            throw new IllegalArgumentException(
14003                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14004        }
14005
14006        return intent;
14007    }
14008
14009    public final int broadcastIntent(IApplicationThread caller,
14010            Intent intent, String resolvedType, IIntentReceiver resultTo,
14011            int resultCode, String resultData, Bundle map,
14012            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14013        enforceNotIsolatedCaller("broadcastIntent");
14014        synchronized(this) {
14015            intent = verifyBroadcastLocked(intent);
14016
14017            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14018            final int callingPid = Binder.getCallingPid();
14019            final int callingUid = Binder.getCallingUid();
14020            final long origId = Binder.clearCallingIdentity();
14021            int res = broadcastIntentLocked(callerApp,
14022                    callerApp != null ? callerApp.info.packageName : null,
14023                    intent, resolvedType, resultTo,
14024                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14025                    callingPid, callingUid, userId);
14026            Binder.restoreCallingIdentity(origId);
14027            return res;
14028        }
14029    }
14030
14031    int broadcastIntentInPackage(String packageName, int uid,
14032            Intent intent, String resolvedType, IIntentReceiver resultTo,
14033            int resultCode, String resultData, Bundle map,
14034            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14035        synchronized(this) {
14036            intent = verifyBroadcastLocked(intent);
14037
14038            final long origId = Binder.clearCallingIdentity();
14039            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14040                    resultTo, resultCode, resultData, map, requiredPermission,
14041                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14042            Binder.restoreCallingIdentity(origId);
14043            return res;
14044        }
14045    }
14046
14047    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14048        // Refuse possible leaked file descriptors
14049        if (intent != null && intent.hasFileDescriptors() == true) {
14050            throw new IllegalArgumentException("File descriptors passed in Intent");
14051        }
14052
14053        userId = handleIncomingUser(Binder.getCallingPid(),
14054                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14055
14056        synchronized(this) {
14057            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14058                    != PackageManager.PERMISSION_GRANTED) {
14059                String msg = "Permission Denial: unbroadcastIntent() from pid="
14060                        + Binder.getCallingPid()
14061                        + ", uid=" + Binder.getCallingUid()
14062                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14063                Slog.w(TAG, msg);
14064                throw new SecurityException(msg);
14065            }
14066            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14067            if (stickies != null) {
14068                ArrayList<Intent> list = stickies.get(intent.getAction());
14069                if (list != null) {
14070                    int N = list.size();
14071                    int i;
14072                    for (i=0; i<N; i++) {
14073                        if (intent.filterEquals(list.get(i))) {
14074                            list.remove(i);
14075                            break;
14076                        }
14077                    }
14078                    if (list.size() <= 0) {
14079                        stickies.remove(intent.getAction());
14080                    }
14081                }
14082                if (stickies.size() <= 0) {
14083                    mStickyBroadcasts.remove(userId);
14084                }
14085            }
14086        }
14087    }
14088
14089    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14090            String resultData, Bundle resultExtras, boolean resultAbort) {
14091        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14092        if (r == null) {
14093            Slog.w(TAG, "finishReceiver called but not found on queue");
14094            return false;
14095        }
14096
14097        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14098    }
14099
14100    void backgroundServicesFinishedLocked(int userId) {
14101        for (BroadcastQueue queue : mBroadcastQueues) {
14102            queue.backgroundServicesFinishedLocked(userId);
14103        }
14104    }
14105
14106    public void finishReceiver(IBinder who, int resultCode, String resultData,
14107            Bundle resultExtras, boolean resultAbort) {
14108        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14109
14110        // Refuse possible leaked file descriptors
14111        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14112            throw new IllegalArgumentException("File descriptors passed in Bundle");
14113        }
14114
14115        final long origId = Binder.clearCallingIdentity();
14116        try {
14117            boolean doNext = false;
14118            BroadcastRecord r;
14119
14120            synchronized(this) {
14121                r = broadcastRecordForReceiverLocked(who);
14122                if (r != null) {
14123                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14124                        resultData, resultExtras, resultAbort, true);
14125                }
14126            }
14127
14128            if (doNext) {
14129                r.queue.processNextBroadcast(false);
14130            }
14131            trimApplications();
14132        } finally {
14133            Binder.restoreCallingIdentity(origId);
14134        }
14135    }
14136
14137    // =========================================================
14138    // INSTRUMENTATION
14139    // =========================================================
14140
14141    public boolean startInstrumentation(ComponentName className,
14142            String profileFile, int flags, Bundle arguments,
14143            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14144            int userId) {
14145        enforceNotIsolatedCaller("startInstrumentation");
14146        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14147                userId, false, true, "startInstrumentation", null);
14148        // Refuse possible leaked file descriptors
14149        if (arguments != null && arguments.hasFileDescriptors()) {
14150            throw new IllegalArgumentException("File descriptors passed in Bundle");
14151        }
14152
14153        synchronized(this) {
14154            InstrumentationInfo ii = null;
14155            ApplicationInfo ai = null;
14156            try {
14157                ii = mContext.getPackageManager().getInstrumentationInfo(
14158                    className, STOCK_PM_FLAGS);
14159                ai = AppGlobals.getPackageManager().getApplicationInfo(
14160                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14161            } catch (PackageManager.NameNotFoundException e) {
14162            } catch (RemoteException e) {
14163            }
14164            if (ii == null) {
14165                reportStartInstrumentationFailure(watcher, className,
14166                        "Unable to find instrumentation info for: " + className);
14167                return false;
14168            }
14169            if (ai == null) {
14170                reportStartInstrumentationFailure(watcher, className,
14171                        "Unable to find instrumentation target package: " + ii.targetPackage);
14172                return false;
14173            }
14174
14175            int match = mContext.getPackageManager().checkSignatures(
14176                    ii.targetPackage, ii.packageName);
14177            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14178                String msg = "Permission Denial: starting instrumentation "
14179                        + className + " from pid="
14180                        + Binder.getCallingPid()
14181                        + ", uid=" + Binder.getCallingPid()
14182                        + " not allowed because package " + ii.packageName
14183                        + " does not have a signature matching the target "
14184                        + ii.targetPackage;
14185                reportStartInstrumentationFailure(watcher, className, msg);
14186                throw new SecurityException(msg);
14187            }
14188
14189            final long origId = Binder.clearCallingIdentity();
14190            // Instrumentation can kill and relaunch even persistent processes
14191            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14192                    "start instr");
14193            ProcessRecord app = addAppLocked(ai, false);
14194            app.instrumentationClass = className;
14195            app.instrumentationInfo = ai;
14196            app.instrumentationProfileFile = profileFile;
14197            app.instrumentationArguments = arguments;
14198            app.instrumentationWatcher = watcher;
14199            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14200            app.instrumentationResultClass = className;
14201            Binder.restoreCallingIdentity(origId);
14202        }
14203
14204        return true;
14205    }
14206
14207    /**
14208     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14209     * error to the logs, but if somebody is watching, send the report there too.  This enables
14210     * the "am" command to report errors with more information.
14211     *
14212     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14213     * @param cn The component name of the instrumentation.
14214     * @param report The error report.
14215     */
14216    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14217            ComponentName cn, String report) {
14218        Slog.w(TAG, report);
14219        try {
14220            if (watcher != null) {
14221                Bundle results = new Bundle();
14222                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14223                results.putString("Error", report);
14224                watcher.instrumentationStatus(cn, -1, results);
14225            }
14226        } catch (RemoteException e) {
14227            Slog.w(TAG, e);
14228        }
14229    }
14230
14231    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14232        if (app.instrumentationWatcher != null) {
14233            try {
14234                // NOTE:  IInstrumentationWatcher *must* be oneway here
14235                app.instrumentationWatcher.instrumentationFinished(
14236                    app.instrumentationClass,
14237                    resultCode,
14238                    results);
14239            } catch (RemoteException e) {
14240            }
14241        }
14242        if (app.instrumentationUiAutomationConnection != null) {
14243            try {
14244                app.instrumentationUiAutomationConnection.shutdown();
14245            } catch (RemoteException re) {
14246                /* ignore */
14247            }
14248            // Only a UiAutomation can set this flag and now that
14249            // it is finished we make sure it is reset to its default.
14250            mUserIsMonkey = false;
14251        }
14252        app.instrumentationWatcher = null;
14253        app.instrumentationUiAutomationConnection = null;
14254        app.instrumentationClass = null;
14255        app.instrumentationInfo = null;
14256        app.instrumentationProfileFile = null;
14257        app.instrumentationArguments = null;
14258
14259        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14260                "finished inst");
14261    }
14262
14263    public void finishInstrumentation(IApplicationThread target,
14264            int resultCode, Bundle results) {
14265        int userId = UserHandle.getCallingUserId();
14266        // Refuse possible leaked file descriptors
14267        if (results != null && results.hasFileDescriptors()) {
14268            throw new IllegalArgumentException("File descriptors passed in Intent");
14269        }
14270
14271        synchronized(this) {
14272            ProcessRecord app = getRecordForAppLocked(target);
14273            if (app == null) {
14274                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14275                return;
14276            }
14277            final long origId = Binder.clearCallingIdentity();
14278            finishInstrumentationLocked(app, resultCode, results);
14279            Binder.restoreCallingIdentity(origId);
14280        }
14281    }
14282
14283    // =========================================================
14284    // CONFIGURATION
14285    // =========================================================
14286
14287    public ConfigurationInfo getDeviceConfigurationInfo() {
14288        ConfigurationInfo config = new ConfigurationInfo();
14289        synchronized (this) {
14290            config.reqTouchScreen = mConfiguration.touchscreen;
14291            config.reqKeyboardType = mConfiguration.keyboard;
14292            config.reqNavigation = mConfiguration.navigation;
14293            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14294                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14295                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14296            }
14297            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14298                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14299                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14300            }
14301            config.reqGlEsVersion = GL_ES_VERSION;
14302        }
14303        return config;
14304    }
14305
14306    ActivityStack getFocusedStack() {
14307        return mStackSupervisor.getFocusedStack();
14308    }
14309
14310    public Configuration getConfiguration() {
14311        Configuration ci;
14312        synchronized(this) {
14313            ci = new Configuration(mConfiguration);
14314        }
14315        return ci;
14316    }
14317
14318    public void updatePersistentConfiguration(Configuration values) {
14319        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14320                "updateConfiguration()");
14321        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14322                "updateConfiguration()");
14323        if (values == null) {
14324            throw new NullPointerException("Configuration must not be null");
14325        }
14326
14327        synchronized(this) {
14328            final long origId = Binder.clearCallingIdentity();
14329            updateConfigurationLocked(values, null, true, false);
14330            Binder.restoreCallingIdentity(origId);
14331        }
14332    }
14333
14334    public void updateConfiguration(Configuration values) {
14335        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14336                "updateConfiguration()");
14337
14338        synchronized(this) {
14339            if (values == null && mWindowManager != null) {
14340                // sentinel: fetch the current configuration from the window manager
14341                values = mWindowManager.computeNewConfiguration();
14342            }
14343
14344            if (mWindowManager != null) {
14345                mProcessList.applyDisplaySize(mWindowManager);
14346            }
14347
14348            final long origId = Binder.clearCallingIdentity();
14349            if (values != null) {
14350                Settings.System.clearConfiguration(values);
14351            }
14352            updateConfigurationLocked(values, null, false, false);
14353            Binder.restoreCallingIdentity(origId);
14354        }
14355    }
14356
14357    /**
14358     * Do either or both things: (1) change the current configuration, and (2)
14359     * make sure the given activity is running with the (now) current
14360     * configuration.  Returns true if the activity has been left running, or
14361     * false if <var>starting</var> is being destroyed to match the new
14362     * configuration.
14363     * @param persistent TODO
14364     */
14365    boolean updateConfigurationLocked(Configuration values,
14366            ActivityRecord starting, boolean persistent, boolean initLocale) {
14367        int changes = 0;
14368
14369        if (values != null) {
14370            Configuration newConfig = new Configuration(mConfiguration);
14371            changes = newConfig.updateFrom(values);
14372            if (changes != 0) {
14373                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14374                    Slog.i(TAG, "Updating configuration to: " + values);
14375                }
14376
14377                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14378
14379                if (values.locale != null && !initLocale) {
14380                    saveLocaleLocked(values.locale,
14381                                     !values.locale.equals(mConfiguration.locale),
14382                                     values.userSetLocale);
14383                }
14384
14385                mConfigurationSeq++;
14386                if (mConfigurationSeq <= 0) {
14387                    mConfigurationSeq = 1;
14388                }
14389                newConfig.seq = mConfigurationSeq;
14390                mConfiguration = newConfig;
14391                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14392
14393                final Configuration configCopy = new Configuration(mConfiguration);
14394
14395                // TODO: If our config changes, should we auto dismiss any currently
14396                // showing dialogs?
14397                mShowDialogs = shouldShowDialogs(newConfig);
14398
14399                AttributeCache ac = AttributeCache.instance();
14400                if (ac != null) {
14401                    ac.updateConfiguration(configCopy);
14402                }
14403
14404                // Make sure all resources in our process are updated
14405                // right now, so that anyone who is going to retrieve
14406                // resource values after we return will be sure to get
14407                // the new ones.  This is especially important during
14408                // boot, where the first config change needs to guarantee
14409                // all resources have that config before following boot
14410                // code is executed.
14411                mSystemThread.applyConfigurationToResources(configCopy);
14412
14413                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14414                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14415                    msg.obj = new Configuration(configCopy);
14416                    mHandler.sendMessage(msg);
14417                }
14418
14419                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14420                    ProcessRecord app = mLruProcesses.get(i);
14421                    try {
14422                        if (app.thread != null) {
14423                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14424                                    + app.processName + " new config " + mConfiguration);
14425                            app.thread.scheduleConfigurationChanged(configCopy);
14426                        }
14427                    } catch (Exception e) {
14428                    }
14429                }
14430                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14431                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14432                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14433                        | Intent.FLAG_RECEIVER_FOREGROUND);
14434                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14435                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14436                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14437                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14438                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14439                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14440                    broadcastIntentLocked(null, null, intent,
14441                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14442                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14443                }
14444            }
14445        }
14446
14447        boolean kept = true;
14448        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14449        // mainStack is null during startup.
14450        if (mainStack != null) {
14451            if (changes != 0 && starting == null) {
14452                // If the configuration changed, and the caller is not already
14453                // in the process of starting an activity, then find the top
14454                // activity to check if its configuration needs to change.
14455                starting = mainStack.topRunningActivityLocked(null);
14456            }
14457
14458            if (starting != null) {
14459                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14460                // And we need to make sure at this point that all other activities
14461                // are made visible with the correct configuration.
14462                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14463            }
14464        }
14465
14466        if (values != null && mWindowManager != null) {
14467            mWindowManager.setNewConfiguration(mConfiguration);
14468        }
14469
14470        return kept;
14471    }
14472
14473    /**
14474     * Decide based on the configuration whether we should shouw the ANR,
14475     * crash, etc dialogs.  The idea is that if there is no affordnace to
14476     * press the on-screen buttons, we shouldn't show the dialog.
14477     *
14478     * A thought: SystemUI might also want to get told about this, the Power
14479     * dialog / global actions also might want different behaviors.
14480     */
14481    private static final boolean shouldShowDialogs(Configuration config) {
14482        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14483                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14484    }
14485
14486    /**
14487     * Save the locale.  You must be inside a synchronized (this) block.
14488     */
14489    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14490        if(isDiff) {
14491            SystemProperties.set("user.language", l.getLanguage());
14492            SystemProperties.set("user.region", l.getCountry());
14493        }
14494
14495        if(isPersist) {
14496            SystemProperties.set("persist.sys.language", l.getLanguage());
14497            SystemProperties.set("persist.sys.country", l.getCountry());
14498            SystemProperties.set("persist.sys.localevar", l.getVariant());
14499        }
14500    }
14501
14502    @Override
14503    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14504        ActivityRecord srec = ActivityRecord.forToken(token);
14505        return srec != null && srec.task.affinity != null &&
14506                srec.task.affinity.equals(destAffinity);
14507    }
14508
14509    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14510            Intent resultData) {
14511
14512        synchronized (this) {
14513            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14514            if (stack != null) {
14515                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14516            }
14517            return false;
14518        }
14519    }
14520
14521    public int getLaunchedFromUid(IBinder activityToken) {
14522        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14523        if (srec == null) {
14524            return -1;
14525        }
14526        return srec.launchedFromUid;
14527    }
14528
14529    public String getLaunchedFromPackage(IBinder activityToken) {
14530        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14531        if (srec == null) {
14532            return null;
14533        }
14534        return srec.launchedFromPackage;
14535    }
14536
14537    // =========================================================
14538    // LIFETIME MANAGEMENT
14539    // =========================================================
14540
14541    // Returns which broadcast queue the app is the current [or imminent] receiver
14542    // on, or 'null' if the app is not an active broadcast recipient.
14543    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14544        BroadcastRecord r = app.curReceiver;
14545        if (r != null) {
14546            return r.queue;
14547        }
14548
14549        // It's not the current receiver, but it might be starting up to become one
14550        synchronized (this) {
14551            for (BroadcastQueue queue : mBroadcastQueues) {
14552                r = queue.mPendingBroadcast;
14553                if (r != null && r.curApp == app) {
14554                    // found it; report which queue it's in
14555                    return queue;
14556                }
14557            }
14558        }
14559
14560        return null;
14561    }
14562
14563    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14564            boolean doingAll, long now) {
14565        if (mAdjSeq == app.adjSeq) {
14566            // This adjustment has already been computed.
14567            return app.curRawAdj;
14568        }
14569
14570        if (app.thread == null) {
14571            app.adjSeq = mAdjSeq;
14572            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14573            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14574            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14575        }
14576
14577        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14578        app.adjSource = null;
14579        app.adjTarget = null;
14580        app.empty = false;
14581        app.cached = false;
14582
14583        final int activitiesSize = app.activities.size();
14584
14585        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14586            // The max adjustment doesn't allow this app to be anything
14587            // below foreground, so it is not worth doing work for it.
14588            app.adjType = "fixed";
14589            app.adjSeq = mAdjSeq;
14590            app.curRawAdj = app.maxAdj;
14591            app.foregroundActivities = false;
14592            app.keeping = true;
14593            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14594            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14595            // System process can do UI, and when they do we want to have
14596            // them trim their memory after the user leaves the UI.  To
14597            // facilitate this, here we need to determine whether or not it
14598            // is currently showing UI.
14599            app.systemNoUi = true;
14600            if (app == TOP_APP) {
14601                app.systemNoUi = false;
14602            } else if (activitiesSize > 0) {
14603                for (int j = 0; j < activitiesSize; j++) {
14604                    final ActivityRecord r = app.activities.get(j);
14605                    if (r.visible) {
14606                        app.systemNoUi = false;
14607                    }
14608                }
14609            }
14610            if (!app.systemNoUi) {
14611                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14612            }
14613            return (app.curAdj=app.maxAdj);
14614        }
14615
14616        app.keeping = false;
14617        app.systemNoUi = false;
14618
14619        // Determine the importance of the process, starting with most
14620        // important to least, and assign an appropriate OOM adjustment.
14621        int adj;
14622        int schedGroup;
14623        int procState;
14624        boolean foregroundActivities = false;
14625        boolean interesting = false;
14626        BroadcastQueue queue;
14627        if (app == TOP_APP) {
14628            // The last app on the list is the foreground app.
14629            adj = ProcessList.FOREGROUND_APP_ADJ;
14630            schedGroup = Process.THREAD_GROUP_DEFAULT;
14631            app.adjType = "top-activity";
14632            foregroundActivities = true;
14633            interesting = true;
14634            procState = ActivityManager.PROCESS_STATE_TOP;
14635        } else if (app.instrumentationClass != null) {
14636            // Don't want to kill running instrumentation.
14637            adj = ProcessList.FOREGROUND_APP_ADJ;
14638            schedGroup = Process.THREAD_GROUP_DEFAULT;
14639            app.adjType = "instrumentation";
14640            interesting = true;
14641            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14642        } else if ((queue = isReceivingBroadcast(app)) != null) {
14643            // An app that is currently receiving a broadcast also
14644            // counts as being in the foreground for OOM killer purposes.
14645            // It's placed in a sched group based on the nature of the
14646            // broadcast as reflected by which queue it's active in.
14647            adj = ProcessList.FOREGROUND_APP_ADJ;
14648            schedGroup = (queue == mFgBroadcastQueue)
14649                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14650            app.adjType = "broadcast";
14651            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14652        } else if (app.executingServices.size() > 0) {
14653            // An app that is currently executing a service callback also
14654            // counts as being in the foreground.
14655            adj = ProcessList.FOREGROUND_APP_ADJ;
14656            schedGroup = app.execServicesFg ?
14657                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14658            app.adjType = "exec-service";
14659            procState = ActivityManager.PROCESS_STATE_SERVICE;
14660            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14661        } else {
14662            // As far as we know the process is empty.  We may change our mind later.
14663            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14664            // At this point we don't actually know the adjustment.  Use the cached adj
14665            // value that the caller wants us to.
14666            adj = cachedAdj;
14667            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14668            app.cached = true;
14669            app.empty = true;
14670            app.adjType = "cch-empty";
14671        }
14672
14673        // Examine all activities if not already foreground.
14674        if (!foregroundActivities && activitiesSize > 0) {
14675            for (int j = 0; j < activitiesSize; j++) {
14676                final ActivityRecord r = app.activities.get(j);
14677                if (r.app != app) {
14678                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14679                            + app + "?!?");
14680                    continue;
14681                }
14682                if (r.visible) {
14683                    // App has a visible activity; only upgrade adjustment.
14684                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14685                        adj = ProcessList.VISIBLE_APP_ADJ;
14686                        app.adjType = "visible";
14687                    }
14688                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14689                        procState = ActivityManager.PROCESS_STATE_TOP;
14690                    }
14691                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14692                    app.cached = false;
14693                    app.empty = false;
14694                    foregroundActivities = true;
14695                    break;
14696                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14697                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14698                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14699                        app.adjType = "pausing";
14700                    }
14701                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14702                        procState = ActivityManager.PROCESS_STATE_TOP;
14703                    }
14704                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14705                    app.cached = false;
14706                    app.empty = false;
14707                    foregroundActivities = true;
14708                } else if (r.state == ActivityState.STOPPING) {
14709                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14710                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14711                        app.adjType = "stopping";
14712                    }
14713                    // For the process state, we will at this point consider the
14714                    // process to be cached.  It will be cached either as an activity
14715                    // or empty depending on whether the activity is finishing.  We do
14716                    // this so that we can treat the process as cached for purposes of
14717                    // memory trimming (determing current memory level, trim command to
14718                    // send to process) since there can be an arbitrary number of stopping
14719                    // processes and they should soon all go into the cached state.
14720                    if (!r.finishing) {
14721                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14722                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14723                        }
14724                    }
14725                    app.cached = false;
14726                    app.empty = false;
14727                    foregroundActivities = true;
14728                } else {
14729                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14730                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14731                        app.adjType = "cch-act";
14732                    }
14733                }
14734            }
14735        }
14736
14737        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14738            if (app.foregroundServices) {
14739                // The user is aware of this app, so make it visible.
14740                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14741                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14742                app.cached = false;
14743                app.adjType = "fg-service";
14744                schedGroup = Process.THREAD_GROUP_DEFAULT;
14745            } else if (app.forcingToForeground != null) {
14746                // The user is aware of this app, so make it visible.
14747                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14748                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14749                app.cached = false;
14750                app.adjType = "force-fg";
14751                app.adjSource = app.forcingToForeground;
14752                schedGroup = Process.THREAD_GROUP_DEFAULT;
14753            }
14754        }
14755
14756        if (app.foregroundServices) {
14757            interesting = true;
14758        }
14759
14760        if (app == mHeavyWeightProcess) {
14761            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14762                // We don't want to kill the current heavy-weight process.
14763                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14764                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14765                app.cached = false;
14766                app.adjType = "heavy";
14767            }
14768            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14769                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14770            }
14771        }
14772
14773        if (app == mHomeProcess) {
14774            if (adj > ProcessList.HOME_APP_ADJ) {
14775                // This process is hosting what we currently consider to be the
14776                // home app, so we don't want to let it go into the background.
14777                adj = ProcessList.HOME_APP_ADJ;
14778                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14779                app.cached = false;
14780                app.adjType = "home";
14781            }
14782            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14783                procState = ActivityManager.PROCESS_STATE_HOME;
14784            }
14785        }
14786
14787        if (app == mPreviousProcess && app.activities.size() > 0) {
14788            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14789                // This was the previous process that showed UI to the user.
14790                // We want to try to keep it around more aggressively, to give
14791                // a good experience around switching between two apps.
14792                adj = ProcessList.PREVIOUS_APP_ADJ;
14793                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14794                app.cached = false;
14795                app.adjType = "previous";
14796            }
14797            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14798                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14799            }
14800        }
14801
14802        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14803                + " reason=" + app.adjType);
14804
14805        // By default, we use the computed adjustment.  It may be changed if
14806        // there are applications dependent on our services or providers, but
14807        // this gives us a baseline and makes sure we don't get into an
14808        // infinite recursion.
14809        app.adjSeq = mAdjSeq;
14810        app.curRawAdj = adj;
14811        app.hasStartedServices = false;
14812
14813        if (mBackupTarget != null && app == mBackupTarget.app) {
14814            // If possible we want to avoid killing apps while they're being backed up
14815            if (adj > ProcessList.BACKUP_APP_ADJ) {
14816                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14817                adj = ProcessList.BACKUP_APP_ADJ;
14818                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14819                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14820                }
14821                app.adjType = "backup";
14822                app.cached = false;
14823            }
14824            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14825                procState = ActivityManager.PROCESS_STATE_BACKUP;
14826            }
14827        }
14828
14829        boolean mayBeTop = false;
14830
14831        for (int is = app.services.size()-1;
14832                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14833                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14834                        || procState > ActivityManager.PROCESS_STATE_TOP);
14835                is--) {
14836            ServiceRecord s = app.services.valueAt(is);
14837            if (s.startRequested) {
14838                app.hasStartedServices = true;
14839                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14840                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14841                }
14842                if (app.hasShownUi && app != mHomeProcess) {
14843                    // If this process has shown some UI, let it immediately
14844                    // go to the LRU list because it may be pretty heavy with
14845                    // UI stuff.  We'll tag it with a label just to help
14846                    // debug and understand what is going on.
14847                    if (adj > ProcessList.SERVICE_ADJ) {
14848                        app.adjType = "cch-started-ui-services";
14849                    }
14850                } else {
14851                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14852                        // This service has seen some activity within
14853                        // recent memory, so we will keep its process ahead
14854                        // of the background processes.
14855                        if (adj > ProcessList.SERVICE_ADJ) {
14856                            adj = ProcessList.SERVICE_ADJ;
14857                            app.adjType = "started-services";
14858                            app.cached = false;
14859                        }
14860                    }
14861                    // If we have let the service slide into the background
14862                    // state, still have some text describing what it is doing
14863                    // even though the service no longer has an impact.
14864                    if (adj > ProcessList.SERVICE_ADJ) {
14865                        app.adjType = "cch-started-services";
14866                    }
14867                }
14868                // Don't kill this process because it is doing work; it
14869                // has said it is doing work.
14870                app.keeping = true;
14871            }
14872            for (int conni = s.connections.size()-1;
14873                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14874                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14875                            || procState > ActivityManager.PROCESS_STATE_TOP);
14876                    conni--) {
14877                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14878                for (int i = 0;
14879                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14880                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14881                                || procState > ActivityManager.PROCESS_STATE_TOP);
14882                        i++) {
14883                    // XXX should compute this based on the max of
14884                    // all connected clients.
14885                    ConnectionRecord cr = clist.get(i);
14886                    if (cr.binding.client == app) {
14887                        // Binding to ourself is not interesting.
14888                        continue;
14889                    }
14890                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14891                        ProcessRecord client = cr.binding.client;
14892                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14893                                TOP_APP, doingAll, now);
14894                        int clientProcState = client.curProcState;
14895                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14896                            // If the other app is cached for any reason, for purposes here
14897                            // we are going to consider it empty.  The specific cached state
14898                            // doesn't propagate except under certain conditions.
14899                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14900                        }
14901                        String adjType = null;
14902                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14903                            // Not doing bind OOM management, so treat
14904                            // this guy more like a started service.
14905                            if (app.hasShownUi && app != mHomeProcess) {
14906                                // If this process has shown some UI, let it immediately
14907                                // go to the LRU list because it may be pretty heavy with
14908                                // UI stuff.  We'll tag it with a label just to help
14909                                // debug and understand what is going on.
14910                                if (adj > clientAdj) {
14911                                    adjType = "cch-bound-ui-services";
14912                                }
14913                                app.cached = false;
14914                                clientAdj = adj;
14915                                clientProcState = procState;
14916                            } else {
14917                                if (now >= (s.lastActivity
14918                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14919                                    // This service has not seen activity within
14920                                    // recent memory, so allow it to drop to the
14921                                    // LRU list if there is no other reason to keep
14922                                    // it around.  We'll also tag it with a label just
14923                                    // to help debug and undertand what is going on.
14924                                    if (adj > clientAdj) {
14925                                        adjType = "cch-bound-services";
14926                                    }
14927                                    clientAdj = adj;
14928                                }
14929                            }
14930                        }
14931                        if (adj > clientAdj) {
14932                            // If this process has recently shown UI, and
14933                            // the process that is binding to it is less
14934                            // important than being visible, then we don't
14935                            // care about the binding as much as we care
14936                            // about letting this process get into the LRU
14937                            // list to be killed and restarted if needed for
14938                            // memory.
14939                            if (app.hasShownUi && app != mHomeProcess
14940                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14941                                adjType = "cch-bound-ui-services";
14942                            } else {
14943                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14944                                        |Context.BIND_IMPORTANT)) != 0) {
14945                                    adj = clientAdj;
14946                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14947                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14948                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14949                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14950                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14951                                    adj = clientAdj;
14952                                } else {
14953                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14954                                        adj = ProcessList.VISIBLE_APP_ADJ;
14955                                    }
14956                                }
14957                                if (!client.cached) {
14958                                    app.cached = false;
14959                                }
14960                                if (client.keeping) {
14961                                    app.keeping = true;
14962                                }
14963                                adjType = "service";
14964                            }
14965                        }
14966                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14967                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14968                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14969                            }
14970                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14971                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14972                                    // Special handling of clients who are in the top state.
14973                                    // We *may* want to consider this process to be in the
14974                                    // top state as well, but only if there is not another
14975                                    // reason for it to be running.  Being on the top is a
14976                                    // special state, meaning you are specifically running
14977                                    // for the current top app.  If the process is already
14978                                    // running in the background for some other reason, it
14979                                    // is more important to continue considering it to be
14980                                    // in the background state.
14981                                    mayBeTop = true;
14982                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14983                                } else {
14984                                    // Special handling for above-top states (persistent
14985                                    // processes).  These should not bring the current process
14986                                    // into the top state, since they are not on top.  Instead
14987                                    // give them the best state after that.
14988                                    clientProcState =
14989                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14990                                }
14991                            }
14992                        } else {
14993                            if (clientProcState <
14994                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14995                                clientProcState =
14996                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14997                            }
14998                        }
14999                        if (procState > clientProcState) {
15000                            procState = clientProcState;
15001                        }
15002                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15003                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15004                            app.pendingUiClean = true;
15005                        }
15006                        if (adjType != null) {
15007                            app.adjType = adjType;
15008                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15009                                    .REASON_SERVICE_IN_USE;
15010                            app.adjSource = cr.binding.client;
15011                            app.adjSourceOom = clientAdj;
15012                            app.adjTarget = s.name;
15013                        }
15014                    }
15015                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15016                        app.treatLikeActivity = true;
15017                    }
15018                    final ActivityRecord a = cr.activity;
15019                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15020                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15021                                (a.visible || a.state == ActivityState.RESUMED
15022                                 || a.state == ActivityState.PAUSING)) {
15023                            adj = ProcessList.FOREGROUND_APP_ADJ;
15024                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15025                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15026                            }
15027                            app.cached = false;
15028                            app.adjType = "service";
15029                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15030                                    .REASON_SERVICE_IN_USE;
15031                            app.adjSource = a;
15032                            app.adjSourceOom = adj;
15033                            app.adjTarget = s.name;
15034                        }
15035                    }
15036                }
15037            }
15038        }
15039
15040        for (int provi = app.pubProviders.size()-1;
15041                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15042                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15043                        || procState > ActivityManager.PROCESS_STATE_TOP);
15044                provi--) {
15045            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15046            for (int i = cpr.connections.size()-1;
15047                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15048                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15049                            || procState > ActivityManager.PROCESS_STATE_TOP);
15050                    i--) {
15051                ContentProviderConnection conn = cpr.connections.get(i);
15052                ProcessRecord client = conn.client;
15053                if (client == app) {
15054                    // Being our own client is not interesting.
15055                    continue;
15056                }
15057                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15058                int clientProcState = client.curProcState;
15059                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15060                    // If the other app is cached for any reason, for purposes here
15061                    // we are going to consider it empty.
15062                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15063                }
15064                if (adj > clientAdj) {
15065                    if (app.hasShownUi && app != mHomeProcess
15066                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15067                        app.adjType = "cch-ui-provider";
15068                    } else {
15069                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15070                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15071                        app.adjType = "provider";
15072                    }
15073                    app.cached &= client.cached;
15074                    app.keeping |= client.keeping;
15075                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15076                            .REASON_PROVIDER_IN_USE;
15077                    app.adjSource = client;
15078                    app.adjSourceOom = clientAdj;
15079                    app.adjTarget = cpr.name;
15080                }
15081                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15082                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15083                        // Special handling of clients who are in the top state.
15084                        // We *may* want to consider this process to be in the
15085                        // top state as well, but only if there is not another
15086                        // reason for it to be running.  Being on the top is a
15087                        // special state, meaning you are specifically running
15088                        // for the current top app.  If the process is already
15089                        // running in the background for some other reason, it
15090                        // is more important to continue considering it to be
15091                        // in the background state.
15092                        mayBeTop = true;
15093                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15094                    } else {
15095                        // Special handling for above-top states (persistent
15096                        // processes).  These should not bring the current process
15097                        // into the top state, since they are not on top.  Instead
15098                        // give them the best state after that.
15099                        clientProcState =
15100                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15101                    }
15102                }
15103                if (procState > clientProcState) {
15104                    procState = clientProcState;
15105                }
15106                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15107                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15108                }
15109            }
15110            // If the provider has external (non-framework) process
15111            // dependencies, ensure that its adjustment is at least
15112            // FOREGROUND_APP_ADJ.
15113            if (cpr.hasExternalProcessHandles()) {
15114                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15115                    adj = ProcessList.FOREGROUND_APP_ADJ;
15116                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15117                    app.cached = false;
15118                    app.keeping = true;
15119                    app.adjType = "provider";
15120                    app.adjTarget = cpr.name;
15121                }
15122                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15123                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15124                }
15125            }
15126        }
15127
15128        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15129            // A client of one of our services or providers is in the top state.  We
15130            // *may* want to be in the top state, but not if we are already running in
15131            // the background for some other reason.  For the decision here, we are going
15132            // to pick out a few specific states that we want to remain in when a client
15133            // is top (states that tend to be longer-term) and otherwise allow it to go
15134            // to the top state.
15135            switch (procState) {
15136                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15137                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15138                case ActivityManager.PROCESS_STATE_SERVICE:
15139                    // These all are longer-term states, so pull them up to the top
15140                    // of the background states, but not all the way to the top state.
15141                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15142                    break;
15143                default:
15144                    // Otherwise, top is a better choice, so take it.
15145                    procState = ActivityManager.PROCESS_STATE_TOP;
15146                    break;
15147            }
15148        }
15149
15150        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15151            if (app.hasClientActivities) {
15152                // This is a cached process, but with client activities.  Mark it so.
15153                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15154                app.adjType = "cch-client-act";
15155            } else if (app.treatLikeActivity) {
15156                // This is a cached process, but somebody wants us to treat it like it has
15157                // an activity, okay!
15158                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15159                app.adjType = "cch-as-act";
15160            }
15161        }
15162
15163        if (adj == ProcessList.SERVICE_ADJ) {
15164            if (doingAll) {
15165                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15166                mNewNumServiceProcs++;
15167                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15168                if (!app.serviceb) {
15169                    // This service isn't far enough down on the LRU list to
15170                    // normally be a B service, but if we are low on RAM and it
15171                    // is large we want to force it down since we would prefer to
15172                    // keep launcher over it.
15173                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15174                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15175                        app.serviceHighRam = true;
15176                        app.serviceb = true;
15177                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15178                    } else {
15179                        mNewNumAServiceProcs++;
15180                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15181                    }
15182                } else {
15183                    app.serviceHighRam = false;
15184                }
15185            }
15186            if (app.serviceb) {
15187                adj = ProcessList.SERVICE_B_ADJ;
15188            }
15189        }
15190
15191        app.curRawAdj = adj;
15192
15193        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15194        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15195        if (adj > app.maxAdj) {
15196            adj = app.maxAdj;
15197            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15198                schedGroup = Process.THREAD_GROUP_DEFAULT;
15199            }
15200        }
15201        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15202            app.keeping = true;
15203        }
15204
15205        // Do final modification to adj.  Everything we do between here and applying
15206        // the final setAdj must be done in this function, because we will also use
15207        // it when computing the final cached adj later.  Note that we don't need to
15208        // worry about this for max adj above, since max adj will always be used to
15209        // keep it out of the cached vaues.
15210        adj = app.modifyRawOomAdj(adj);
15211
15212        app.curProcState = procState;
15213
15214        int importance = app.memImportance;
15215        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15216            app.curAdj = adj;
15217            app.curSchedGroup = schedGroup;
15218            if (!interesting) {
15219                // For this reporting, if there is not something explicitly
15220                // interesting in this process then we will push it to the
15221                // background importance.
15222                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15223            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15224                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15225            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15226                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15227            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15228                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15229            } else if (adj >= ProcessList.SERVICE_ADJ) {
15230                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15231            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15232                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15233            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15234                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15235            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15236                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15237            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15238                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15239            } else {
15240                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15241            }
15242        }
15243
15244        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15245        if (foregroundActivities != app.foregroundActivities) {
15246            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15247        }
15248        if (changes != 0) {
15249            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15250            app.memImportance = importance;
15251            app.foregroundActivities = foregroundActivities;
15252            int i = mPendingProcessChanges.size()-1;
15253            ProcessChangeItem item = null;
15254            while (i >= 0) {
15255                item = mPendingProcessChanges.get(i);
15256                if (item.pid == app.pid) {
15257                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15258                    break;
15259                }
15260                i--;
15261            }
15262            if (i < 0) {
15263                // No existing item in pending changes; need a new one.
15264                final int NA = mAvailProcessChanges.size();
15265                if (NA > 0) {
15266                    item = mAvailProcessChanges.remove(NA-1);
15267                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15268                } else {
15269                    item = new ProcessChangeItem();
15270                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15271                }
15272                item.changes = 0;
15273                item.pid = app.pid;
15274                item.uid = app.info.uid;
15275                if (mPendingProcessChanges.size() == 0) {
15276                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15277                            "*** Enqueueing dispatch processes changed!");
15278                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15279                }
15280                mPendingProcessChanges.add(item);
15281            }
15282            item.changes |= changes;
15283            item.importance = importance;
15284            item.foregroundActivities = foregroundActivities;
15285            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15286                    + Integer.toHexString(System.identityHashCode(item))
15287                    + " " + app.toShortString() + ": changes=" + item.changes
15288                    + " importance=" + item.importance
15289                    + " foreground=" + item.foregroundActivities
15290                    + " type=" + app.adjType + " source=" + app.adjSource
15291                    + " target=" + app.adjTarget);
15292        }
15293
15294        return app.curRawAdj;
15295    }
15296
15297    /**
15298     * Schedule PSS collection of a process.
15299     */
15300    void requestPssLocked(ProcessRecord proc, int procState) {
15301        if (mPendingPssProcesses.contains(proc)) {
15302            return;
15303        }
15304        if (mPendingPssProcesses.size() == 0) {
15305            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15306        }
15307        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15308        proc.pssProcState = procState;
15309        mPendingPssProcesses.add(proc);
15310    }
15311
15312    /**
15313     * Schedule PSS collection of all processes.
15314     */
15315    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15316        if (!always) {
15317            if (now < (mLastFullPssTime +
15318                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15319                return;
15320            }
15321        }
15322        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15323        mLastFullPssTime = now;
15324        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15325        mPendingPssProcesses.clear();
15326        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15327            ProcessRecord app = mLruProcesses.get(i);
15328            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15329                app.pssProcState = app.setProcState;
15330                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15331                        mSleeping, now);
15332                mPendingPssProcesses.add(app);
15333            }
15334        }
15335        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15336    }
15337
15338    /**
15339     * Ask a given process to GC right now.
15340     */
15341    final void performAppGcLocked(ProcessRecord app) {
15342        try {
15343            app.lastRequestedGc = SystemClock.uptimeMillis();
15344            if (app.thread != null) {
15345                if (app.reportLowMemory) {
15346                    app.reportLowMemory = false;
15347                    app.thread.scheduleLowMemory();
15348                } else {
15349                    app.thread.processInBackground();
15350                }
15351            }
15352        } catch (Exception e) {
15353            // whatever.
15354        }
15355    }
15356
15357    /**
15358     * Returns true if things are idle enough to perform GCs.
15359     */
15360    private final boolean canGcNowLocked() {
15361        boolean processingBroadcasts = false;
15362        for (BroadcastQueue q : mBroadcastQueues) {
15363            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15364                processingBroadcasts = true;
15365            }
15366        }
15367        return !processingBroadcasts
15368                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15369    }
15370
15371    /**
15372     * Perform GCs on all processes that are waiting for it, but only
15373     * if things are idle.
15374     */
15375    final void performAppGcsLocked() {
15376        final int N = mProcessesToGc.size();
15377        if (N <= 0) {
15378            return;
15379        }
15380        if (canGcNowLocked()) {
15381            while (mProcessesToGc.size() > 0) {
15382                ProcessRecord proc = mProcessesToGc.remove(0);
15383                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15384                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15385                            <= SystemClock.uptimeMillis()) {
15386                        // To avoid spamming the system, we will GC processes one
15387                        // at a time, waiting a few seconds between each.
15388                        performAppGcLocked(proc);
15389                        scheduleAppGcsLocked();
15390                        return;
15391                    } else {
15392                        // It hasn't been long enough since we last GCed this
15393                        // process...  put it in the list to wait for its time.
15394                        addProcessToGcListLocked(proc);
15395                        break;
15396                    }
15397                }
15398            }
15399
15400            scheduleAppGcsLocked();
15401        }
15402    }
15403
15404    /**
15405     * If all looks good, perform GCs on all processes waiting for them.
15406     */
15407    final void performAppGcsIfAppropriateLocked() {
15408        if (canGcNowLocked()) {
15409            performAppGcsLocked();
15410            return;
15411        }
15412        // Still not idle, wait some more.
15413        scheduleAppGcsLocked();
15414    }
15415
15416    /**
15417     * Schedule the execution of all pending app GCs.
15418     */
15419    final void scheduleAppGcsLocked() {
15420        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15421
15422        if (mProcessesToGc.size() > 0) {
15423            // Schedule a GC for the time to the next process.
15424            ProcessRecord proc = mProcessesToGc.get(0);
15425            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15426
15427            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15428            long now = SystemClock.uptimeMillis();
15429            if (when < (now+GC_TIMEOUT)) {
15430                when = now + GC_TIMEOUT;
15431            }
15432            mHandler.sendMessageAtTime(msg, when);
15433        }
15434    }
15435
15436    /**
15437     * Add a process to the array of processes waiting to be GCed.  Keeps the
15438     * list in sorted order by the last GC time.  The process can't already be
15439     * on the list.
15440     */
15441    final void addProcessToGcListLocked(ProcessRecord proc) {
15442        boolean added = false;
15443        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15444            if (mProcessesToGc.get(i).lastRequestedGc <
15445                    proc.lastRequestedGc) {
15446                added = true;
15447                mProcessesToGc.add(i+1, proc);
15448                break;
15449            }
15450        }
15451        if (!added) {
15452            mProcessesToGc.add(0, proc);
15453        }
15454    }
15455
15456    /**
15457     * Set up to ask a process to GC itself.  This will either do it
15458     * immediately, or put it on the list of processes to gc the next
15459     * time things are idle.
15460     */
15461    final void scheduleAppGcLocked(ProcessRecord app) {
15462        long now = SystemClock.uptimeMillis();
15463        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15464            return;
15465        }
15466        if (!mProcessesToGc.contains(app)) {
15467            addProcessToGcListLocked(app);
15468            scheduleAppGcsLocked();
15469        }
15470    }
15471
15472    final void checkExcessivePowerUsageLocked(boolean doKills) {
15473        updateCpuStatsNow();
15474
15475        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15476        boolean doWakeKills = doKills;
15477        boolean doCpuKills = doKills;
15478        if (mLastPowerCheckRealtime == 0) {
15479            doWakeKills = false;
15480        }
15481        if (mLastPowerCheckUptime == 0) {
15482            doCpuKills = false;
15483        }
15484        if (stats.isScreenOn()) {
15485            doWakeKills = false;
15486        }
15487        final long curRealtime = SystemClock.elapsedRealtime();
15488        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15489        final long curUptime = SystemClock.uptimeMillis();
15490        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15491        mLastPowerCheckRealtime = curRealtime;
15492        mLastPowerCheckUptime = curUptime;
15493        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15494            doWakeKills = false;
15495        }
15496        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15497            doCpuKills = false;
15498        }
15499        int i = mLruProcesses.size();
15500        while (i > 0) {
15501            i--;
15502            ProcessRecord app = mLruProcesses.get(i);
15503            if (!app.keeping) {
15504                long wtime;
15505                synchronized (stats) {
15506                    wtime = stats.getProcessWakeTime(app.info.uid,
15507                            app.pid, curRealtime);
15508                }
15509                long wtimeUsed = wtime - app.lastWakeTime;
15510                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15511                if (DEBUG_POWER) {
15512                    StringBuilder sb = new StringBuilder(128);
15513                    sb.append("Wake for ");
15514                    app.toShortString(sb);
15515                    sb.append(": over ");
15516                    TimeUtils.formatDuration(realtimeSince, sb);
15517                    sb.append(" used ");
15518                    TimeUtils.formatDuration(wtimeUsed, sb);
15519                    sb.append(" (");
15520                    sb.append((wtimeUsed*100)/realtimeSince);
15521                    sb.append("%)");
15522                    Slog.i(TAG, sb.toString());
15523                    sb.setLength(0);
15524                    sb.append("CPU for ");
15525                    app.toShortString(sb);
15526                    sb.append(": over ");
15527                    TimeUtils.formatDuration(uptimeSince, sb);
15528                    sb.append(" used ");
15529                    TimeUtils.formatDuration(cputimeUsed, sb);
15530                    sb.append(" (");
15531                    sb.append((cputimeUsed*100)/uptimeSince);
15532                    sb.append("%)");
15533                    Slog.i(TAG, sb.toString());
15534                }
15535                // If a process has held a wake lock for more
15536                // than 50% of the time during this period,
15537                // that sounds bad.  Kill!
15538                if (doWakeKills && realtimeSince > 0
15539                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15540                    synchronized (stats) {
15541                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15542                                realtimeSince, wtimeUsed);
15543                    }
15544                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15545                            + " during " + realtimeSince);
15546                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15547                } else if (doCpuKills && uptimeSince > 0
15548                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15549                    synchronized (stats) {
15550                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15551                                uptimeSince, cputimeUsed);
15552                    }
15553                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15554                            + " during " + uptimeSince);
15555                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15556                } else {
15557                    app.lastWakeTime = wtime;
15558                    app.lastCpuTime = app.curCpuTime;
15559                }
15560            }
15561        }
15562    }
15563
15564    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15565            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15566        boolean success = true;
15567
15568        if (app.curRawAdj != app.setRawAdj) {
15569            if (wasKeeping && !app.keeping) {
15570                // This app is no longer something we want to keep.  Note
15571                // its current wake lock time to later know to kill it if
15572                // it is not behaving well.
15573                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15574                synchronized (stats) {
15575                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15576                            app.pid, SystemClock.elapsedRealtime());
15577                }
15578                app.lastCpuTime = app.curCpuTime;
15579            }
15580
15581            app.setRawAdj = app.curRawAdj;
15582        }
15583
15584        if (app.curAdj != app.setAdj) {
15585            ProcessList.setOomAdj(app.pid, app.curAdj);
15586            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15587                TAG, "Set " + app.pid + " " + app.processName +
15588                " adj " + app.curAdj + ": " + app.adjType);
15589            app.setAdj = app.curAdj;
15590        }
15591
15592        if (app.setSchedGroup != app.curSchedGroup) {
15593            app.setSchedGroup = app.curSchedGroup;
15594            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15595                    "Setting process group of " + app.processName
15596                    + " to " + app.curSchedGroup);
15597            if (app.waitingToKill != null &&
15598                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15599                killUnneededProcessLocked(app, app.waitingToKill);
15600                success = false;
15601            } else {
15602                if (true) {
15603                    long oldId = Binder.clearCallingIdentity();
15604                    try {
15605                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15606                    } catch (Exception e) {
15607                        Slog.w(TAG, "Failed setting process group of " + app.pid
15608                                + " to " + app.curSchedGroup);
15609                        e.printStackTrace();
15610                    } finally {
15611                        Binder.restoreCallingIdentity(oldId);
15612                    }
15613                } else {
15614                    if (app.thread != null) {
15615                        try {
15616                            app.thread.setSchedulingGroup(app.curSchedGroup);
15617                        } catch (RemoteException e) {
15618                        }
15619                    }
15620                }
15621                Process.setSwappiness(app.pid,
15622                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15623            }
15624        }
15625        if (app.repProcState != app.curProcState) {
15626            app.repProcState = app.curProcState;
15627            if (!reportingProcessState && app.thread != null) {
15628                try {
15629                    if (false) {
15630                        //RuntimeException h = new RuntimeException("here");
15631                        Slog.i(TAG, "Sending new process state " + app.repProcState
15632                                + " to " + app /*, h*/);
15633                    }
15634                    app.thread.setProcessState(app.repProcState);
15635                } catch (RemoteException e) {
15636                }
15637            }
15638        }
15639        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15640                app.setProcState)) {
15641            app.lastStateTime = now;
15642            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15643                    mSleeping, now);
15644            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15645                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15646                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15647                    + (app.nextPssTime-now) + ": " + app);
15648        } else {
15649            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15650                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15651                requestPssLocked(app, app.setProcState);
15652                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15653                        mSleeping, now);
15654            } else if (false && DEBUG_PSS) {
15655                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15656            }
15657        }
15658        if (app.setProcState != app.curProcState) {
15659            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15660                    "Proc state change of " + app.processName
15661                    + " to " + app.curProcState);
15662            app.setProcState = app.curProcState;
15663            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15664                app.notCachedSinceIdle = false;
15665            }
15666            if (!doingAll) {
15667                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15668            } else {
15669                app.procStateChanged = true;
15670            }
15671        }
15672        return success;
15673    }
15674
15675    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15676        if (proc.thread != null && proc.baseProcessTracker != null) {
15677            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15678        }
15679    }
15680
15681    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15682            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15683        if (app.thread == null) {
15684            return false;
15685        }
15686
15687        final boolean wasKeeping = app.keeping;
15688
15689        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15690
15691        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15692                reportingProcessState, now);
15693    }
15694
15695    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15696            boolean oomAdj) {
15697        if (isForeground != proc.foregroundServices) {
15698            proc.foregroundServices = isForeground;
15699            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15700                    proc.info.uid);
15701            if (isForeground) {
15702                if (curProcs == null) {
15703                    curProcs = new ArrayList<ProcessRecord>();
15704                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15705                }
15706                if (!curProcs.contains(proc)) {
15707                    curProcs.add(proc);
15708                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15709                            proc.info.packageName, proc.info.uid);
15710                }
15711            } else {
15712                if (curProcs != null) {
15713                    if (curProcs.remove(proc)) {
15714                        mBatteryStatsService.noteEvent(
15715                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15716                                proc.info.packageName, proc.info.uid);
15717                        if (curProcs.size() <= 0) {
15718                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15719                        }
15720                    }
15721                }
15722            }
15723            if (oomAdj) {
15724                updateOomAdjLocked();
15725            }
15726        }
15727    }
15728
15729    private final ActivityRecord resumedAppLocked() {
15730        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15731        String pkg;
15732        int uid;
15733        if (act != null && !act.sleeping) {
15734            pkg = act.packageName;
15735            uid = act.info.applicationInfo.uid;
15736        } else {
15737            pkg = null;
15738            uid = -1;
15739        }
15740        // Has the UID or resumed package name changed?
15741        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15742                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15743            if (mCurResumedPackage != null) {
15744                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15745                        mCurResumedPackage, mCurResumedUid);
15746            }
15747            mCurResumedPackage = pkg;
15748            mCurResumedUid = uid;
15749            if (mCurResumedPackage != null) {
15750                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15751                        mCurResumedPackage, mCurResumedUid);
15752            }
15753        }
15754        return act;
15755    }
15756
15757    final boolean updateOomAdjLocked(ProcessRecord app) {
15758        return updateOomAdjLocked(app, false);
15759    }
15760
15761    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15762        final ActivityRecord TOP_ACT = resumedAppLocked();
15763        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15764        final boolean wasCached = app.cached;
15765
15766        mAdjSeq++;
15767
15768        // This is the desired cached adjusment we want to tell it to use.
15769        // If our app is currently cached, we know it, and that is it.  Otherwise,
15770        // we don't know it yet, and it needs to now be cached we will then
15771        // need to do a complete oom adj.
15772        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15773                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15774        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15775                SystemClock.uptimeMillis());
15776        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15777            // Changed to/from cached state, so apps after it in the LRU
15778            // list may also be changed.
15779            updateOomAdjLocked();
15780        }
15781        return success;
15782    }
15783
15784    final void updateOomAdjLocked() {
15785        final ActivityRecord TOP_ACT = resumedAppLocked();
15786        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15787        final long now = SystemClock.uptimeMillis();
15788        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15789        final int N = mLruProcesses.size();
15790
15791        if (false) {
15792            RuntimeException e = new RuntimeException();
15793            e.fillInStackTrace();
15794            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15795        }
15796
15797        mAdjSeq++;
15798        mNewNumServiceProcs = 0;
15799        mNewNumAServiceProcs = 0;
15800
15801        final int emptyProcessLimit;
15802        final int cachedProcessLimit;
15803        if (mProcessLimit <= 0) {
15804            emptyProcessLimit = cachedProcessLimit = 0;
15805        } else if (mProcessLimit == 1) {
15806            emptyProcessLimit = 1;
15807            cachedProcessLimit = 0;
15808        } else {
15809            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15810            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15811        }
15812
15813        // Let's determine how many processes we have running vs.
15814        // how many slots we have for background processes; we may want
15815        // to put multiple processes in a slot of there are enough of
15816        // them.
15817        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15818                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15819        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15820        if (numEmptyProcs > cachedProcessLimit) {
15821            // If there are more empty processes than our limit on cached
15822            // processes, then use the cached process limit for the factor.
15823            // This ensures that the really old empty processes get pushed
15824            // down to the bottom, so if we are running low on memory we will
15825            // have a better chance at keeping around more cached processes
15826            // instead of a gazillion empty processes.
15827            numEmptyProcs = cachedProcessLimit;
15828        }
15829        int emptyFactor = numEmptyProcs/numSlots;
15830        if (emptyFactor < 1) emptyFactor = 1;
15831        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15832        if (cachedFactor < 1) cachedFactor = 1;
15833        int stepCached = 0;
15834        int stepEmpty = 0;
15835        int numCached = 0;
15836        int numEmpty = 0;
15837        int numTrimming = 0;
15838
15839        mNumNonCachedProcs = 0;
15840        mNumCachedHiddenProcs = 0;
15841
15842        // First update the OOM adjustment for each of the
15843        // application processes based on their current state.
15844        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15845        int nextCachedAdj = curCachedAdj+1;
15846        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15847        int nextEmptyAdj = curEmptyAdj+2;
15848        for (int i=N-1; i>=0; i--) {
15849            ProcessRecord app = mLruProcesses.get(i);
15850            if (!app.killedByAm && app.thread != null) {
15851                app.procStateChanged = false;
15852                final boolean wasKeeping = app.keeping;
15853                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15854
15855                // If we haven't yet assigned the final cached adj
15856                // to the process, do that now.
15857                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15858                    switch (app.curProcState) {
15859                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15860                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15861                            // This process is a cached process holding activities...
15862                            // assign it the next cached value for that type, and then
15863                            // step that cached level.
15864                            app.curRawAdj = curCachedAdj;
15865                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15866                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15867                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15868                                    + ")");
15869                            if (curCachedAdj != nextCachedAdj) {
15870                                stepCached++;
15871                                if (stepCached >= cachedFactor) {
15872                                    stepCached = 0;
15873                                    curCachedAdj = nextCachedAdj;
15874                                    nextCachedAdj += 2;
15875                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15876                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15877                                    }
15878                                }
15879                            }
15880                            break;
15881                        default:
15882                            // For everything else, assign next empty cached process
15883                            // level and bump that up.  Note that this means that
15884                            // long-running services that have dropped down to the
15885                            // cached level will be treated as empty (since their process
15886                            // state is still as a service), which is what we want.
15887                            app.curRawAdj = curEmptyAdj;
15888                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15889                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15890                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15891                                    + ")");
15892                            if (curEmptyAdj != nextEmptyAdj) {
15893                                stepEmpty++;
15894                                if (stepEmpty >= emptyFactor) {
15895                                    stepEmpty = 0;
15896                                    curEmptyAdj = nextEmptyAdj;
15897                                    nextEmptyAdj += 2;
15898                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15899                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15900                                    }
15901                                }
15902                            }
15903                            break;
15904                    }
15905                }
15906
15907                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15908
15909                // Count the number of process types.
15910                switch (app.curProcState) {
15911                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15912                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15913                        mNumCachedHiddenProcs++;
15914                        numCached++;
15915                        if (numCached > cachedProcessLimit) {
15916                            killUnneededProcessLocked(app, "cached #" + numCached);
15917                        }
15918                        break;
15919                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15920                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15921                                && app.lastActivityTime < oldTime) {
15922                            killUnneededProcessLocked(app, "empty for "
15923                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15924                                    / 1000) + "s");
15925                        } else {
15926                            numEmpty++;
15927                            if (numEmpty > emptyProcessLimit) {
15928                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15929                            }
15930                        }
15931                        break;
15932                    default:
15933                        mNumNonCachedProcs++;
15934                        break;
15935                }
15936
15937                if (app.isolated && app.services.size() <= 0) {
15938                    // If this is an isolated process, and there are no
15939                    // services running in it, then the process is no longer
15940                    // needed.  We agressively kill these because we can by
15941                    // definition not re-use the same process again, and it is
15942                    // good to avoid having whatever code was running in them
15943                    // left sitting around after no longer needed.
15944                    killUnneededProcessLocked(app, "isolated not needed");
15945                }
15946
15947                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15948                        && !app.killedByAm) {
15949                    numTrimming++;
15950                }
15951            }
15952        }
15953
15954        mNumServiceProcs = mNewNumServiceProcs;
15955
15956        // Now determine the memory trimming level of background processes.
15957        // Unfortunately we need to start at the back of the list to do this
15958        // properly.  We only do this if the number of background apps we
15959        // are managing to keep around is less than half the maximum we desire;
15960        // if we are keeping a good number around, we'll let them use whatever
15961        // memory they want.
15962        final int numCachedAndEmpty = numCached + numEmpty;
15963        int memFactor;
15964        if (numCached <= ProcessList.TRIM_CACHED_APPS
15965                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15966            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15967                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15968            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15969                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15970            } else {
15971                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15972            }
15973        } else {
15974            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15975        }
15976        // We always allow the memory level to go up (better).  We only allow it to go
15977        // down if we are in a state where that is allowed, *and* the total number of processes
15978        // has gone down since last time.
15979        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15980                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15981                + " last=" + mLastNumProcesses);
15982        if (memFactor > mLastMemoryLevel) {
15983            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15984                memFactor = mLastMemoryLevel;
15985                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15986            }
15987        }
15988        mLastMemoryLevel = memFactor;
15989        mLastNumProcesses = mLruProcesses.size();
15990        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15991        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15992        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15993            if (mLowRamStartTime == 0) {
15994                mLowRamStartTime = now;
15995            }
15996            int step = 0;
15997            int fgTrimLevel;
15998            switch (memFactor) {
15999                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16000                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16001                    break;
16002                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16003                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16004                    break;
16005                default:
16006                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16007                    break;
16008            }
16009            int factor = numTrimming/3;
16010            int minFactor = 2;
16011            if (mHomeProcess != null) minFactor++;
16012            if (mPreviousProcess != null) minFactor++;
16013            if (factor < minFactor) factor = minFactor;
16014            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16015            for (int i=N-1; i>=0; i--) {
16016                ProcessRecord app = mLruProcesses.get(i);
16017                if (allChanged || app.procStateChanged) {
16018                    setProcessTrackerState(app, trackerMemFactor, now);
16019                    app.procStateChanged = false;
16020                }
16021                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16022                        && !app.killedByAm) {
16023                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16024                        try {
16025                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16026                                    "Trimming memory of " + app.processName
16027                                    + " to " + curLevel);
16028                            app.thread.scheduleTrimMemory(curLevel);
16029                        } catch (RemoteException e) {
16030                        }
16031                        if (false) {
16032                            // For now we won't do this; our memory trimming seems
16033                            // to be good enough at this point that destroying
16034                            // activities causes more harm than good.
16035                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16036                                    && app != mHomeProcess && app != mPreviousProcess) {
16037                                // Need to do this on its own message because the stack may not
16038                                // be in a consistent state at this point.
16039                                // For these apps we will also finish their activities
16040                                // to help them free memory.
16041                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16042                            }
16043                        }
16044                    }
16045                    app.trimMemoryLevel = curLevel;
16046                    step++;
16047                    if (step >= factor) {
16048                        step = 0;
16049                        switch (curLevel) {
16050                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16051                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16052                                break;
16053                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16054                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16055                                break;
16056                        }
16057                    }
16058                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16059                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16060                            && app.thread != null) {
16061                        try {
16062                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16063                                    "Trimming memory of heavy-weight " + app.processName
16064                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16065                            app.thread.scheduleTrimMemory(
16066                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16067                        } catch (RemoteException e) {
16068                        }
16069                    }
16070                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16071                } else {
16072                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16073                            || app.systemNoUi) && app.pendingUiClean) {
16074                        // If this application is now in the background and it
16075                        // had done UI, then give it the special trim level to
16076                        // have it free UI resources.
16077                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16078                        if (app.trimMemoryLevel < level && app.thread != null) {
16079                            try {
16080                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16081                                        "Trimming memory of bg-ui " + app.processName
16082                                        + " to " + level);
16083                                app.thread.scheduleTrimMemory(level);
16084                            } catch (RemoteException e) {
16085                            }
16086                        }
16087                        app.pendingUiClean = false;
16088                    }
16089                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16090                        try {
16091                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16092                                    "Trimming memory of fg " + app.processName
16093                                    + " to " + fgTrimLevel);
16094                            app.thread.scheduleTrimMemory(fgTrimLevel);
16095                        } catch (RemoteException e) {
16096                        }
16097                    }
16098                    app.trimMemoryLevel = fgTrimLevel;
16099                }
16100            }
16101        } else {
16102            if (mLowRamStartTime != 0) {
16103                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16104                mLowRamStartTime = 0;
16105            }
16106            for (int i=N-1; i>=0; i--) {
16107                ProcessRecord app = mLruProcesses.get(i);
16108                if (allChanged || app.procStateChanged) {
16109                    setProcessTrackerState(app, trackerMemFactor, now);
16110                    app.procStateChanged = false;
16111                }
16112                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16113                        || app.systemNoUi) && app.pendingUiClean) {
16114                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16115                            && app.thread != null) {
16116                        try {
16117                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16118                                    "Trimming memory of ui hidden " + app.processName
16119                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16120                            app.thread.scheduleTrimMemory(
16121                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16122                        } catch (RemoteException e) {
16123                        }
16124                    }
16125                    app.pendingUiClean = false;
16126                }
16127                app.trimMemoryLevel = 0;
16128            }
16129        }
16130
16131        if (mAlwaysFinishActivities) {
16132            // Need to do this on its own message because the stack may not
16133            // be in a consistent state at this point.
16134            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16135        }
16136
16137        if (allChanged) {
16138            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16139        }
16140
16141        if (mProcessStats.shouldWriteNowLocked(now)) {
16142            mHandler.post(new Runnable() {
16143                @Override public void run() {
16144                    synchronized (ActivityManagerService.this) {
16145                        mProcessStats.writeStateAsyncLocked();
16146                    }
16147                }
16148            });
16149        }
16150
16151        if (DEBUG_OOM_ADJ) {
16152            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16153        }
16154    }
16155
16156    final void trimApplications() {
16157        synchronized (this) {
16158            int i;
16159
16160            // First remove any unused application processes whose package
16161            // has been removed.
16162            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16163                final ProcessRecord app = mRemovedProcesses.get(i);
16164                if (app.activities.size() == 0
16165                        && app.curReceiver == null && app.services.size() == 0) {
16166                    Slog.i(
16167                        TAG, "Exiting empty application process "
16168                        + app.processName + " ("
16169                        + (app.thread != null ? app.thread.asBinder() : null)
16170                        + ")\n");
16171                    if (app.pid > 0 && app.pid != MY_PID) {
16172                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16173                                app.processName, app.setAdj, "empty");
16174                        app.killedByAm = true;
16175                        Process.killProcessQuiet(app.pid);
16176                    } else {
16177                        try {
16178                            app.thread.scheduleExit();
16179                        } catch (Exception e) {
16180                            // Ignore exceptions.
16181                        }
16182                    }
16183                    cleanUpApplicationRecordLocked(app, false, true, -1);
16184                    mRemovedProcesses.remove(i);
16185
16186                    if (app.persistent) {
16187                        if (app.persistent) {
16188                            addAppLocked(app.info, false);
16189                        }
16190                    }
16191                }
16192            }
16193
16194            // Now update the oom adj for all processes.
16195            updateOomAdjLocked();
16196        }
16197    }
16198
16199    /** This method sends the specified signal to each of the persistent apps */
16200    public void signalPersistentProcesses(int sig) throws RemoteException {
16201        if (sig != Process.SIGNAL_USR1) {
16202            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16203        }
16204
16205        synchronized (this) {
16206            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16207                    != PackageManager.PERMISSION_GRANTED) {
16208                throw new SecurityException("Requires permission "
16209                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16210            }
16211
16212            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16213                ProcessRecord r = mLruProcesses.get(i);
16214                if (r.thread != null && r.persistent) {
16215                    Process.sendSignal(r.pid, sig);
16216                }
16217            }
16218        }
16219    }
16220
16221    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16222        if (proc == null || proc == mProfileProc) {
16223            proc = mProfileProc;
16224            path = mProfileFile;
16225            profileType = mProfileType;
16226            clearProfilerLocked();
16227        }
16228        if (proc == null) {
16229            return;
16230        }
16231        try {
16232            proc.thread.profilerControl(false, path, null, profileType);
16233        } catch (RemoteException e) {
16234            throw new IllegalStateException("Process disappeared");
16235        }
16236    }
16237
16238    private void clearProfilerLocked() {
16239        if (mProfileFd != null) {
16240            try {
16241                mProfileFd.close();
16242            } catch (IOException e) {
16243            }
16244        }
16245        mProfileApp = null;
16246        mProfileProc = null;
16247        mProfileFile = null;
16248        mProfileType = 0;
16249        mAutoStopProfiler = false;
16250    }
16251
16252    public boolean profileControl(String process, int userId, boolean start,
16253            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16254
16255        try {
16256            synchronized (this) {
16257                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16258                // its own permission.
16259                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16260                        != PackageManager.PERMISSION_GRANTED) {
16261                    throw new SecurityException("Requires permission "
16262                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16263                }
16264
16265                if (start && fd == null) {
16266                    throw new IllegalArgumentException("null fd");
16267                }
16268
16269                ProcessRecord proc = null;
16270                if (process != null) {
16271                    proc = findProcessLocked(process, userId, "profileControl");
16272                }
16273
16274                if (start && (proc == null || proc.thread == null)) {
16275                    throw new IllegalArgumentException("Unknown process: " + process);
16276                }
16277
16278                if (start) {
16279                    stopProfilerLocked(null, null, 0);
16280                    setProfileApp(proc.info, proc.processName, path, fd, false);
16281                    mProfileProc = proc;
16282                    mProfileType = profileType;
16283                    try {
16284                        fd = fd.dup();
16285                    } catch (IOException e) {
16286                        fd = null;
16287                    }
16288                    proc.thread.profilerControl(start, path, fd, profileType);
16289                    fd = null;
16290                    mProfileFd = null;
16291                } else {
16292                    stopProfilerLocked(proc, path, profileType);
16293                    if (fd != null) {
16294                        try {
16295                            fd.close();
16296                        } catch (IOException e) {
16297                        }
16298                    }
16299                }
16300
16301                return true;
16302            }
16303        } catch (RemoteException e) {
16304            throw new IllegalStateException("Process disappeared");
16305        } finally {
16306            if (fd != null) {
16307                try {
16308                    fd.close();
16309                } catch (IOException e) {
16310                }
16311            }
16312        }
16313    }
16314
16315    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16316        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16317                userId, true, true, callName, null);
16318        ProcessRecord proc = null;
16319        try {
16320            int pid = Integer.parseInt(process);
16321            synchronized (mPidsSelfLocked) {
16322                proc = mPidsSelfLocked.get(pid);
16323            }
16324        } catch (NumberFormatException e) {
16325        }
16326
16327        if (proc == null) {
16328            ArrayMap<String, SparseArray<ProcessRecord>> all
16329                    = mProcessNames.getMap();
16330            SparseArray<ProcessRecord> procs = all.get(process);
16331            if (procs != null && procs.size() > 0) {
16332                proc = procs.valueAt(0);
16333                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16334                    for (int i=1; i<procs.size(); i++) {
16335                        ProcessRecord thisProc = procs.valueAt(i);
16336                        if (thisProc.userId == userId) {
16337                            proc = thisProc;
16338                            break;
16339                        }
16340                    }
16341                }
16342            }
16343        }
16344
16345        return proc;
16346    }
16347
16348    public boolean dumpHeap(String process, int userId, boolean managed,
16349            String path, ParcelFileDescriptor fd) throws RemoteException {
16350
16351        try {
16352            synchronized (this) {
16353                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16354                // its own permission (same as profileControl).
16355                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16356                        != PackageManager.PERMISSION_GRANTED) {
16357                    throw new SecurityException("Requires permission "
16358                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16359                }
16360
16361                if (fd == null) {
16362                    throw new IllegalArgumentException("null fd");
16363                }
16364
16365                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16366                if (proc == null || proc.thread == null) {
16367                    throw new IllegalArgumentException("Unknown process: " + process);
16368                }
16369
16370                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16371                if (!isDebuggable) {
16372                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16373                        throw new SecurityException("Process not debuggable: " + proc);
16374                    }
16375                }
16376
16377                proc.thread.dumpHeap(managed, path, fd);
16378                fd = null;
16379                return true;
16380            }
16381        } catch (RemoteException e) {
16382            throw new IllegalStateException("Process disappeared");
16383        } finally {
16384            if (fd != null) {
16385                try {
16386                    fd.close();
16387                } catch (IOException e) {
16388                }
16389            }
16390        }
16391    }
16392
16393    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16394    public void monitor() {
16395        synchronized (this) { }
16396    }
16397
16398    void onCoreSettingsChange(Bundle settings) {
16399        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16400            ProcessRecord processRecord = mLruProcesses.get(i);
16401            try {
16402                if (processRecord.thread != null) {
16403                    processRecord.thread.setCoreSettings(settings);
16404                }
16405            } catch (RemoteException re) {
16406                /* ignore */
16407            }
16408        }
16409    }
16410
16411    // Multi-user methods
16412
16413    /**
16414     * Start user, if its not already running, but don't bring it to foreground.
16415     */
16416    @Override
16417    public boolean startUserInBackground(final int userId) {
16418        return startUser(userId, /* foreground */ false);
16419    }
16420
16421    /**
16422     * Refreshes the list of users related to the current user when either a
16423     * user switch happens or when a new related user is started in the
16424     * background.
16425     */
16426    private void updateCurrentProfileIdsLocked() {
16427        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16428                mCurrentUserId, false /* enabledOnly */);
16429        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16430        for (int i = 0; i < currentProfileIds.length; i++) {
16431            currentProfileIds[i] = profiles.get(i).id;
16432        }
16433        mCurrentProfileIds = currentProfileIds;
16434    }
16435
16436    private Set getProfileIdsLocked(int userId) {
16437        Set userIds = new HashSet<Integer>();
16438        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16439                userId, false /* enabledOnly */);
16440        for (UserInfo user : profiles) {
16441            userIds.add(Integer.valueOf(user.id));
16442        }
16443        return userIds;
16444    }
16445
16446    @Override
16447    public boolean switchUser(final int userId) {
16448        return startUser(userId, /* foregound */ true);
16449    }
16450
16451    private boolean startUser(final int userId, boolean foreground) {
16452        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16453                != PackageManager.PERMISSION_GRANTED) {
16454            String msg = "Permission Denial: switchUser() from pid="
16455                    + Binder.getCallingPid()
16456                    + ", uid=" + Binder.getCallingUid()
16457                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16458            Slog.w(TAG, msg);
16459            throw new SecurityException(msg);
16460        }
16461
16462        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16463
16464        final long ident = Binder.clearCallingIdentity();
16465        try {
16466            synchronized (this) {
16467                final int oldUserId = mCurrentUserId;
16468                if (oldUserId == userId) {
16469                    return true;
16470                }
16471
16472                mStackSupervisor.setLockTaskModeLocked(null);
16473
16474                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16475                if (userInfo == null) {
16476                    Slog.w(TAG, "No user info for user #" + userId);
16477                    return false;
16478                }
16479
16480                if (foreground) {
16481                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16482                            R.anim.screen_user_enter);
16483                }
16484
16485                boolean needStart = false;
16486
16487                // If the user we are switching to is not currently started, then
16488                // we need to start it now.
16489                if (mStartedUsers.get(userId) == null) {
16490                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16491                    updateStartedUserArrayLocked();
16492                    needStart = true;
16493                }
16494
16495                final Integer userIdInt = Integer.valueOf(userId);
16496                mUserLru.remove(userIdInt);
16497                mUserLru.add(userIdInt);
16498
16499                if (foreground) {
16500                    mCurrentUserId = userId;
16501                    updateCurrentProfileIdsLocked();
16502                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16503                    // Once the internal notion of the active user has switched, we lock the device
16504                    // with the option to show the user switcher on the keyguard.
16505                    mWindowManager.lockNow(null);
16506                } else {
16507                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16508                    updateCurrentProfileIdsLocked();
16509                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16510                    mUserLru.remove(currentUserIdInt);
16511                    mUserLru.add(currentUserIdInt);
16512                }
16513
16514                final UserStartedState uss = mStartedUsers.get(userId);
16515
16516                // Make sure user is in the started state.  If it is currently
16517                // stopping, we need to knock that off.
16518                if (uss.mState == UserStartedState.STATE_STOPPING) {
16519                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16520                    // so we can just fairly silently bring the user back from
16521                    // the almost-dead.
16522                    uss.mState = UserStartedState.STATE_RUNNING;
16523                    updateStartedUserArrayLocked();
16524                    needStart = true;
16525                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16526                    // This means ACTION_SHUTDOWN has been sent, so we will
16527                    // need to treat this as a new boot of the user.
16528                    uss.mState = UserStartedState.STATE_BOOTING;
16529                    updateStartedUserArrayLocked();
16530                    needStart = true;
16531                }
16532
16533                if (foreground) {
16534                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16535                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16536                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16537                            oldUserId, userId, uss));
16538                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16539                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16540                }
16541
16542                if (needStart) {
16543                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16544                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16545                            | Intent.FLAG_RECEIVER_FOREGROUND);
16546                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16547                    broadcastIntentLocked(null, null, intent,
16548                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16549                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16550                }
16551
16552                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16553                    if (userId != 0) {
16554                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16555                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16556                        broadcastIntentLocked(null, null, intent, null,
16557                                new IIntentReceiver.Stub() {
16558                                    public void performReceive(Intent intent, int resultCode,
16559                                            String data, Bundle extras, boolean ordered,
16560                                            boolean sticky, int sendingUser) {
16561                                        userInitialized(uss, userId);
16562                                    }
16563                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16564                                true, false, MY_PID, Process.SYSTEM_UID,
16565                                userId);
16566                        uss.initializing = true;
16567                    } else {
16568                        getUserManagerLocked().makeInitialized(userInfo.id);
16569                    }
16570                }
16571
16572                if (foreground) {
16573                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16574                    if (homeInFront) {
16575                        startHomeActivityLocked(userId);
16576                    } else {
16577                        mStackSupervisor.resumeTopActivitiesLocked();
16578                    }
16579                    EventLogTags.writeAmSwitchUser(userId);
16580                    getUserManagerLocked().userForeground(userId);
16581                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16582                }
16583
16584                if (needStart) {
16585                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16586                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16587                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16588                    broadcastIntentLocked(null, null, intent,
16589                            null, new IIntentReceiver.Stub() {
16590                                @Override
16591                                public void performReceive(Intent intent, int resultCode, String data,
16592                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16593                                        throws RemoteException {
16594                                }
16595                            }, 0, null, null,
16596                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16597                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16598                }
16599            }
16600        } finally {
16601            Binder.restoreCallingIdentity(ident);
16602        }
16603
16604        return true;
16605    }
16606
16607    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16608        long ident = Binder.clearCallingIdentity();
16609        try {
16610            Intent intent;
16611            if (oldUserId >= 0) {
16612                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16613                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16614                        | Intent.FLAG_RECEIVER_FOREGROUND);
16615                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16616                broadcastIntentLocked(null, null, intent,
16617                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16618                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16619            }
16620            if (newUserId >= 0) {
16621                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16622                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16623                        | Intent.FLAG_RECEIVER_FOREGROUND);
16624                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16625                broadcastIntentLocked(null, null, intent,
16626                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16627                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16628                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16629                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16630                        | Intent.FLAG_RECEIVER_FOREGROUND);
16631                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16632                broadcastIntentLocked(null, null, intent,
16633                        null, null, 0, null, null,
16634                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16635                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16636            }
16637        } finally {
16638            Binder.restoreCallingIdentity(ident);
16639        }
16640    }
16641
16642    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16643            final int newUserId) {
16644        final int N = mUserSwitchObservers.beginBroadcast();
16645        if (N > 0) {
16646            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16647                int mCount = 0;
16648                @Override
16649                public void sendResult(Bundle data) throws RemoteException {
16650                    synchronized (ActivityManagerService.this) {
16651                        if (mCurUserSwitchCallback == this) {
16652                            mCount++;
16653                            if (mCount == N) {
16654                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16655                            }
16656                        }
16657                    }
16658                }
16659            };
16660            synchronized (this) {
16661                uss.switching = true;
16662                mCurUserSwitchCallback = callback;
16663            }
16664            for (int i=0; i<N; i++) {
16665                try {
16666                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16667                            newUserId, callback);
16668                } catch (RemoteException e) {
16669                }
16670            }
16671        } else {
16672            synchronized (this) {
16673                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16674            }
16675        }
16676        mUserSwitchObservers.finishBroadcast();
16677    }
16678
16679    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16680        synchronized (this) {
16681            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16682            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16683        }
16684    }
16685
16686    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16687        mCurUserSwitchCallback = null;
16688        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16689        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16690                oldUserId, newUserId, uss));
16691    }
16692
16693    void userInitialized(UserStartedState uss, int newUserId) {
16694        completeSwitchAndInitalize(uss, newUserId, true, false);
16695    }
16696
16697    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16698        completeSwitchAndInitalize(uss, newUserId, false, true);
16699    }
16700
16701    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16702            boolean clearInitializing, boolean clearSwitching) {
16703        boolean unfrozen = false;
16704        synchronized (this) {
16705            if (clearInitializing) {
16706                uss.initializing = false;
16707                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16708            }
16709            if (clearSwitching) {
16710                uss.switching = false;
16711            }
16712            if (!uss.switching && !uss.initializing) {
16713                mWindowManager.stopFreezingScreen();
16714                unfrozen = true;
16715            }
16716        }
16717        if (unfrozen) {
16718            final int N = mUserSwitchObservers.beginBroadcast();
16719            for (int i=0; i<N; i++) {
16720                try {
16721                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16722                } catch (RemoteException e) {
16723                }
16724            }
16725            mUserSwitchObservers.finishBroadcast();
16726        }
16727    }
16728
16729    void scheduleStartProfilesLocked() {
16730        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16731            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16732                    DateUtils.SECOND_IN_MILLIS);
16733        }
16734    }
16735
16736    void startProfilesLocked() {
16737        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16738        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16739                mCurrentUserId, false /* enabledOnly */);
16740        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16741        for (UserInfo user : profiles) {
16742            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16743                    && user.id != mCurrentUserId) {
16744                toStart.add(user);
16745            }
16746        }
16747        final int n = toStart.size();
16748        int i = 0;
16749        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16750            startUserInBackground(toStart.get(i).id);
16751        }
16752        if (i < n) {
16753            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16754        }
16755    }
16756
16757    void finishUserSwitch(UserStartedState uss) {
16758        synchronized (this) {
16759            if (uss.mState == UserStartedState.STATE_BOOTING
16760                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16761                uss.mState = UserStartedState.STATE_RUNNING;
16762                final int userId = uss.mHandle.getIdentifier();
16763                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16764                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16765                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16766                broadcastIntentLocked(null, null, intent,
16767                        null, null, 0, null, null,
16768                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16769                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16770            }
16771
16772            startProfilesLocked();
16773
16774            int num = mUserLru.size();
16775            int i = 0;
16776            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16777                Integer oldUserId = mUserLru.get(i);
16778                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16779                if (oldUss == null) {
16780                    // Shouldn't happen, but be sane if it does.
16781                    mUserLru.remove(i);
16782                    num--;
16783                    continue;
16784                }
16785                if (oldUss.mState == UserStartedState.STATE_STOPPING
16786                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16787                    // This user is already stopping, doesn't count.
16788                    num--;
16789                    i++;
16790                    continue;
16791                }
16792                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16793                    // Owner and current can't be stopped, but count as running.
16794                    i++;
16795                    continue;
16796                }
16797                // This is a user to be stopped.
16798                stopUserLocked(oldUserId, null);
16799                num--;
16800                i++;
16801            }
16802        }
16803    }
16804
16805    @Override
16806    public int stopUser(final int userId, final IStopUserCallback callback) {
16807        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16808                != PackageManager.PERMISSION_GRANTED) {
16809            String msg = "Permission Denial: switchUser() from pid="
16810                    + Binder.getCallingPid()
16811                    + ", uid=" + Binder.getCallingUid()
16812                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16813            Slog.w(TAG, msg);
16814            throw new SecurityException(msg);
16815        }
16816        if (userId <= 0) {
16817            throw new IllegalArgumentException("Can't stop primary user " + userId);
16818        }
16819        synchronized (this) {
16820            return stopUserLocked(userId, callback);
16821        }
16822    }
16823
16824    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16825        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16826        if (mCurrentUserId == userId) {
16827            return ActivityManager.USER_OP_IS_CURRENT;
16828        }
16829
16830        final UserStartedState uss = mStartedUsers.get(userId);
16831        if (uss == null) {
16832            // User is not started, nothing to do...  but we do need to
16833            // callback if requested.
16834            if (callback != null) {
16835                mHandler.post(new Runnable() {
16836                    @Override
16837                    public void run() {
16838                        try {
16839                            callback.userStopped(userId);
16840                        } catch (RemoteException e) {
16841                        }
16842                    }
16843                });
16844            }
16845            return ActivityManager.USER_OP_SUCCESS;
16846        }
16847
16848        if (callback != null) {
16849            uss.mStopCallbacks.add(callback);
16850        }
16851
16852        if (uss.mState != UserStartedState.STATE_STOPPING
16853                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16854            uss.mState = UserStartedState.STATE_STOPPING;
16855            updateStartedUserArrayLocked();
16856
16857            long ident = Binder.clearCallingIdentity();
16858            try {
16859                // We are going to broadcast ACTION_USER_STOPPING and then
16860                // once that is done send a final ACTION_SHUTDOWN and then
16861                // stop the user.
16862                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16863                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16864                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16865                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16866                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16867                // This is the result receiver for the final shutdown broadcast.
16868                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16869                    @Override
16870                    public void performReceive(Intent intent, int resultCode, String data,
16871                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16872                        finishUserStop(uss);
16873                    }
16874                };
16875                // This is the result receiver for the initial stopping broadcast.
16876                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16877                    @Override
16878                    public void performReceive(Intent intent, int resultCode, String data,
16879                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16880                        // On to the next.
16881                        synchronized (ActivityManagerService.this) {
16882                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16883                                // Whoops, we are being started back up.  Abort, abort!
16884                                return;
16885                            }
16886                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16887                        }
16888                        broadcastIntentLocked(null, null, shutdownIntent,
16889                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16890                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16891                    }
16892                };
16893                // Kick things off.
16894                broadcastIntentLocked(null, null, stoppingIntent,
16895                        null, stoppingReceiver, 0, null, null,
16896                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16897                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16898            } finally {
16899                Binder.restoreCallingIdentity(ident);
16900            }
16901        }
16902
16903        return ActivityManager.USER_OP_SUCCESS;
16904    }
16905
16906    void finishUserStop(UserStartedState uss) {
16907        final int userId = uss.mHandle.getIdentifier();
16908        boolean stopped;
16909        ArrayList<IStopUserCallback> callbacks;
16910        synchronized (this) {
16911            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16912            if (mStartedUsers.get(userId) != uss) {
16913                stopped = false;
16914            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16915                stopped = false;
16916            } else {
16917                stopped = true;
16918                // User can no longer run.
16919                mStartedUsers.remove(userId);
16920                mUserLru.remove(Integer.valueOf(userId));
16921                updateStartedUserArrayLocked();
16922
16923                // Clean up all state and processes associated with the user.
16924                // Kill all the processes for the user.
16925                forceStopUserLocked(userId, "finish user");
16926            }
16927        }
16928
16929        for (int i=0; i<callbacks.size(); i++) {
16930            try {
16931                if (stopped) callbacks.get(i).userStopped(userId);
16932                else callbacks.get(i).userStopAborted(userId);
16933            } catch (RemoteException e) {
16934            }
16935        }
16936
16937        mStackSupervisor.removeUserLocked(userId);
16938    }
16939
16940    @Override
16941    public UserInfo getCurrentUser() {
16942        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16943                != PackageManager.PERMISSION_GRANTED) && (
16944                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16945                != PackageManager.PERMISSION_GRANTED)) {
16946            String msg = "Permission Denial: getCurrentUser() from pid="
16947                    + Binder.getCallingPid()
16948                    + ", uid=" + Binder.getCallingUid()
16949                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16950            Slog.w(TAG, msg);
16951            throw new SecurityException(msg);
16952        }
16953        synchronized (this) {
16954            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16955        }
16956    }
16957
16958    int getCurrentUserIdLocked() {
16959        return mCurrentUserId;
16960    }
16961
16962    @Override
16963    public boolean isUserRunning(int userId, boolean orStopped) {
16964        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16965                != PackageManager.PERMISSION_GRANTED) {
16966            String msg = "Permission Denial: isUserRunning() from pid="
16967                    + Binder.getCallingPid()
16968                    + ", uid=" + Binder.getCallingUid()
16969                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16970            Slog.w(TAG, msg);
16971            throw new SecurityException(msg);
16972        }
16973        synchronized (this) {
16974            return isUserRunningLocked(userId, orStopped);
16975        }
16976    }
16977
16978    boolean isUserRunningLocked(int userId, boolean orStopped) {
16979        UserStartedState state = mStartedUsers.get(userId);
16980        if (state == null) {
16981            return false;
16982        }
16983        if (orStopped) {
16984            return true;
16985        }
16986        return state.mState != UserStartedState.STATE_STOPPING
16987                && state.mState != UserStartedState.STATE_SHUTDOWN;
16988    }
16989
16990    @Override
16991    public int[] getRunningUserIds() {
16992        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16993                != PackageManager.PERMISSION_GRANTED) {
16994            String msg = "Permission Denial: isUserRunning() from pid="
16995                    + Binder.getCallingPid()
16996                    + ", uid=" + Binder.getCallingUid()
16997                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16998            Slog.w(TAG, msg);
16999            throw new SecurityException(msg);
17000        }
17001        synchronized (this) {
17002            return mStartedUserArray;
17003        }
17004    }
17005
17006    private void updateStartedUserArrayLocked() {
17007        int num = 0;
17008        for (int i=0; i<mStartedUsers.size();  i++) {
17009            UserStartedState uss = mStartedUsers.valueAt(i);
17010            // This list does not include stopping users.
17011            if (uss.mState != UserStartedState.STATE_STOPPING
17012                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17013                num++;
17014            }
17015        }
17016        mStartedUserArray = new int[num];
17017        num = 0;
17018        for (int i=0; i<mStartedUsers.size();  i++) {
17019            UserStartedState uss = mStartedUsers.valueAt(i);
17020            if (uss.mState != UserStartedState.STATE_STOPPING
17021                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17022                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17023                num++;
17024            }
17025        }
17026    }
17027
17028    @Override
17029    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17030        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17031                != PackageManager.PERMISSION_GRANTED) {
17032            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17033                    + Binder.getCallingPid()
17034                    + ", uid=" + Binder.getCallingUid()
17035                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17036            Slog.w(TAG, msg);
17037            throw new SecurityException(msg);
17038        }
17039
17040        mUserSwitchObservers.register(observer);
17041    }
17042
17043    @Override
17044    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17045        mUserSwitchObservers.unregister(observer);
17046    }
17047
17048    private boolean userExists(int userId) {
17049        if (userId == 0) {
17050            return true;
17051        }
17052        UserManagerService ums = getUserManagerLocked();
17053        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17054    }
17055
17056    int[] getUsersLocked() {
17057        UserManagerService ums = getUserManagerLocked();
17058        return ums != null ? ums.getUserIds() : new int[] { 0 };
17059    }
17060
17061    UserManagerService getUserManagerLocked() {
17062        if (mUserManager == null) {
17063            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17064            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17065        }
17066        return mUserManager;
17067    }
17068
17069    private int applyUserId(int uid, int userId) {
17070        return UserHandle.getUid(userId, uid);
17071    }
17072
17073    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17074        if (info == null) return null;
17075        ApplicationInfo newInfo = new ApplicationInfo(info);
17076        newInfo.uid = applyUserId(info.uid, userId);
17077        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17078                + info.packageName;
17079        return newInfo;
17080    }
17081
17082    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17083        if (aInfo == null
17084                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17085            return aInfo;
17086        }
17087
17088        ActivityInfo info = new ActivityInfo(aInfo);
17089        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17090        return info;
17091    }
17092
17093    private final class LocalService extends ActivityManagerInternal {
17094        @Override
17095        public void goingToSleep() {
17096            ActivityManagerService.this.goingToSleep();
17097        }
17098
17099        @Override
17100        public void wakingUp() {
17101            ActivityManagerService.this.wakingUp();
17102        }
17103    }
17104}
17105