ActivityManagerService.java revision 2a764949c943681a4d25a17a0b203a0127a4a486
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.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27
28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
29
30import android.app.AppOpsManager;
31import android.app.IActivityContainer;
32import android.app.IActivityContainerCallback;
33import android.appwidget.AppWidgetManager;
34import android.graphics.Rect;
35import android.os.BatteryStats;
36import android.util.ArrayMap;
37import com.android.internal.R;
38import com.android.internal.annotations.GuardedBy;
39import com.android.internal.app.IAppOpsService;
40import com.android.internal.app.ProcessMap;
41import com.android.internal.app.ProcessStats;
42import com.android.internal.os.BackgroundThread;
43import com.android.internal.os.BatteryStatsImpl;
44import com.android.internal.os.ProcessCpuTracker;
45import com.android.internal.os.TransferPipe;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.ServiceThread;
54import com.android.server.SystemService;
55import com.android.server.Watchdog;
56import com.android.server.am.ActivityStack.ActivityState;
57import com.android.server.firewall.IntentFirewall;
58import com.android.server.pm.UserManagerService;
59import com.android.server.wm.AppTransition;
60import com.android.server.wm.WindowManagerService;
61import com.google.android.collect.Lists;
62import com.google.android.collect.Maps;
63
64import dalvik.system.Zygote;
65
66import libcore.io.IoUtils;
67
68import org.xmlpull.v1.XmlPullParser;
69import org.xmlpull.v1.XmlPullParserException;
70import org.xmlpull.v1.XmlSerializer;
71
72import android.app.Activity;
73import android.app.ActivityManager;
74import android.app.ActivityManager.RunningTaskInfo;
75import android.app.ActivityManager.StackInfo;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*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, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    /**
344     * Description of a request to start a new activity, which has been held
345     * due to app switches being disabled.
346     */
347    static class PendingActivityLaunch {
348        final ActivityRecord r;
349        final ActivityRecord sourceRecord;
350        final int startFlags;
351        final ActivityStack stack;
352
353        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
354                int _startFlags, ActivityStack _stack) {
355            r = _r;
356            sourceRecord = _sourceRecord;
357            startFlags = _startFlags;
358            stack = _stack;
359        }
360    }
361
362    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
363            = new ArrayList<PendingActivityLaunch>();
364
365    BroadcastQueue mFgBroadcastQueue;
366    BroadcastQueue mBgBroadcastQueue;
367    // Convenient for easy iteration over the queues. Foreground is first
368    // so that dispatch of foreground broadcasts gets precedence.
369    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
370
371    BroadcastQueue broadcastQueueForIntent(Intent intent) {
372        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
373        if (DEBUG_BACKGROUND_BROADCAST) {
374            Slog.i(TAG, "Broadcast intent " + intent + " on "
375                    + (isFg ? "foreground" : "background")
376                    + " queue");
377        }
378        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
379    }
380
381    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
382        for (BroadcastQueue queue : mBroadcastQueues) {
383            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
384            if (r != null) {
385                return r;
386            }
387        }
388        return null;
389    }
390
391    /**
392     * Activity we have told the window manager to have key focus.
393     */
394    ActivityRecord mFocusedActivity = null;
395
396    /**
397     * List of intents that were used to start the most recent tasks.
398     */
399    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
400
401    public class PendingAssistExtras extends Binder implements Runnable {
402        public final ActivityRecord activity;
403        public boolean haveResult = false;
404        public Bundle result = null;
405        public PendingAssistExtras(ActivityRecord _activity) {
406            activity = _activity;
407        }
408        @Override
409        public void run() {
410            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
411            synchronized (this) {
412                haveResult = true;
413                notifyAll();
414            }
415        }
416    }
417
418    final ArrayList<PendingAssistExtras> mPendingAssistExtras
419            = new ArrayList<PendingAssistExtras>();
420
421    /**
422     * Process management.
423     */
424    final ProcessList mProcessList = new ProcessList();
425
426    /**
427     * All of the applications we currently have running organized by name.
428     * The keys are strings of the application package name (as
429     * returned by the package manager), and the keys are ApplicationRecord
430     * objects.
431     */
432    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
433
434    /**
435     * Tracking long-term execution of processes to look for abuse and other
436     * bad app behavior.
437     */
438    final ProcessStatsService mProcessStats;
439
440    /**
441     * The currently running isolated processes.
442     */
443    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
444
445    /**
446     * Counter for assigning isolated process uids, to avoid frequently reusing the
447     * same ones.
448     */
449    int mNextIsolatedProcessUid = 0;
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Information about a process that is currently marked as bad.
463     */
464    static final class BadProcessInfo {
465        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
466            this.time = time;
467            this.shortMsg = shortMsg;
468            this.longMsg = longMsg;
469            this.stack = stack;
470        }
471
472        final long time;
473        final String shortMsg;
474        final String longMsg;
475        final String stack;
476    }
477
478    /**
479     * Set of applications that we consider to be bad, and will reject
480     * incoming broadcasts from (which the user has no control over).
481     * Processes are added to this set when they have crashed twice within
482     * a minimum amount of time; they are removed from it when they are
483     * later restarted (hopefully due to some user action).  The value is the
484     * time it was added to the list.
485     */
486    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
487
488    /**
489     * All of the processes we currently have running organized by pid.
490     * The keys are the pid running the application.
491     *
492     * <p>NOTE: This object is protected by its own lock, NOT the global
493     * activity manager lock!
494     */
495    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
496
497    /**
498     * All of the processes that have been forced to be foreground.  The key
499     * is the pid of the caller who requested it (we hold a death
500     * link on it).
501     */
502    abstract class ForegroundToken implements IBinder.DeathRecipient {
503        int pid;
504        IBinder token;
505    }
506    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
507
508    /**
509     * List of records for processes that someone had tried to start before the
510     * system was ready.  We don't start them at that point, but ensure they
511     * are started by the time booting is complete.
512     */
513    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
520
521    /**
522     * Processes that are being forcibly torn down.
523     */
524    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     */
530    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Where in mLruProcesses that the processes hosting activities start.
534     */
535    int mLruProcessActivityStart = 0;
536
537    /**
538     * Where in mLruProcesses that the processes hosting services start.
539     * This is after (lower index) than mLruProcessesActivityStart.
540     */
541    int mLruProcessServiceStart = 0;
542
543    /**
544     * List of processes that should gc as soon as things are idle.
545     */
546    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
547
548    /**
549     * Processes we want to collect PSS data from.
550     */
551    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Last time we requested PSS data of all processes.
555     */
556    long mLastFullPssTime = SystemClock.uptimeMillis();
557
558    /**
559     * This is the process holding what we currently consider to be
560     * the "home" activity.
561     */
562    ProcessRecord mHomeProcess;
563
564    /**
565     * This is the process holding the activity the user last visited that
566     * is in a different process from the one they are currently in.
567     */
568    ProcessRecord mPreviousProcess;
569
570    /**
571     * The time at which the previous process was last visible.
572     */
573    long mPreviousProcessVisibleTime;
574
575    /**
576     * Which uses have been started, so are allowed to run code.
577     */
578    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
579
580    /**
581     * LRU list of history of current users.  Most recently current is at the end.
582     */
583    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
584
585    /**
586     * Constant array of the users that are currently started.
587     */
588    int[] mStartedUserArray = new int[] { 0 };
589
590    /**
591     * Registered observers of the user switching mechanics.
592     */
593    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
594            = new RemoteCallbackList<IUserSwitchObserver>();
595
596    /**
597     * Currently active user switch.
598     */
599    Object mCurUserSwitchCallback;
600
601    /**
602     * Packages that the user has asked to have run in screen size
603     * compatibility mode instead of filling the screen.
604     */
605    final CompatModePackages mCompatModePackages;
606
607    /**
608     * Set of IntentSenderRecord objects that are currently active.
609     */
610    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
611            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
612
613    /**
614     * Fingerprints (hashCode()) of stack traces that we've
615     * already logged DropBox entries for.  Guarded by itself.  If
616     * something (rogue user app) forces this over
617     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
618     */
619    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
620    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
621
622    /**
623     * Strict Mode background batched logging state.
624     *
625     * The string buffer is guarded by itself, and its lock is also
626     * used to determine if another batched write is already
627     * in-flight.
628     */
629    private final StringBuilder mStrictModeBuffer = new StringBuilder();
630
631    /**
632     * Keeps track of all IIntentReceivers that have been registered for
633     * broadcasts.  Hash keys are the receiver IBinder, hash value is
634     * a ReceiverList.
635     */
636    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
637            new HashMap<IBinder, ReceiverList>();
638
639    /**
640     * Resolver for broadcast intents to registered receivers.
641     * Holds BroadcastFilter (subclass of IntentFilter).
642     */
643    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
644            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
645        @Override
646        protected boolean allowFilterResult(
647                BroadcastFilter filter, List<BroadcastFilter> dest) {
648            IBinder target = filter.receiverList.receiver.asBinder();
649            for (int i=dest.size()-1; i>=0; i--) {
650                if (dest.get(i).receiverList.receiver.asBinder() == target) {
651                    return false;
652                }
653            }
654            return true;
655        }
656
657        @Override
658        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
659            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
660                    || userId == filter.owningUserId) {
661                return super.newResult(filter, match, userId);
662            }
663            return null;
664        }
665
666        @Override
667        protected BroadcastFilter[] newArray(int size) {
668            return new BroadcastFilter[size];
669        }
670
671        @Override
672        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
673            return packageName.equals(filter.packageName);
674        }
675    };
676
677    /**
678     * State of all active sticky broadcasts per user.  Keys are the action of the
679     * sticky Intent, values are an ArrayList of all broadcasted intents with
680     * that action (which should usually be one).  The SparseArray is keyed
681     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
682     * for stickies that are sent to all users.
683     */
684    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
685            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
686
687    final ActiveServices mServices;
688
689    /**
690     * Backup/restore process management
691     */
692    String mBackupAppName = null;
693    BackupRecord mBackupTarget = null;
694
695    /**
696     * List of PendingThumbnailsRecord objects of clients who are still
697     * waiting to receive all of the thumbnails for a task.
698     */
699    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
700            new ArrayList<PendingThumbnailsRecord>();
701
702    final ProviderMap mProviderMap;
703
704    /**
705     * List of content providers who have clients waiting for them.  The
706     * application is currently being launched and the provider will be
707     * removed from this list once it is published.
708     */
709    final ArrayList<ContentProviderRecord> mLaunchingProviders
710            = new ArrayList<ContentProviderRecord>();
711
712    /**
713     * File storing persisted {@link #mGrantedUriPermissions}.
714     */
715    private final AtomicFile mGrantFile;
716
717    /** XML constants used in {@link #mGrantFile} */
718    private static final String TAG_URI_GRANTS = "uri-grants";
719    private static final String TAG_URI_GRANT = "uri-grant";
720    private static final String ATTR_USER_HANDLE = "userHandle";
721    private static final String ATTR_SOURCE_PKG = "sourcePkg";
722    private static final String ATTR_TARGET_PKG = "targetPkg";
723    private static final String ATTR_URI = "uri";
724    private static final String ATTR_MODE_FLAGS = "modeFlags";
725    private static final String ATTR_CREATED_TIME = "createdTime";
726
727    /**
728     * Global set of specific {@link Uri} permissions that have been granted.
729     * This optimized lookup structure maps from {@link UriPermission#targetUid}
730     * to {@link UriPermission#uri} to {@link UriPermission}.
731     */
732    @GuardedBy("this")
733    private final SparseArray<ArrayMap<Uri, UriPermission>>
734            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
735
736    CoreSettingsObserver mCoreSettingsObserver;
737
738    /**
739     * Thread-local storage used to carry caller permissions over through
740     * indirect content-provider access.
741     */
742    private class Identity {
743        public int pid;
744        public int uid;
745
746        Identity(int _pid, int _uid) {
747            pid = _pid;
748            uid = _uid;
749        }
750    }
751
752    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
753
754    /**
755     * All information we have collected about the runtime performance of
756     * any user id that can impact battery performance.
757     */
758    final BatteryStatsService mBatteryStatsService;
759
760    /**
761     * Information about component usage
762     */
763    final UsageStatsService mUsageStatsService;
764
765    /**
766     * Information about and control over application operations
767     */
768    final AppOpsService mAppOpsService;
769
770    /**
771     * Current configuration information.  HistoryRecord objects are given
772     * a reference to this object to indicate which configuration they are
773     * currently running in, so this object must be kept immutable.
774     */
775    Configuration mConfiguration = new Configuration();
776
777    /**
778     * Current sequencing integer of the configuration, for skipping old
779     * configurations.
780     */
781    int mConfigurationSeq = 0;
782
783    /**
784     * Hardware-reported OpenGLES version.
785     */
786    final int GL_ES_VERSION;
787
788    /**
789     * List of initialization arguments to pass to all processes when binding applications to them.
790     * For example, references to the commonly used services.
791     */
792    HashMap<String, IBinder> mAppBindArgs;
793
794    /**
795     * Temporary to avoid allocations.  Protected by main lock.
796     */
797    final StringBuilder mStringBuilder = new StringBuilder(256);
798
799    /**
800     * Used to control how we initialize the service.
801     */
802    boolean mStartRunning = false;
803    ComponentName mTopComponent;
804    String mTopAction;
805    String mTopData;
806    boolean mProcessesReady = false;
807    boolean mSystemReady = false;
808    boolean mBooting = false;
809    boolean mWaitingUpdate = false;
810    boolean mDidUpdate = false;
811    boolean mOnBattery = false;
812    boolean mLaunchWarningShown = false;
813
814    Context mContext;
815
816    int mFactoryTest;
817
818    boolean mCheckedForSetup;
819
820    /**
821     * The time at which we will allow normal application switches again,
822     * after a call to {@link #stopAppSwitches()}.
823     */
824    long mAppSwitchesAllowedTime;
825
826    /**
827     * This is set to true after the first switch after mAppSwitchesAllowedTime
828     * is set; any switches after that will clear the time.
829     */
830    boolean mDidAppSwitch;
831
832    /**
833     * Last time (in realtime) at which we checked for power usage.
834     */
835    long mLastPowerCheckRealtime;
836
837    /**
838     * Last time (in uptime) at which we checked for power usage.
839     */
840    long mLastPowerCheckUptime;
841
842    /**
843     * Set while we are wanting to sleep, to prevent any
844     * activities from being started/resumed.
845     */
846    boolean mSleeping = false;
847
848    /**
849     * State of external calls telling us if the device is asleep.
850     */
851    boolean mWentToSleep = false;
852
853    /**
854     * State of external call telling us if the lock screen is shown.
855     */
856    boolean mLockScreenShown = false;
857
858    /**
859     * Set if we are shutting down the system, similar to sleeping.
860     */
861    boolean mShuttingDown = false;
862
863    /**
864     * Current sequence id for oom_adj computation traversal.
865     */
866    int mAdjSeq = 0;
867
868    /**
869     * Current sequence id for process LRU updating.
870     */
871    int mLruSeq = 0;
872
873    /**
874     * Keep track of the non-cached/empty process we last found, to help
875     * determine how to distribute cached/empty processes next time.
876     */
877    int mNumNonCachedProcs = 0;
878
879    /**
880     * Keep track of the number of cached hidden procs, to balance oom adj
881     * distribution between those and empty procs.
882     */
883    int mNumCachedHiddenProcs = 0;
884
885    /**
886     * Keep track of the number of service processes we last found, to
887     * determine on the next iteration which should be B services.
888     */
889    int mNumServiceProcs = 0;
890    int mNewNumAServiceProcs = 0;
891    int mNewNumServiceProcs = 0;
892
893    /**
894     * Allow the current computed overall memory level of the system to go down?
895     * This is set to false when we are killing processes for reasons other than
896     * memory management, so that the now smaller process list will not be taken as
897     * an indication that memory is tighter.
898     */
899    boolean mAllowLowerMemLevel = false;
900
901    /**
902     * The last computed memory level, for holding when we are in a state that
903     * processes are going away for other reasons.
904     */
905    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
906
907    /**
908     * The last total number of process we have, to determine if changes actually look
909     * like a shrinking number of process due to lower RAM.
910     */
911    int mLastNumProcesses;
912
913    /**
914     * The uptime of the last time we performed idle maintenance.
915     */
916    long mLastIdleTime = SystemClock.uptimeMillis();
917
918    /**
919     * Total time spent with RAM that has been added in the past since the last idle time.
920     */
921    long mLowRamTimeSinceLastIdle = 0;
922
923    /**
924     * If RAM is currently low, when that horrible situation started.
925     */
926    long mLowRamStartTime = 0;
927
928    /**
929     * For reporting to battery stats the current top application.
930     */
931    private String mCurResumedPackage = null;
932    private int mCurResumedUid = -1;
933
934    /**
935     * For reporting to battery stats the apps currently running foreground
936     * service.  The ProcessMap is package/uid tuples; each of these contain
937     * an array of the currently foreground processes.
938     */
939    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
940            = new ProcessMap<ArrayList<ProcessRecord>>();
941
942    /**
943     * This is set if we had to do a delayed dexopt of an app before launching
944     * it, to increasing the ANR timeouts in that case.
945     */
946    boolean mDidDexOpt;
947
948    /**
949     * Set if the systemServer made a call to enterSafeMode.
950     */
951    boolean mSafeMode;
952
953    String mDebugApp = null;
954    boolean mWaitForDebugger = false;
955    boolean mDebugTransient = false;
956    String mOrigDebugApp = null;
957    boolean mOrigWaitForDebugger = false;
958    boolean mAlwaysFinishActivities = false;
959    IActivityController mController = null;
960    String mProfileApp = null;
961    ProcessRecord mProfileProc = null;
962    String mProfileFile;
963    ParcelFileDescriptor mProfileFd;
964    int mProfileType = 0;
965    boolean mAutoStopProfiler = false;
966    String mOpenGlTraceApp = null;
967
968    static class ProcessChangeItem {
969        static final int CHANGE_ACTIVITIES = 1<<0;
970        static final int CHANGE_IMPORTANCE= 1<<1;
971        int changes;
972        int uid;
973        int pid;
974        int importance;
975        boolean foregroundActivities;
976    }
977
978    final RemoteCallbackList<IProcessObserver> mProcessObservers
979            = new RemoteCallbackList<IProcessObserver>();
980    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
981
982    final ArrayList<ProcessChangeItem> mPendingProcessChanges
983            = new ArrayList<ProcessChangeItem>();
984    final ArrayList<ProcessChangeItem> mAvailProcessChanges
985            = new ArrayList<ProcessChangeItem>();
986
987    /**
988     * Runtime CPU use collection thread.  This object's lock is used to
989     * protect all related state.
990     */
991    final Thread mProcessCpuThread;
992
993    /**
994     * Used to collect process stats when showing not responding dialog.
995     * Protected by mProcessCpuThread.
996     */
997    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
998            MONITOR_THREAD_CPU_USAGE);
999    final AtomicLong mLastCpuTime = new AtomicLong(0);
1000    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1001
1002    long mLastWriteTime = 0;
1003
1004    /**
1005     * Used to retain an update lock when the foreground activity is in
1006     * immersive mode.
1007     */
1008    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1009
1010    /**
1011     * Set to true after the system has finished booting.
1012     */
1013    boolean mBooted = false;
1014
1015    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1016    int mProcessLimitOverride = -1;
1017
1018    WindowManagerService mWindowManager;
1019
1020    final ActivityThread mSystemThread;
1021
1022    int mCurrentUserId = 0;
1023    int[] mCurrentProfileIds = new int[0]; // Accessed by ActivityStack
1024    private UserManagerService mUserManager;
1025
1026    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1027        final ProcessRecord mApp;
1028        final int mPid;
1029        final IApplicationThread mAppThread;
1030
1031        AppDeathRecipient(ProcessRecord app, int pid,
1032                IApplicationThread thread) {
1033            if (localLOGV) Slog.v(
1034                TAG, "New death recipient " + this
1035                + " for thread " + thread.asBinder());
1036            mApp = app;
1037            mPid = pid;
1038            mAppThread = thread;
1039        }
1040
1041        @Override
1042        public void binderDied() {
1043            if (localLOGV) Slog.v(
1044                TAG, "Death received in " + this
1045                + " for thread " + mAppThread.asBinder());
1046            synchronized(ActivityManagerService.this) {
1047                appDiedLocked(mApp, mPid, mAppThread);
1048            }
1049        }
1050    }
1051
1052    static final int SHOW_ERROR_MSG = 1;
1053    static final int SHOW_NOT_RESPONDING_MSG = 2;
1054    static final int SHOW_FACTORY_ERROR_MSG = 3;
1055    static final int UPDATE_CONFIGURATION_MSG = 4;
1056    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1057    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1058    static final int SERVICE_TIMEOUT_MSG = 12;
1059    static final int UPDATE_TIME_ZONE = 13;
1060    static final int SHOW_UID_ERROR_MSG = 14;
1061    static final int IM_FEELING_LUCKY_MSG = 15;
1062    static final int PROC_START_TIMEOUT_MSG = 20;
1063    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1064    static final int KILL_APPLICATION_MSG = 22;
1065    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1066    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1067    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1068    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1069    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1070    static final int CLEAR_DNS_CACHE_MSG = 28;
1071    static final int UPDATE_HTTP_PROXY_MSG = 29;
1072    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1073    static final int DISPATCH_PROCESSES_CHANGED = 31;
1074    static final int DISPATCH_PROCESS_DIED = 32;
1075    static final int REPORT_MEM_USAGE_MSG = 33;
1076    static final int REPORT_USER_SWITCH_MSG = 34;
1077    static final int CONTINUE_USER_SWITCH_MSG = 35;
1078    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1079    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1080    static final int PERSIST_URI_GRANTS_MSG = 38;
1081    static final int REQUEST_ALL_PSS_MSG = 39;
1082    static final int START_PROFILES_MSG = 40;
1083    static final int UPDATE_TIME = 41;
1084
1085    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1086    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1087    static final int FIRST_COMPAT_MODE_MSG = 300;
1088    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1089
1090    AlertDialog mUidAlert;
1091    CompatModeDialog mCompatModeDialog;
1092    long mLastMemUsageReportTime = 0;
1093
1094    /**
1095     * Flag whether the current user is a "monkey", i.e. whether
1096     * the UI is driven by a UI automation tool.
1097     */
1098    private boolean mUserIsMonkey;
1099
1100    final ServiceThread mHandlerThread;
1101    final MainHandler mHandler;
1102
1103    final class MainHandler extends Handler {
1104        public MainHandler(Looper looper) {
1105            super(looper, null, true);
1106        }
1107
1108        @Override
1109        public void handleMessage(Message msg) {
1110            switch (msg.what) {
1111            case SHOW_ERROR_MSG: {
1112                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1113                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1114                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1115                synchronized (ActivityManagerService.this) {
1116                    ProcessRecord proc = (ProcessRecord)data.get("app");
1117                    AppErrorResult res = (AppErrorResult) data.get("result");
1118                    if (proc != null && proc.crashDialog != null) {
1119                        Slog.e(TAG, "App already has crash dialog: " + proc);
1120                        if (res != null) {
1121                            res.set(0);
1122                        }
1123                        return;
1124                    }
1125                    if (!showBackground && UserHandle.getAppId(proc.uid)
1126                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1127                            && proc.pid != MY_PID) {
1128                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1129                        if (res != null) {
1130                            res.set(0);
1131                        }
1132                        return;
1133                    }
1134                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1135                        Dialog d = new AppErrorDialog(mContext,
1136                                ActivityManagerService.this, res, proc);
1137                        d.show();
1138                        proc.crashDialog = d;
1139                    } else {
1140                        // The device is asleep, so just pretend that the user
1141                        // saw a crash dialog and hit "force quit".
1142                        if (res != null) {
1143                            res.set(0);
1144                        }
1145                    }
1146                }
1147
1148                ensureBootCompleted();
1149            } break;
1150            case SHOW_NOT_RESPONDING_MSG: {
1151                synchronized (ActivityManagerService.this) {
1152                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1153                    ProcessRecord proc = (ProcessRecord)data.get("app");
1154                    if (proc != null && proc.anrDialog != null) {
1155                        Slog.e(TAG, "App already has anr dialog: " + proc);
1156                        return;
1157                    }
1158
1159                    Intent intent = new Intent("android.intent.action.ANR");
1160                    if (!mProcessesReady) {
1161                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1162                                | Intent.FLAG_RECEIVER_FOREGROUND);
1163                    }
1164                    broadcastIntentLocked(null, null, intent,
1165                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1166                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1167
1168                    if (mShowDialogs) {
1169                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1170                                mContext, proc, (ActivityRecord)data.get("activity"),
1171                                msg.arg1 != 0);
1172                        d.show();
1173                        proc.anrDialog = d;
1174                    } else {
1175                        // Just kill the app if there is no dialog to be shown.
1176                        killAppAtUsersRequest(proc, null);
1177                    }
1178                }
1179
1180                ensureBootCompleted();
1181            } break;
1182            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1183                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1184                synchronized (ActivityManagerService.this) {
1185                    ProcessRecord proc = (ProcessRecord) data.get("app");
1186                    if (proc == null) {
1187                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1188                        break;
1189                    }
1190                    if (proc.crashDialog != null) {
1191                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1192                        return;
1193                    }
1194                    AppErrorResult res = (AppErrorResult) data.get("result");
1195                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1196                        Dialog d = new StrictModeViolationDialog(mContext,
1197                                ActivityManagerService.this, res, proc);
1198                        d.show();
1199                        proc.crashDialog = d;
1200                    } else {
1201                        // The device is asleep, so just pretend that the user
1202                        // saw a crash dialog and hit "force quit".
1203                        res.set(0);
1204                    }
1205                }
1206                ensureBootCompleted();
1207            } break;
1208            case SHOW_FACTORY_ERROR_MSG: {
1209                Dialog d = new FactoryErrorDialog(
1210                    mContext, msg.getData().getCharSequence("msg"));
1211                d.show();
1212                ensureBootCompleted();
1213            } break;
1214            case UPDATE_CONFIGURATION_MSG: {
1215                final ContentResolver resolver = mContext.getContentResolver();
1216                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1217            } break;
1218            case GC_BACKGROUND_PROCESSES_MSG: {
1219                synchronized (ActivityManagerService.this) {
1220                    performAppGcsIfAppropriateLocked();
1221                }
1222            } break;
1223            case WAIT_FOR_DEBUGGER_MSG: {
1224                synchronized (ActivityManagerService.this) {
1225                    ProcessRecord app = (ProcessRecord)msg.obj;
1226                    if (msg.arg1 != 0) {
1227                        if (!app.waitedForDebugger) {
1228                            Dialog d = new AppWaitingForDebuggerDialog(
1229                                    ActivityManagerService.this,
1230                                    mContext, app);
1231                            app.waitDialog = d;
1232                            app.waitedForDebugger = true;
1233                            d.show();
1234                        }
1235                    } else {
1236                        if (app.waitDialog != null) {
1237                            app.waitDialog.dismiss();
1238                            app.waitDialog = null;
1239                        }
1240                    }
1241                }
1242            } break;
1243            case SERVICE_TIMEOUT_MSG: {
1244                if (mDidDexOpt) {
1245                    mDidDexOpt = false;
1246                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1247                    nmsg.obj = msg.obj;
1248                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1249                    return;
1250                }
1251                mServices.serviceTimeout((ProcessRecord)msg.obj);
1252            } break;
1253            case UPDATE_TIME_ZONE: {
1254                synchronized (ActivityManagerService.this) {
1255                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1256                        ProcessRecord r = mLruProcesses.get(i);
1257                        if (r.thread != null) {
1258                            try {
1259                                r.thread.updateTimeZone();
1260                            } catch (RemoteException ex) {
1261                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1262                            }
1263                        }
1264                    }
1265                }
1266            } break;
1267            case CLEAR_DNS_CACHE_MSG: {
1268                synchronized (ActivityManagerService.this) {
1269                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1270                        ProcessRecord r = mLruProcesses.get(i);
1271                        if (r.thread != null) {
1272                            try {
1273                                r.thread.clearDnsCache();
1274                            } catch (RemoteException ex) {
1275                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1276                            }
1277                        }
1278                    }
1279                }
1280            } break;
1281            case UPDATE_HTTP_PROXY_MSG: {
1282                ProxyProperties proxy = (ProxyProperties)msg.obj;
1283                String host = "";
1284                String port = "";
1285                String exclList = "";
1286                String pacFileUrl = null;
1287                if (proxy != null) {
1288                    host = proxy.getHost();
1289                    port = Integer.toString(proxy.getPort());
1290                    exclList = proxy.getExclusionList();
1291                    pacFileUrl = proxy.getPacFileUrl();
1292                }
1293                synchronized (ActivityManagerService.this) {
1294                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1295                        ProcessRecord r = mLruProcesses.get(i);
1296                        if (r.thread != null) {
1297                            try {
1298                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1299                            } catch (RemoteException ex) {
1300                                Slog.w(TAG, "Failed to update http proxy for: " +
1301                                        r.info.processName);
1302                            }
1303                        }
1304                    }
1305                }
1306            } break;
1307            case SHOW_UID_ERROR_MSG: {
1308                String title = "System UIDs Inconsistent";
1309                String text = "UIDs on the system are inconsistent, you need to wipe your"
1310                        + " data partition or your device will be unstable.";
1311                Log.e(TAG, title + ": " + text);
1312                if (mShowDialogs) {
1313                    // XXX This is a temporary dialog, no need to localize.
1314                    AlertDialog d = new BaseErrorDialog(mContext);
1315                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1316                    d.setCancelable(false);
1317                    d.setTitle(title);
1318                    d.setMessage(text);
1319                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1320                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1321                    mUidAlert = d;
1322                    d.show();
1323                }
1324            } break;
1325            case IM_FEELING_LUCKY_MSG: {
1326                if (mUidAlert != null) {
1327                    mUidAlert.dismiss();
1328                    mUidAlert = null;
1329                }
1330            } break;
1331            case PROC_START_TIMEOUT_MSG: {
1332                if (mDidDexOpt) {
1333                    mDidDexOpt = false;
1334                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1335                    nmsg.obj = msg.obj;
1336                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1337                    return;
1338                }
1339                ProcessRecord app = (ProcessRecord)msg.obj;
1340                synchronized (ActivityManagerService.this) {
1341                    processStartTimedOutLocked(app);
1342                }
1343            } break;
1344            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    doPendingActivityLaunchesLocked(true);
1347                }
1348            } break;
1349            case KILL_APPLICATION_MSG: {
1350                synchronized (ActivityManagerService.this) {
1351                    int appid = msg.arg1;
1352                    boolean restart = (msg.arg2 == 1);
1353                    Bundle bundle = (Bundle)msg.obj;
1354                    String pkg = bundle.getString("pkg");
1355                    String reason = bundle.getString("reason");
1356                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1357                            false, UserHandle.USER_ALL, reason);
1358                }
1359            } break;
1360            case FINALIZE_PENDING_INTENT_MSG: {
1361                ((PendingIntentRecord)msg.obj).completeFinalize();
1362            } break;
1363            case POST_HEAVY_NOTIFICATION_MSG: {
1364                INotificationManager inm = NotificationManager.getService();
1365                if (inm == null) {
1366                    return;
1367                }
1368
1369                ActivityRecord root = (ActivityRecord)msg.obj;
1370                ProcessRecord process = root.app;
1371                if (process == null) {
1372                    return;
1373                }
1374
1375                try {
1376                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1377                    String text = mContext.getString(R.string.heavy_weight_notification,
1378                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1379                    Notification notification = new Notification();
1380                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1381                    notification.when = 0;
1382                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1383                    notification.tickerText = text;
1384                    notification.defaults = 0; // please be quiet
1385                    notification.sound = null;
1386                    notification.vibrate = null;
1387                    notification.setLatestEventInfo(context, text,
1388                            mContext.getText(R.string.heavy_weight_notification_detail),
1389                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1390                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1391                                    new UserHandle(root.userId)));
1392
1393                    try {
1394                        int[] outId = new int[1];
1395                        inm.enqueueNotificationWithTag("android", "android", null,
1396                                R.string.heavy_weight_notification,
1397                                notification, outId, root.userId);
1398                    } catch (RuntimeException e) {
1399                        Slog.w(ActivityManagerService.TAG,
1400                                "Error showing notification for heavy-weight app", e);
1401                    } catch (RemoteException e) {
1402                    }
1403                } catch (NameNotFoundException e) {
1404                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1405                }
1406            } break;
1407            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1408                INotificationManager inm = NotificationManager.getService();
1409                if (inm == null) {
1410                    return;
1411                }
1412                try {
1413                    inm.cancelNotificationWithTag("android", null,
1414                            R.string.heavy_weight_notification,  msg.arg1);
1415                } catch (RuntimeException e) {
1416                    Slog.w(ActivityManagerService.TAG,
1417                            "Error canceling notification for service", e);
1418                } catch (RemoteException e) {
1419                }
1420            } break;
1421            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1422                synchronized (ActivityManagerService.this) {
1423                    checkExcessivePowerUsageLocked(true);
1424                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1425                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1426                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1427                }
1428            } break;
1429            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1430                synchronized (ActivityManagerService.this) {
1431                    ActivityRecord ar = (ActivityRecord)msg.obj;
1432                    if (mCompatModeDialog != null) {
1433                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1434                                ar.info.applicationInfo.packageName)) {
1435                            return;
1436                        }
1437                        mCompatModeDialog.dismiss();
1438                        mCompatModeDialog = null;
1439                    }
1440                    if (ar != null && false) {
1441                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1442                                ar.packageName)) {
1443                            int mode = mCompatModePackages.computeCompatModeLocked(
1444                                    ar.info.applicationInfo);
1445                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1446                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1447                                mCompatModeDialog = new CompatModeDialog(
1448                                        ActivityManagerService.this, mContext,
1449                                        ar.info.applicationInfo);
1450                                mCompatModeDialog.show();
1451                            }
1452                        }
1453                    }
1454                }
1455                break;
1456            }
1457            case DISPATCH_PROCESSES_CHANGED: {
1458                dispatchProcessesChanged();
1459                break;
1460            }
1461            case DISPATCH_PROCESS_DIED: {
1462                final int pid = msg.arg1;
1463                final int uid = msg.arg2;
1464                dispatchProcessDied(pid, uid);
1465                break;
1466            }
1467            case REPORT_MEM_USAGE_MSG: {
1468                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1469                Thread thread = new Thread() {
1470                    @Override public void run() {
1471                        final SparseArray<ProcessMemInfo> infoMap
1472                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1473                        for (int i=0, N=memInfos.size(); i<N; i++) {
1474                            ProcessMemInfo mi = memInfos.get(i);
1475                            infoMap.put(mi.pid, mi);
1476                        }
1477                        updateCpuStatsNow();
1478                        synchronized (mProcessCpuThread) {
1479                            final int N = mProcessCpuTracker.countStats();
1480                            for (int i=0; i<N; i++) {
1481                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1482                                if (st.vsize > 0) {
1483                                    long pss = Debug.getPss(st.pid, null);
1484                                    if (pss > 0) {
1485                                        if (infoMap.indexOfKey(st.pid) < 0) {
1486                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1487                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1488                                            mi.pss = pss;
1489                                            memInfos.add(mi);
1490                                        }
1491                                    }
1492                                }
1493                            }
1494                        }
1495
1496                        long totalPss = 0;
1497                        for (int i=0, N=memInfos.size(); i<N; i++) {
1498                            ProcessMemInfo mi = memInfos.get(i);
1499                            if (mi.pss == 0) {
1500                                mi.pss = Debug.getPss(mi.pid, null);
1501                            }
1502                            totalPss += mi.pss;
1503                        }
1504                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1505                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1506                                if (lhs.oomAdj != rhs.oomAdj) {
1507                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1508                                }
1509                                if (lhs.pss != rhs.pss) {
1510                                    return lhs.pss < rhs.pss ? 1 : -1;
1511                                }
1512                                return 0;
1513                            }
1514                        });
1515
1516                        StringBuilder tag = new StringBuilder(128);
1517                        StringBuilder stack = new StringBuilder(128);
1518                        tag.append("Low on memory -- ");
1519                        appendMemBucket(tag, totalPss, "total", false);
1520                        appendMemBucket(stack, totalPss, "total", true);
1521
1522                        StringBuilder logBuilder = new StringBuilder(1024);
1523                        logBuilder.append("Low on memory:\n");
1524
1525                        boolean firstLine = true;
1526                        int lastOomAdj = Integer.MIN_VALUE;
1527                        for (int i=0, N=memInfos.size(); i<N; i++) {
1528                            ProcessMemInfo mi = memInfos.get(i);
1529
1530                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1531                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1532                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1533                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1534                                if (lastOomAdj != mi.oomAdj) {
1535                                    lastOomAdj = mi.oomAdj;
1536                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1537                                        tag.append(" / ");
1538                                    }
1539                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1540                                        if (firstLine) {
1541                                            stack.append(":");
1542                                            firstLine = false;
1543                                        }
1544                                        stack.append("\n\t at ");
1545                                    } else {
1546                                        stack.append("$");
1547                                    }
1548                                } else {
1549                                    tag.append(" ");
1550                                    stack.append("$");
1551                                }
1552                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1553                                    appendMemBucket(tag, mi.pss, mi.name, false);
1554                                }
1555                                appendMemBucket(stack, mi.pss, mi.name, true);
1556                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1557                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1558                                    stack.append("(");
1559                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1560                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1561                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1562                                            stack.append(":");
1563                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1564                                        }
1565                                    }
1566                                    stack.append(")");
1567                                }
1568                            }
1569
1570                            logBuilder.append("  ");
1571                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1572                            logBuilder.append(' ');
1573                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1574                            logBuilder.append(' ');
1575                            ProcessList.appendRamKb(logBuilder, mi.pss);
1576                            logBuilder.append(" kB: ");
1577                            logBuilder.append(mi.name);
1578                            logBuilder.append(" (");
1579                            logBuilder.append(mi.pid);
1580                            logBuilder.append(") ");
1581                            logBuilder.append(mi.adjType);
1582                            logBuilder.append('\n');
1583                            if (mi.adjReason != null) {
1584                                logBuilder.append("                      ");
1585                                logBuilder.append(mi.adjReason);
1586                                logBuilder.append('\n');
1587                            }
1588                        }
1589
1590                        logBuilder.append("           ");
1591                        ProcessList.appendRamKb(logBuilder, totalPss);
1592                        logBuilder.append(" kB: TOTAL\n");
1593
1594                        long[] infos = new long[Debug.MEMINFO_COUNT];
1595                        Debug.getMemInfo(infos);
1596                        logBuilder.append("  MemInfo: ");
1597                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1598                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1599                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1600                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1601                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1602                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1603                            logBuilder.append("  ZRAM: ");
1604                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1605                            logBuilder.append(" kB RAM, ");
1606                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1607                            logBuilder.append(" kB swap total, ");
1608                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1609                            logBuilder.append(" kB swap free\n");
1610                        }
1611                        Slog.i(TAG, logBuilder.toString());
1612
1613                        StringBuilder dropBuilder = new StringBuilder(1024);
1614                        /*
1615                        StringWriter oomSw = new StringWriter();
1616                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1617                        StringWriter catSw = new StringWriter();
1618                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1619                        String[] emptyArgs = new String[] { };
1620                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1621                        oomPw.flush();
1622                        String oomString = oomSw.toString();
1623                        */
1624                        dropBuilder.append(stack);
1625                        dropBuilder.append('\n');
1626                        dropBuilder.append('\n');
1627                        dropBuilder.append(logBuilder);
1628                        dropBuilder.append('\n');
1629                        /*
1630                        dropBuilder.append(oomString);
1631                        dropBuilder.append('\n');
1632                        */
1633                        StringWriter catSw = new StringWriter();
1634                        synchronized (ActivityManagerService.this) {
1635                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1636                            String[] emptyArgs = new String[] { };
1637                            catPw.println();
1638                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1639                            catPw.println();
1640                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1641                                    false, false, null);
1642                            catPw.println();
1643                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1644                            catPw.flush();
1645                        }
1646                        dropBuilder.append(catSw.toString());
1647                        addErrorToDropBox("lowmem", null, "system_server", null,
1648                                null, tag.toString(), dropBuilder.toString(), null, null);
1649                        //Slog.i(TAG, "Sent to dropbox:");
1650                        //Slog.i(TAG, dropBuilder.toString());
1651                        synchronized (ActivityManagerService.this) {
1652                            long now = SystemClock.uptimeMillis();
1653                            if (mLastMemUsageReportTime < now) {
1654                                mLastMemUsageReportTime = now;
1655                            }
1656                        }
1657                    }
1658                };
1659                thread.start();
1660                break;
1661            }
1662            case REPORT_USER_SWITCH_MSG: {
1663                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1664                break;
1665            }
1666            case CONTINUE_USER_SWITCH_MSG: {
1667                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1668                break;
1669            }
1670            case USER_SWITCH_TIMEOUT_MSG: {
1671                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1672                break;
1673            }
1674            case IMMERSIVE_MODE_LOCK_MSG: {
1675                final boolean nextState = (msg.arg1 != 0);
1676                if (mUpdateLock.isHeld() != nextState) {
1677                    if (DEBUG_IMMERSIVE) {
1678                        final ActivityRecord r = (ActivityRecord) msg.obj;
1679                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1680                    }
1681                    if (nextState) {
1682                        mUpdateLock.acquire();
1683                    } else {
1684                        mUpdateLock.release();
1685                    }
1686                }
1687                break;
1688            }
1689            case PERSIST_URI_GRANTS_MSG: {
1690                writeGrantedUriPermissions();
1691                break;
1692            }
1693            case REQUEST_ALL_PSS_MSG: {
1694                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1695                break;
1696            }
1697            case START_PROFILES_MSG: {
1698                synchronized (ActivityManagerService.this) {
1699                    startProfilesLocked();
1700                }
1701                break;
1702            }
1703            case UPDATE_TIME: {
1704                synchronized (ActivityManagerService.this) {
1705                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1706                        ProcessRecord r = mLruProcesses.get(i);
1707                        if (r.thread != null) {
1708                            try {
1709                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1710                            } catch (RemoteException ex) {
1711                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1712                            }
1713                        }
1714                    }
1715                }
1716                break;
1717            }
1718            }
1719        }
1720    };
1721
1722    static final int COLLECT_PSS_BG_MSG = 1;
1723
1724    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1725        @Override
1726        public void handleMessage(Message msg) {
1727            switch (msg.what) {
1728            case COLLECT_PSS_BG_MSG: {
1729                int i=0, num=0;
1730                long start = SystemClock.uptimeMillis();
1731                long[] tmp = new long[1];
1732                do {
1733                    ProcessRecord proc;
1734                    int procState;
1735                    int pid;
1736                    synchronized (ActivityManagerService.this) {
1737                        if (i >= mPendingPssProcesses.size()) {
1738                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1739                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1740                            mPendingPssProcesses.clear();
1741                            return;
1742                        }
1743                        proc = mPendingPssProcesses.get(i);
1744                        procState = proc.pssProcState;
1745                        if (proc.thread != null && procState == proc.setProcState) {
1746                            pid = proc.pid;
1747                        } else {
1748                            proc = null;
1749                            pid = 0;
1750                        }
1751                        i++;
1752                    }
1753                    if (proc != null) {
1754                        long pss = Debug.getPss(pid, tmp);
1755                        synchronized (ActivityManagerService.this) {
1756                            if (proc.thread != null && proc.setProcState == procState
1757                                    && proc.pid == pid) {
1758                                num++;
1759                                proc.lastPssTime = SystemClock.uptimeMillis();
1760                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1761                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1762                                        + ": " + pss + " lastPss=" + proc.lastPss
1763                                        + " state=" + ProcessList.makeProcStateString(procState));
1764                                if (proc.initialIdlePss == 0) {
1765                                    proc.initialIdlePss = pss;
1766                                }
1767                                proc.lastPss = pss;
1768                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1769                                    proc.lastCachedPss = pss;
1770                                }
1771                            }
1772                        }
1773                    }
1774                } while (true);
1775            }
1776            }
1777        }
1778    };
1779
1780    public void setSystemProcess() {
1781        try {
1782            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1783            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1784            ServiceManager.addService("meminfo", new MemBinder(this));
1785            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1786            ServiceManager.addService("dbinfo", new DbBinder(this));
1787            if (MONITOR_CPU_USAGE) {
1788                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1789            }
1790            ServiceManager.addService("permission", new PermissionController(this));
1791
1792            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1793                    "android", STOCK_PM_FLAGS);
1794            mSystemThread.installSystemApplicationInfo(info);
1795
1796            synchronized (this) {
1797                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1798                app.persistent = true;
1799                app.pid = MY_PID;
1800                app.maxAdj = ProcessList.SYSTEM_ADJ;
1801                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1802                mProcessNames.put(app.processName, app.uid, app);
1803                synchronized (mPidsSelfLocked) {
1804                    mPidsSelfLocked.put(app.pid, app);
1805                }
1806                updateLruProcessLocked(app, false, null);
1807                updateOomAdjLocked();
1808            }
1809        } catch (PackageManager.NameNotFoundException e) {
1810            throw new RuntimeException(
1811                    "Unable to find android system package", e);
1812        }
1813    }
1814
1815    public void setWindowManager(WindowManagerService wm) {
1816        mWindowManager = wm;
1817        mStackSupervisor.setWindowManager(wm);
1818    }
1819
1820    public void startObservingNativeCrashes() {
1821        final NativeCrashListener ncl = new NativeCrashListener(this);
1822        ncl.start();
1823    }
1824
1825    public IAppOpsService getAppOpsService() {
1826        return mAppOpsService;
1827    }
1828
1829    static class MemBinder extends Binder {
1830        ActivityManagerService mActivityManagerService;
1831        MemBinder(ActivityManagerService activityManagerService) {
1832            mActivityManagerService = activityManagerService;
1833        }
1834
1835        @Override
1836        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1837            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1838                    != PackageManager.PERMISSION_GRANTED) {
1839                pw.println("Permission Denial: can't dump meminfo from from pid="
1840                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1841                        + " without permission " + android.Manifest.permission.DUMP);
1842                return;
1843            }
1844
1845            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1846        }
1847    }
1848
1849    static class GraphicsBinder extends Binder {
1850        ActivityManagerService mActivityManagerService;
1851        GraphicsBinder(ActivityManagerService activityManagerService) {
1852            mActivityManagerService = activityManagerService;
1853        }
1854
1855        @Override
1856        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1857            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1858                    != PackageManager.PERMISSION_GRANTED) {
1859                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1860                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1861                        + " without permission " + android.Manifest.permission.DUMP);
1862                return;
1863            }
1864
1865            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1866        }
1867    }
1868
1869    static class DbBinder extends Binder {
1870        ActivityManagerService mActivityManagerService;
1871        DbBinder(ActivityManagerService activityManagerService) {
1872            mActivityManagerService = activityManagerService;
1873        }
1874
1875        @Override
1876        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1877            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1878                    != PackageManager.PERMISSION_GRANTED) {
1879                pw.println("Permission Denial: can't dump dbinfo from from pid="
1880                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1881                        + " without permission " + android.Manifest.permission.DUMP);
1882                return;
1883            }
1884
1885            mActivityManagerService.dumpDbInfo(fd, pw, args);
1886        }
1887    }
1888
1889    static class CpuBinder extends Binder {
1890        ActivityManagerService mActivityManagerService;
1891        CpuBinder(ActivityManagerService activityManagerService) {
1892            mActivityManagerService = activityManagerService;
1893        }
1894
1895        @Override
1896        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1897            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1898                    != PackageManager.PERMISSION_GRANTED) {
1899                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1900                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1901                        + " without permission " + android.Manifest.permission.DUMP);
1902                return;
1903            }
1904
1905            synchronized (mActivityManagerService.mProcessCpuThread) {
1906                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1907                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1908                        SystemClock.uptimeMillis()));
1909            }
1910        }
1911    }
1912
1913    public static final class Lifecycle extends SystemService {
1914        private final ActivityManagerService mService;
1915
1916        public Lifecycle(Context context) {
1917            super(context);
1918            mService = new ActivityManagerService(context);
1919        }
1920
1921        @Override
1922        public void onStart() {
1923            mService.start();
1924        }
1925
1926        public ActivityManagerService getService() {
1927            return mService;
1928        }
1929    }
1930
1931    // Note: This method is invoked on the main thread but may need to attach various
1932    // handlers to other threads.  So take care to be explicit about the looper.
1933    public ActivityManagerService(Context systemContext) {
1934        mContext = systemContext;
1935        mFactoryTest = FactoryTest.getMode();
1936        mSystemThread = ActivityThread.currentActivityThread();
1937
1938        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1939
1940        mHandlerThread = new ServiceThread(TAG,
1941                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1942        mHandlerThread.start();
1943        mHandler = new MainHandler(mHandlerThread.getLooper());
1944
1945        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1946                "foreground", BROADCAST_FG_TIMEOUT, false);
1947        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1948                "background", BROADCAST_BG_TIMEOUT, true);
1949        mBroadcastQueues[0] = mFgBroadcastQueue;
1950        mBroadcastQueues[1] = mBgBroadcastQueue;
1951
1952        mServices = new ActiveServices(this);
1953        mProviderMap = new ProviderMap(this);
1954
1955        // TODO: Move creation of battery stats service outside of activity manager service.
1956        File dataDir = Environment.getDataDirectory();
1957        File systemDir = new File(dataDir, "system");
1958        systemDir.mkdirs();
1959        mBatteryStatsService = new BatteryStatsService(new File(
1960                systemDir, "batterystats.bin").toString(), mHandler);
1961        mBatteryStatsService.getActiveStatistics().readLocked();
1962        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1963        mOnBattery = DEBUG_POWER ? true
1964                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1965        mBatteryStatsService.getActiveStatistics().setCallback(this);
1966
1967        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1968
1969        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1970        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1971
1972        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1973
1974        // User 0 is the first and only user that runs at boot.
1975        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1976        mUserLru.add(Integer.valueOf(0));
1977        updateStartedUserArrayLocked();
1978
1979        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1980            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1981
1982        mConfiguration.setToDefaults();
1983        mConfiguration.setLocale(Locale.getDefault());
1984
1985        mConfigurationSeq = mConfiguration.seq = 1;
1986        mProcessCpuTracker.init();
1987
1988        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1989        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1990        mStackSupervisor = new ActivityStackSupervisor(this);
1991
1992        mProcessCpuThread = new Thread("CpuTracker") {
1993            @Override
1994            public void run() {
1995                while (true) {
1996                    try {
1997                        try {
1998                            synchronized(this) {
1999                                final long now = SystemClock.uptimeMillis();
2000                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2001                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2002                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2003                                //        + ", write delay=" + nextWriteDelay);
2004                                if (nextWriteDelay < nextCpuDelay) {
2005                                    nextCpuDelay = nextWriteDelay;
2006                                }
2007                                if (nextCpuDelay > 0) {
2008                                    mProcessCpuMutexFree.set(true);
2009                                    this.wait(nextCpuDelay);
2010                                }
2011                            }
2012                        } catch (InterruptedException e) {
2013                        }
2014                        updateCpuStatsNow();
2015                    } catch (Exception e) {
2016                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2017                    }
2018                }
2019            }
2020        };
2021
2022        Watchdog.getInstance().addMonitor(this);
2023        Watchdog.getInstance().addThread(mHandler);
2024    }
2025
2026    private void start() {
2027        mProcessCpuThread.start();
2028
2029        mBatteryStatsService.publish(mContext);
2030        mUsageStatsService.publish(mContext);
2031        mAppOpsService.publish(mContext);
2032        startRunning(null, null, null, null);
2033    }
2034
2035    @Override
2036    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2037            throws RemoteException {
2038        if (code == SYSPROPS_TRANSACTION) {
2039            // We need to tell all apps about the system property change.
2040            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2041            synchronized(this) {
2042                final int NP = mProcessNames.getMap().size();
2043                for (int ip=0; ip<NP; ip++) {
2044                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2045                    final int NA = apps.size();
2046                    for (int ia=0; ia<NA; ia++) {
2047                        ProcessRecord app = apps.valueAt(ia);
2048                        if (app.thread != null) {
2049                            procs.add(app.thread.asBinder());
2050                        }
2051                    }
2052                }
2053            }
2054
2055            int N = procs.size();
2056            for (int i=0; i<N; i++) {
2057                Parcel data2 = Parcel.obtain();
2058                try {
2059                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2060                } catch (RemoteException e) {
2061                }
2062                data2.recycle();
2063            }
2064        }
2065        try {
2066            return super.onTransact(code, data, reply, flags);
2067        } catch (RuntimeException e) {
2068            // The activity manager only throws security exceptions, so let's
2069            // log all others.
2070            if (!(e instanceof SecurityException)) {
2071                Slog.wtf(TAG, "Activity Manager Crash", e);
2072            }
2073            throw e;
2074        }
2075    }
2076
2077    void updateCpuStats() {
2078        final long now = SystemClock.uptimeMillis();
2079        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2080            return;
2081        }
2082        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2083            synchronized (mProcessCpuThread) {
2084                mProcessCpuThread.notify();
2085            }
2086        }
2087    }
2088
2089    void updateCpuStatsNow() {
2090        synchronized (mProcessCpuThread) {
2091            mProcessCpuMutexFree.set(false);
2092            final long now = SystemClock.uptimeMillis();
2093            boolean haveNewCpuStats = false;
2094
2095            if (MONITOR_CPU_USAGE &&
2096                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2097                mLastCpuTime.set(now);
2098                haveNewCpuStats = true;
2099                mProcessCpuTracker.update();
2100                //Slog.i(TAG, mProcessCpu.printCurrentState());
2101                //Slog.i(TAG, "Total CPU usage: "
2102                //        + mProcessCpu.getTotalCpuPercent() + "%");
2103
2104                // Slog the cpu usage if the property is set.
2105                if ("true".equals(SystemProperties.get("events.cpu"))) {
2106                    int user = mProcessCpuTracker.getLastUserTime();
2107                    int system = mProcessCpuTracker.getLastSystemTime();
2108                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2109                    int irq = mProcessCpuTracker.getLastIrqTime();
2110                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2111                    int idle = mProcessCpuTracker.getLastIdleTime();
2112
2113                    int total = user + system + iowait + irq + softIrq + idle;
2114                    if (total == 0) total = 1;
2115
2116                    EventLog.writeEvent(EventLogTags.CPU,
2117                            ((user+system+iowait+irq+softIrq) * 100) / total,
2118                            (user * 100) / total,
2119                            (system * 100) / total,
2120                            (iowait * 100) / total,
2121                            (irq * 100) / total,
2122                            (softIrq * 100) / total);
2123                }
2124            }
2125
2126            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2127            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2128            synchronized(bstats) {
2129                synchronized(mPidsSelfLocked) {
2130                    if (haveNewCpuStats) {
2131                        if (mOnBattery) {
2132                            int perc = bstats.startAddingCpuLocked();
2133                            int totalUTime = 0;
2134                            int totalSTime = 0;
2135                            final int N = mProcessCpuTracker.countStats();
2136                            for (int i=0; i<N; i++) {
2137                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2138                                if (!st.working) {
2139                                    continue;
2140                                }
2141                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2142                                int otherUTime = (st.rel_utime*perc)/100;
2143                                int otherSTime = (st.rel_stime*perc)/100;
2144                                totalUTime += otherUTime;
2145                                totalSTime += otherSTime;
2146                                if (pr != null) {
2147                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2148                                    if (ps == null || !ps.isActive()) {
2149                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2150                                                pr.info.uid, pr.processName);
2151                                    }
2152                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2153                                            st.rel_stime-otherSTime);
2154                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2155                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2156                                } else {
2157                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2158                                    if (ps == null || !ps.isActive()) {
2159                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2160                                                bstats.mapUid(st.uid), st.name);
2161                                    }
2162                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2163                                            st.rel_stime-otherSTime);
2164                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2165                                }
2166                            }
2167                            bstats.finishAddingCpuLocked(perc, totalUTime,
2168                                    totalSTime, cpuSpeedTimes);
2169                        }
2170                    }
2171                }
2172
2173                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2174                    mLastWriteTime = now;
2175                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2176                }
2177            }
2178        }
2179    }
2180
2181    @Override
2182    public void batteryNeedsCpuUpdate() {
2183        updateCpuStatsNow();
2184    }
2185
2186    @Override
2187    public void batteryPowerChanged(boolean onBattery) {
2188        // When plugging in, update the CPU stats first before changing
2189        // the plug state.
2190        updateCpuStatsNow();
2191        synchronized (this) {
2192            synchronized(mPidsSelfLocked) {
2193                mOnBattery = DEBUG_POWER ? true : onBattery;
2194            }
2195        }
2196    }
2197
2198    /**
2199     * Initialize the application bind args. These are passed to each
2200     * process when the bindApplication() IPC is sent to the process. They're
2201     * lazily setup to make sure the services are running when they're asked for.
2202     */
2203    private HashMap<String, IBinder> getCommonServicesLocked() {
2204        if (mAppBindArgs == null) {
2205            mAppBindArgs = new HashMap<String, IBinder>();
2206
2207            // Setup the application init args
2208            mAppBindArgs.put("package", ServiceManager.getService("package"));
2209            mAppBindArgs.put("window", ServiceManager.getService("window"));
2210            mAppBindArgs.put(Context.ALARM_SERVICE,
2211                    ServiceManager.getService(Context.ALARM_SERVICE));
2212        }
2213        return mAppBindArgs;
2214    }
2215
2216    final void setFocusedActivityLocked(ActivityRecord r) {
2217        if (mFocusedActivity != r) {
2218            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2219            mFocusedActivity = r;
2220            mStackSupervisor.setFocusedStack(r);
2221            if (r != null) {
2222                mWindowManager.setFocusedApp(r.appToken, true);
2223            }
2224            applyUpdateLockStateLocked(r);
2225        }
2226    }
2227
2228    @Override
2229    public void setFocusedStack(int stackId) {
2230        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2231        synchronized (ActivityManagerService.this) {
2232            ActivityStack stack = mStackSupervisor.getStack(stackId);
2233            if (stack != null) {
2234                ActivityRecord r = stack.topRunningActivityLocked(null);
2235                if (r != null) {
2236                    setFocusedActivityLocked(r);
2237                }
2238            }
2239        }
2240    }
2241
2242    @Override
2243    public void notifyActivityDrawn(IBinder token) {
2244        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2245        synchronized (this) {
2246            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2247            if (r != null) {
2248                r.task.stack.notifyActivityDrawnLocked(r);
2249            }
2250        }
2251    }
2252
2253    final void applyUpdateLockStateLocked(ActivityRecord r) {
2254        // Modifications to the UpdateLock state are done on our handler, outside
2255        // the activity manager's locks.  The new state is determined based on the
2256        // state *now* of the relevant activity record.  The object is passed to
2257        // the handler solely for logging detail, not to be consulted/modified.
2258        final boolean nextState = r != null && r.immersive;
2259        mHandler.sendMessage(
2260                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2261    }
2262
2263    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2264        Message msg = Message.obtain();
2265        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2266        msg.obj = r.task.askedCompatMode ? null : r;
2267        mHandler.sendMessage(msg);
2268    }
2269
2270    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2271            String what, Object obj, ProcessRecord srcApp) {
2272        app.lastActivityTime = now;
2273
2274        if (app.activities.size() > 0) {
2275            // Don't want to touch dependent processes that are hosting activities.
2276            return index;
2277        }
2278
2279        int lrui = mLruProcesses.lastIndexOf(app);
2280        if (lrui < 0) {
2281            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2282                    + what + " " + obj + " from " + srcApp);
2283            return index;
2284        }
2285
2286        if (lrui >= index) {
2287            // Don't want to cause this to move dependent processes *back* in the
2288            // list as if they were less frequently used.
2289            return index;
2290        }
2291
2292        if (lrui >= mLruProcessActivityStart) {
2293            // Don't want to touch dependent processes that are hosting activities.
2294            return index;
2295        }
2296
2297        mLruProcesses.remove(lrui);
2298        if (index > 0) {
2299            index--;
2300        }
2301        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2302                + " in LRU list: " + app);
2303        mLruProcesses.add(index, app);
2304        return index;
2305    }
2306
2307    final void removeLruProcessLocked(ProcessRecord app) {
2308        int lrui = mLruProcesses.lastIndexOf(app);
2309        if (lrui >= 0) {
2310            if (lrui <= mLruProcessActivityStart) {
2311                mLruProcessActivityStart--;
2312            }
2313            if (lrui <= mLruProcessServiceStart) {
2314                mLruProcessServiceStart--;
2315            }
2316            mLruProcesses.remove(lrui);
2317        }
2318    }
2319
2320    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2321            ProcessRecord client) {
2322        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2323                || app.treatLikeActivity;
2324        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2325        if (!activityChange && hasActivity) {
2326            // The process has activities, so we are only allowing activity-based adjustments
2327            // to move it.  It should be kept in the front of the list with other
2328            // processes that have activities, and we don't want those to change their
2329            // order except due to activity operations.
2330            return;
2331        }
2332
2333        mLruSeq++;
2334        final long now = SystemClock.uptimeMillis();
2335        app.lastActivityTime = now;
2336
2337        // First a quick reject: if the app is already at the position we will
2338        // put it, then there is nothing to do.
2339        if (hasActivity) {
2340            final int N = mLruProcesses.size();
2341            if (N > 0 && mLruProcesses.get(N-1) == app) {
2342                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2343                return;
2344            }
2345        } else {
2346            if (mLruProcessServiceStart > 0
2347                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2348                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2349                return;
2350            }
2351        }
2352
2353        int lrui = mLruProcesses.lastIndexOf(app);
2354
2355        if (app.persistent && lrui >= 0) {
2356            // We don't care about the position of persistent processes, as long as
2357            // they are in the list.
2358            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2359            return;
2360        }
2361
2362        /* In progress: compute new position first, so we can avoid doing work
2363           if the process is not actually going to move.  Not yet working.
2364        int addIndex;
2365        int nextIndex;
2366        boolean inActivity = false, inService = false;
2367        if (hasActivity) {
2368            // Process has activities, put it at the very tipsy-top.
2369            addIndex = mLruProcesses.size();
2370            nextIndex = mLruProcessServiceStart;
2371            inActivity = true;
2372        } else if (hasService) {
2373            // Process has services, put it at the top of the service list.
2374            addIndex = mLruProcessActivityStart;
2375            nextIndex = mLruProcessServiceStart;
2376            inActivity = true;
2377            inService = true;
2378        } else  {
2379            // Process not otherwise of interest, it goes to the top of the non-service area.
2380            addIndex = mLruProcessServiceStart;
2381            if (client != null) {
2382                int clientIndex = mLruProcesses.lastIndexOf(client);
2383                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2384                        + app);
2385                if (clientIndex >= 0 && addIndex > clientIndex) {
2386                    addIndex = clientIndex;
2387                }
2388            }
2389            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2390        }
2391
2392        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2393                + mLruProcessActivityStart + "): " + app);
2394        */
2395
2396        if (lrui >= 0) {
2397            if (lrui < mLruProcessActivityStart) {
2398                mLruProcessActivityStart--;
2399            }
2400            if (lrui < mLruProcessServiceStart) {
2401                mLruProcessServiceStart--;
2402            }
2403            /*
2404            if (addIndex > lrui) {
2405                addIndex--;
2406            }
2407            if (nextIndex > lrui) {
2408                nextIndex--;
2409            }
2410            */
2411            mLruProcesses.remove(lrui);
2412        }
2413
2414        /*
2415        mLruProcesses.add(addIndex, app);
2416        if (inActivity) {
2417            mLruProcessActivityStart++;
2418        }
2419        if (inService) {
2420            mLruProcessActivityStart++;
2421        }
2422        */
2423
2424        int nextIndex;
2425        if (hasActivity) {
2426            final int N = mLruProcesses.size();
2427            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2428                // Process doesn't have activities, but has clients with
2429                // activities...  move it up, but one below the top (the top
2430                // should always have a real activity).
2431                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2432                mLruProcesses.add(N-1, app);
2433                // To keep it from spamming the LRU list (by making a bunch of clients),
2434                // we will push down any other entries owned by the app.
2435                final int uid = app.info.uid;
2436                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2437                    ProcessRecord subProc = mLruProcesses.get(i);
2438                    if (subProc.info.uid == uid) {
2439                        // We want to push this one down the list.  If the process after
2440                        // it is for the same uid, however, don't do so, because we don't
2441                        // want them internally to be re-ordered.
2442                        if (mLruProcesses.get(i-1).info.uid != uid) {
2443                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2444                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2445                            ProcessRecord tmp = mLruProcesses.get(i);
2446                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2447                            mLruProcesses.set(i-1, tmp);
2448                            i--;
2449                        }
2450                    } else {
2451                        // A gap, we can stop here.
2452                        break;
2453                    }
2454                }
2455            } else {
2456                // Process has activities, put it at the very tipsy-top.
2457                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2458                mLruProcesses.add(app);
2459            }
2460            nextIndex = mLruProcessServiceStart;
2461        } else if (hasService) {
2462            // Process has services, put it at the top of the service list.
2463            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2464            mLruProcesses.add(mLruProcessActivityStart, app);
2465            nextIndex = mLruProcessServiceStart;
2466            mLruProcessActivityStart++;
2467        } else  {
2468            // Process not otherwise of interest, it goes to the top of the non-service area.
2469            int index = mLruProcessServiceStart;
2470            if (client != null) {
2471                // If there is a client, don't allow the process to be moved up higher
2472                // in the list than that client.
2473                int clientIndex = mLruProcesses.lastIndexOf(client);
2474                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2475                        + " when updating " + app);
2476                if (clientIndex <= lrui) {
2477                    // Don't allow the client index restriction to push it down farther in the
2478                    // list than it already is.
2479                    clientIndex = lrui;
2480                }
2481                if (clientIndex >= 0 && index > clientIndex) {
2482                    index = clientIndex;
2483                }
2484            }
2485            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2486            mLruProcesses.add(index, app);
2487            nextIndex = index-1;
2488            mLruProcessActivityStart++;
2489            mLruProcessServiceStart++;
2490        }
2491
2492        // If the app is currently using a content provider or service,
2493        // bump those processes as well.
2494        for (int j=app.connections.size()-1; j>=0; j--) {
2495            ConnectionRecord cr = app.connections.valueAt(j);
2496            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2497                    && cr.binding.service.app != null
2498                    && cr.binding.service.app.lruSeq != mLruSeq
2499                    && !cr.binding.service.app.persistent) {
2500                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2501                        "service connection", cr, app);
2502            }
2503        }
2504        for (int j=app.conProviders.size()-1; j>=0; j--) {
2505            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2506            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2507                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2508                        "provider reference", cpr, app);
2509            }
2510        }
2511    }
2512
2513    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2514        if (uid == Process.SYSTEM_UID) {
2515            // The system gets to run in any process.  If there are multiple
2516            // processes with the same uid, just pick the first (this
2517            // should never happen).
2518            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2519            if (procs == null) return null;
2520            final int N = procs.size();
2521            for (int i = 0; i < N; i++) {
2522                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2523            }
2524        }
2525        ProcessRecord proc = mProcessNames.get(processName, uid);
2526        if (false && proc != null && !keepIfLarge
2527                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2528                && proc.lastCachedPss >= 4000) {
2529            // Turn this condition on to cause killing to happen regularly, for testing.
2530            if (proc.baseProcessTracker != null) {
2531                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2532            }
2533            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2534                    + "k from cached");
2535        } else if (proc != null && !keepIfLarge
2536                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2537                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2538            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2539            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2540                if (proc.baseProcessTracker != null) {
2541                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2542                }
2543                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2544                        + "k from cached");
2545            }
2546        }
2547        return proc;
2548    }
2549
2550    void ensurePackageDexOpt(String packageName) {
2551        IPackageManager pm = AppGlobals.getPackageManager();
2552        try {
2553            if (pm.performDexOpt(packageName)) {
2554                mDidDexOpt = true;
2555            }
2556        } catch (RemoteException e) {
2557        }
2558    }
2559
2560    boolean isNextTransitionForward() {
2561        int transit = mWindowManager.getPendingAppTransition();
2562        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2563                || transit == AppTransition.TRANSIT_TASK_OPEN
2564                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2565    }
2566
2567    final ProcessRecord startProcessLocked(String processName,
2568            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2569            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2570            boolean isolated, boolean keepIfLarge) {
2571        ProcessRecord app;
2572        if (!isolated) {
2573            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2574        } else {
2575            // If this is an isolated process, it can't re-use an existing process.
2576            app = null;
2577        }
2578        // We don't have to do anything more if:
2579        // (1) There is an existing application record; and
2580        // (2) The caller doesn't think it is dead, OR there is no thread
2581        //     object attached to it so we know it couldn't have crashed; and
2582        // (3) There is a pid assigned to it, so it is either starting or
2583        //     already running.
2584        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2585                + " app=" + app + " knownToBeDead=" + knownToBeDead
2586                + " thread=" + (app != null ? app.thread : null)
2587                + " pid=" + (app != null ? app.pid : -1));
2588        if (app != null && app.pid > 0) {
2589            if (!knownToBeDead || app.thread == null) {
2590                // We already have the app running, or are waiting for it to
2591                // come up (we have a pid but not yet its thread), so keep it.
2592                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2593                // If this is a new package in the process, add the package to the list
2594                app.addPackage(info.packageName, mProcessStats);
2595                return app;
2596            }
2597
2598            // An application record is attached to a previous process,
2599            // clean it up now.
2600            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2601            handleAppDiedLocked(app, true, true);
2602        }
2603
2604        String hostingNameStr = hostingName != null
2605                ? hostingName.flattenToShortString() : null;
2606
2607        if (!isolated) {
2608            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2609                // If we are in the background, then check to see if this process
2610                // is bad.  If so, we will just silently fail.
2611                if (mBadProcesses.get(info.processName, info.uid) != null) {
2612                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2613                            + "/" + info.processName);
2614                    return null;
2615                }
2616            } else {
2617                // When the user is explicitly starting a process, then clear its
2618                // crash count so that we won't make it bad until they see at
2619                // least one crash dialog again, and make the process good again
2620                // if it had been bad.
2621                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2622                        + "/" + info.processName);
2623                mProcessCrashTimes.remove(info.processName, info.uid);
2624                if (mBadProcesses.get(info.processName, info.uid) != null) {
2625                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2626                            UserHandle.getUserId(info.uid), info.uid,
2627                            info.processName);
2628                    mBadProcesses.remove(info.processName, info.uid);
2629                    if (app != null) {
2630                        app.bad = false;
2631                    }
2632                }
2633            }
2634        }
2635
2636        if (app == null) {
2637            app = newProcessRecordLocked(info, processName, isolated);
2638            if (app == null) {
2639                Slog.w(TAG, "Failed making new process record for "
2640                        + processName + "/" + info.uid + " isolated=" + isolated);
2641                return null;
2642            }
2643            mProcessNames.put(processName, app.uid, app);
2644            if (isolated) {
2645                mIsolatedProcesses.put(app.uid, app);
2646            }
2647        } else {
2648            // If this is a new package in the process, add the package to the list
2649            app.addPackage(info.packageName, mProcessStats);
2650        }
2651
2652        // If the system is not ready yet, then hold off on starting this
2653        // process until it is.
2654        if (!mProcessesReady
2655                && !isAllowedWhileBooting(info)
2656                && !allowWhileBooting) {
2657            if (!mProcessesOnHold.contains(app)) {
2658                mProcessesOnHold.add(app);
2659            }
2660            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2661            return app;
2662        }
2663
2664        startProcessLocked(app, hostingType, hostingNameStr);
2665        return (app.pid != 0) ? app : null;
2666    }
2667
2668    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2669        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2670    }
2671
2672    private final void startProcessLocked(ProcessRecord app,
2673            String hostingType, String hostingNameStr) {
2674        if (app.pid > 0 && app.pid != MY_PID) {
2675            synchronized (mPidsSelfLocked) {
2676                mPidsSelfLocked.remove(app.pid);
2677                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2678            }
2679            app.setPid(0);
2680        }
2681
2682        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2683                "startProcessLocked removing on hold: " + app);
2684        mProcessesOnHold.remove(app);
2685
2686        updateCpuStats();
2687
2688        try {
2689            int uid = app.uid;
2690
2691            int[] gids = null;
2692            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2693            if (!app.isolated) {
2694                int[] permGids = null;
2695                try {
2696                    final PackageManager pm = mContext.getPackageManager();
2697                    permGids = pm.getPackageGids(app.info.packageName);
2698
2699                    if (Environment.isExternalStorageEmulated()) {
2700                        if (pm.checkPermission(
2701                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2702                                app.info.packageName) == PERMISSION_GRANTED) {
2703                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2704                        } else {
2705                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2706                        }
2707                    }
2708                } catch (PackageManager.NameNotFoundException e) {
2709                    Slog.w(TAG, "Unable to retrieve gids", e);
2710                }
2711
2712                /*
2713                 * Add shared application GID so applications can share some
2714                 * resources like shared libraries
2715                 */
2716                if (permGids == null) {
2717                    gids = new int[1];
2718                } else {
2719                    gids = new int[permGids.length + 1];
2720                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2721                }
2722                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2723            }
2724            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2725                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2726                        && mTopComponent != null
2727                        && app.processName.equals(mTopComponent.getPackageName())) {
2728                    uid = 0;
2729                }
2730                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2731                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2732                    uid = 0;
2733                }
2734            }
2735            int debugFlags = 0;
2736            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2737                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2738                // Also turn on CheckJNI for debuggable apps. It's quite
2739                // awkward to turn on otherwise.
2740                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2741            }
2742            // Run the app in safe mode if its manifest requests so or the
2743            // system is booted in safe mode.
2744            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2745                mSafeMode == true) {
2746                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2747            }
2748            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2749                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2750            }
2751            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2752                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2753            }
2754            if ("1".equals(SystemProperties.get("debug.assert"))) {
2755                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2756            }
2757
2758            // Start the process.  It will either succeed and return a result containing
2759            // the PID of the new process, or else throw a RuntimeException.
2760            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2761                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2762                    app.info.targetSdkVersion, app.info.seinfo, null);
2763
2764            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2765            synchronized (bs) {
2766                if (bs.isOnBattery()) {
2767                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2768                }
2769            }
2770
2771            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2772                    UserHandle.getUserId(uid), startResult.pid, uid,
2773                    app.processName, hostingType,
2774                    hostingNameStr != null ? hostingNameStr : "");
2775
2776            if (app.persistent) {
2777                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2778            }
2779
2780            StringBuilder buf = mStringBuilder;
2781            buf.setLength(0);
2782            buf.append("Start proc ");
2783            buf.append(app.processName);
2784            buf.append(" for ");
2785            buf.append(hostingType);
2786            if (hostingNameStr != null) {
2787                buf.append(" ");
2788                buf.append(hostingNameStr);
2789            }
2790            buf.append(": pid=");
2791            buf.append(startResult.pid);
2792            buf.append(" uid=");
2793            buf.append(uid);
2794            buf.append(" gids={");
2795            if (gids != null) {
2796                for (int gi=0; gi<gids.length; gi++) {
2797                    if (gi != 0) buf.append(", ");
2798                    buf.append(gids[gi]);
2799
2800                }
2801            }
2802            buf.append("}");
2803            Slog.i(TAG, buf.toString());
2804            app.setPid(startResult.pid);
2805            app.usingWrapper = startResult.usingWrapper;
2806            app.removed = false;
2807            synchronized (mPidsSelfLocked) {
2808                this.mPidsSelfLocked.put(startResult.pid, app);
2809                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2810                msg.obj = app;
2811                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2812                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2813            }
2814            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2815                    app.processName, app.info.uid);
2816            if (app.isolated) {
2817                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2818            }
2819        } catch (RuntimeException e) {
2820            // XXX do better error recovery.
2821            app.setPid(0);
2822            Slog.e(TAG, "Failure starting process " + app.processName, e);
2823        }
2824    }
2825
2826    void updateUsageStats(ActivityRecord component, boolean resumed) {
2827        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2828        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2829        if (resumed) {
2830            mUsageStatsService.noteResumeComponent(component.realActivity);
2831            synchronized (stats) {
2832                stats.noteActivityResumedLocked(component.app.uid);
2833            }
2834        } else {
2835            mUsageStatsService.notePauseComponent(component.realActivity);
2836            synchronized (stats) {
2837                stats.noteActivityPausedLocked(component.app.uid);
2838            }
2839        }
2840    }
2841
2842    Intent getHomeIntent() {
2843        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2844        intent.setComponent(mTopComponent);
2845        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2846            intent.addCategory(Intent.CATEGORY_HOME);
2847        }
2848        return intent;
2849    }
2850
2851    boolean startHomeActivityLocked(int userId) {
2852        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2853                && mTopAction == null) {
2854            // We are running in factory test mode, but unable to find
2855            // the factory test app, so just sit around displaying the
2856            // error message and don't try to start anything.
2857            return false;
2858        }
2859        Intent intent = getHomeIntent();
2860        ActivityInfo aInfo =
2861            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2862        if (aInfo != null) {
2863            intent.setComponent(new ComponentName(
2864                    aInfo.applicationInfo.packageName, aInfo.name));
2865            // Don't do this if the home app is currently being
2866            // instrumented.
2867            aInfo = new ActivityInfo(aInfo);
2868            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2869            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2870                    aInfo.applicationInfo.uid, true);
2871            if (app == null || app.instrumentationClass == null) {
2872                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2873                mStackSupervisor.startHomeActivity(intent, aInfo);
2874            }
2875        }
2876
2877        return true;
2878    }
2879
2880    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2881        ActivityInfo ai = null;
2882        ComponentName comp = intent.getComponent();
2883        try {
2884            if (comp != null) {
2885                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2886            } else {
2887                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2888                        intent,
2889                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2890                            flags, userId);
2891
2892                if (info != null) {
2893                    ai = info.activityInfo;
2894                }
2895            }
2896        } catch (RemoteException e) {
2897            // ignore
2898        }
2899
2900        return ai;
2901    }
2902
2903    /**
2904     * Starts the "new version setup screen" if appropriate.
2905     */
2906    void startSetupActivityLocked() {
2907        // Only do this once per boot.
2908        if (mCheckedForSetup) {
2909            return;
2910        }
2911
2912        // We will show this screen if the current one is a different
2913        // version than the last one shown, and we are not running in
2914        // low-level factory test mode.
2915        final ContentResolver resolver = mContext.getContentResolver();
2916        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2917                Settings.Global.getInt(resolver,
2918                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2919            mCheckedForSetup = true;
2920
2921            // See if we should be showing the platform update setup UI.
2922            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2923            List<ResolveInfo> ris = mContext.getPackageManager()
2924                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2925
2926            // We don't allow third party apps to replace this.
2927            ResolveInfo ri = null;
2928            for (int i=0; ris != null && i<ris.size(); i++) {
2929                if ((ris.get(i).activityInfo.applicationInfo.flags
2930                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2931                    ri = ris.get(i);
2932                    break;
2933                }
2934            }
2935
2936            if (ri != null) {
2937                String vers = ri.activityInfo.metaData != null
2938                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2939                        : null;
2940                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2941                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2942                            Intent.METADATA_SETUP_VERSION);
2943                }
2944                String lastVers = Settings.Secure.getString(
2945                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2946                if (vers != null && !vers.equals(lastVers)) {
2947                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2948                    intent.setComponent(new ComponentName(
2949                            ri.activityInfo.packageName, ri.activityInfo.name));
2950                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2951                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2952                }
2953            }
2954        }
2955    }
2956
2957    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2958        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2959    }
2960
2961    void enforceNotIsolatedCaller(String caller) {
2962        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2963            throw new SecurityException("Isolated process not allowed to call " + caller);
2964        }
2965    }
2966
2967    @Override
2968    public int getFrontActivityScreenCompatMode() {
2969        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2970        synchronized (this) {
2971            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2972        }
2973    }
2974
2975    @Override
2976    public void setFrontActivityScreenCompatMode(int mode) {
2977        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2978                "setFrontActivityScreenCompatMode");
2979        synchronized (this) {
2980            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2981        }
2982    }
2983
2984    @Override
2985    public int getPackageScreenCompatMode(String packageName) {
2986        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2987        synchronized (this) {
2988            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2989        }
2990    }
2991
2992    @Override
2993    public void setPackageScreenCompatMode(String packageName, int mode) {
2994        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2995                "setPackageScreenCompatMode");
2996        synchronized (this) {
2997            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2998        }
2999    }
3000
3001    @Override
3002    public boolean getPackageAskScreenCompat(String packageName) {
3003        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3004        synchronized (this) {
3005            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3006        }
3007    }
3008
3009    @Override
3010    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3011        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3012                "setPackageAskScreenCompat");
3013        synchronized (this) {
3014            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3015        }
3016    }
3017
3018    private void dispatchProcessesChanged() {
3019        int N;
3020        synchronized (this) {
3021            N = mPendingProcessChanges.size();
3022            if (mActiveProcessChanges.length < N) {
3023                mActiveProcessChanges = new ProcessChangeItem[N];
3024            }
3025            mPendingProcessChanges.toArray(mActiveProcessChanges);
3026            mAvailProcessChanges.addAll(mPendingProcessChanges);
3027            mPendingProcessChanges.clear();
3028            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3029        }
3030
3031        int i = mProcessObservers.beginBroadcast();
3032        while (i > 0) {
3033            i--;
3034            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3035            if (observer != null) {
3036                try {
3037                    for (int j=0; j<N; j++) {
3038                        ProcessChangeItem item = mActiveProcessChanges[j];
3039                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3040                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3041                                    + item.pid + " uid=" + item.uid + ": "
3042                                    + item.foregroundActivities);
3043                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3044                                    item.foregroundActivities);
3045                        }
3046                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3047                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3048                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3049                            observer.onImportanceChanged(item.pid, item.uid,
3050                                    item.importance);
3051                        }
3052                    }
3053                } catch (RemoteException e) {
3054                }
3055            }
3056        }
3057        mProcessObservers.finishBroadcast();
3058    }
3059
3060    private void dispatchProcessDied(int pid, int uid) {
3061        int i = mProcessObservers.beginBroadcast();
3062        while (i > 0) {
3063            i--;
3064            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3065            if (observer != null) {
3066                try {
3067                    observer.onProcessDied(pid, uid);
3068                } catch (RemoteException e) {
3069                }
3070            }
3071        }
3072        mProcessObservers.finishBroadcast();
3073    }
3074
3075    final void doPendingActivityLaunchesLocked(boolean doResume) {
3076        final int N = mPendingActivityLaunches.size();
3077        if (N <= 0) {
3078            return;
3079        }
3080        for (int i=0; i<N; i++) {
3081            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3082            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3083                    doResume && i == (N-1), null);
3084        }
3085        mPendingActivityLaunches.clear();
3086    }
3087
3088    @Override
3089    public final int startActivity(IApplicationThread caller, String callingPackage,
3090            Intent intent, String resolvedType, IBinder resultTo,
3091            String resultWho, int requestCode, int startFlags,
3092            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3093        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3094                resultWho, requestCode,
3095                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3096    }
3097
3098    @Override
3099    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3100            Intent intent, String resolvedType, IBinder resultTo,
3101            String resultWho, int requestCode, int startFlags,
3102            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3103        enforceNotIsolatedCaller("startActivity");
3104        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3105                false, true, "startActivity", null);
3106        // TODO: Switch to user app stacks here.
3107        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3108                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3109                null, null, options, userId, null);
3110    }
3111
3112    @Override
3113    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3114            Intent intent, String resolvedType, IBinder resultTo,
3115            String resultWho, int requestCode, int startFlags, String profileFile,
3116            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3117        enforceNotIsolatedCaller("startActivityAndWait");
3118        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3119                false, true, "startActivityAndWait", null);
3120        WaitResult res = new WaitResult();
3121        // TODO: Switch to user app stacks here.
3122        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3123                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3124                res, null, options, UserHandle.getCallingUserId(), null);
3125        return res;
3126    }
3127
3128    @Override
3129    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3130            Intent intent, String resolvedType, IBinder resultTo,
3131            String resultWho, int requestCode, int startFlags, Configuration config,
3132            Bundle options, int userId) {
3133        enforceNotIsolatedCaller("startActivityWithConfig");
3134        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3135                false, true, "startActivityWithConfig", null);
3136        // TODO: Switch to user app stacks here.
3137        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3138                resolvedType, resultTo, resultWho, requestCode, startFlags,
3139                null, null, null, config, options, userId, null);
3140        return ret;
3141    }
3142
3143    @Override
3144    public int startActivityIntentSender(IApplicationThread caller,
3145            IntentSender intent, Intent fillInIntent, String resolvedType,
3146            IBinder resultTo, String resultWho, int requestCode,
3147            int flagsMask, int flagsValues, Bundle options) {
3148        enforceNotIsolatedCaller("startActivityIntentSender");
3149        // Refuse possible leaked file descriptors
3150        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3151            throw new IllegalArgumentException("File descriptors passed in Intent");
3152        }
3153
3154        IIntentSender sender = intent.getTarget();
3155        if (!(sender instanceof PendingIntentRecord)) {
3156            throw new IllegalArgumentException("Bad PendingIntent object");
3157        }
3158
3159        PendingIntentRecord pir = (PendingIntentRecord)sender;
3160
3161        synchronized (this) {
3162            // If this is coming from the currently resumed activity, it is
3163            // effectively saying that app switches are allowed at this point.
3164            final ActivityStack stack = getFocusedStack();
3165            if (stack.mResumedActivity != null &&
3166                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3167                mAppSwitchesAllowedTime = 0;
3168            }
3169        }
3170        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3171                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3172        return ret;
3173    }
3174
3175    @Override
3176    public boolean startNextMatchingActivity(IBinder callingActivity,
3177            Intent intent, Bundle options) {
3178        // Refuse possible leaked file descriptors
3179        if (intent != null && intent.hasFileDescriptors() == true) {
3180            throw new IllegalArgumentException("File descriptors passed in Intent");
3181        }
3182
3183        synchronized (this) {
3184            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3185            if (r == null) {
3186                ActivityOptions.abort(options);
3187                return false;
3188            }
3189            if (r.app == null || r.app.thread == null) {
3190                // The caller is not running...  d'oh!
3191                ActivityOptions.abort(options);
3192                return false;
3193            }
3194            intent = new Intent(intent);
3195            // The caller is not allowed to change the data.
3196            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3197            // And we are resetting to find the next component...
3198            intent.setComponent(null);
3199
3200            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3201
3202            ActivityInfo aInfo = null;
3203            try {
3204                List<ResolveInfo> resolves =
3205                    AppGlobals.getPackageManager().queryIntentActivities(
3206                            intent, r.resolvedType,
3207                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3208                            UserHandle.getCallingUserId());
3209
3210                // Look for the original activity in the list...
3211                final int N = resolves != null ? resolves.size() : 0;
3212                for (int i=0; i<N; i++) {
3213                    ResolveInfo rInfo = resolves.get(i);
3214                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3215                            && rInfo.activityInfo.name.equals(r.info.name)) {
3216                        // We found the current one...  the next matching is
3217                        // after it.
3218                        i++;
3219                        if (i<N) {
3220                            aInfo = resolves.get(i).activityInfo;
3221                        }
3222                        if (debug) {
3223                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3224                                    + "/" + r.info.name);
3225                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3226                                    + "/" + aInfo.name);
3227                        }
3228                        break;
3229                    }
3230                }
3231            } catch (RemoteException e) {
3232            }
3233
3234            if (aInfo == null) {
3235                // Nobody who is next!
3236                ActivityOptions.abort(options);
3237                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3238                return false;
3239            }
3240
3241            intent.setComponent(new ComponentName(
3242                    aInfo.applicationInfo.packageName, aInfo.name));
3243            intent.setFlags(intent.getFlags()&~(
3244                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3245                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3246                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3247                    Intent.FLAG_ACTIVITY_NEW_TASK));
3248
3249            // Okay now we need to start the new activity, replacing the
3250            // currently running activity.  This is a little tricky because
3251            // we want to start the new one as if the current one is finished,
3252            // but not finish the current one first so that there is no flicker.
3253            // And thus...
3254            final boolean wasFinishing = r.finishing;
3255            r.finishing = true;
3256
3257            // Propagate reply information over to the new activity.
3258            final ActivityRecord resultTo = r.resultTo;
3259            final String resultWho = r.resultWho;
3260            final int requestCode = r.requestCode;
3261            r.resultTo = null;
3262            if (resultTo != null) {
3263                resultTo.removeResultsLocked(r, resultWho, requestCode);
3264            }
3265
3266            final long origId = Binder.clearCallingIdentity();
3267            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3268                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3269                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3270                    options, false, null, null);
3271            Binder.restoreCallingIdentity(origId);
3272
3273            r.finishing = wasFinishing;
3274            if (res != ActivityManager.START_SUCCESS) {
3275                return false;
3276            }
3277            return true;
3278        }
3279    }
3280
3281    final int startActivityInPackage(int uid, String callingPackage,
3282            Intent intent, String resolvedType, IBinder resultTo,
3283            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3284                    IActivityContainer container) {
3285
3286        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3287                false, true, "startActivityInPackage", null);
3288
3289        // TODO: Switch to user app stacks here.
3290        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3291                resultTo, resultWho, requestCode, startFlags,
3292                null, null, null, null, options, userId, container);
3293        return ret;
3294    }
3295
3296    @Override
3297    public final int startActivities(IApplicationThread caller, String callingPackage,
3298            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3299            int userId) {
3300        enforceNotIsolatedCaller("startActivities");
3301        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3302                false, true, "startActivity", null);
3303        // TODO: Switch to user app stacks here.
3304        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3305                resolvedTypes, resultTo, options, userId);
3306        return ret;
3307    }
3308
3309    final int startActivitiesInPackage(int uid, String callingPackage,
3310            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3311            Bundle options, int userId) {
3312
3313        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3314                false, true, "startActivityInPackage", null);
3315        // TODO: Switch to user app stacks here.
3316        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3317                resultTo, options, userId);
3318        return ret;
3319    }
3320
3321    final void addRecentTaskLocked(TaskRecord task) {
3322        int N = mRecentTasks.size();
3323        // Quick case: check if the top-most recent task is the same.
3324        if (N > 0 && mRecentTasks.get(0) == task) {
3325            return;
3326        }
3327        // Remove any existing entries that are the same kind of task.
3328        final Intent intent = task.intent;
3329        final boolean document = intent != null && intent.isDocument();
3330        for (int i=0; i<N; i++) {
3331            TaskRecord tr = mRecentTasks.get(i);
3332            if (task != tr) {
3333                if (task.userId != tr.userId) {
3334                    continue;
3335                }
3336                final Intent trIntent = tr.intent;
3337                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3338                    (intent == null || !intent.filterEquals(trIntent))) {
3339                    continue;
3340                }
3341                if (document || trIntent != null && trIntent.isDocument()) {
3342                    // Document tasks do not match other tasks.
3343                    continue;
3344                }
3345            }
3346
3347            // Either task and tr are the same or, their affinities match or their intents match
3348            // and neither of them is a document.
3349            tr.disposeThumbnail();
3350            mRecentTasks.remove(i);
3351            i--;
3352            N--;
3353            if (task.intent == null) {
3354                // If the new recent task we are adding is not fully
3355                // specified, then replace it with the existing recent task.
3356                task = tr;
3357            }
3358        }
3359        if (N >= MAX_RECENT_TASKS) {
3360            mRecentTasks.remove(N-1).disposeThumbnail();
3361        }
3362        mRecentTasks.add(0, task);
3363    }
3364
3365    @Override
3366    public void reportActivityFullyDrawn(IBinder token) {
3367        synchronized (this) {
3368            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3369            if (r == null) {
3370                return;
3371            }
3372            r.reportFullyDrawnLocked();
3373        }
3374    }
3375
3376    @Override
3377    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3378        synchronized (this) {
3379            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3380            if (r == null) {
3381                return;
3382            }
3383            final long origId = Binder.clearCallingIdentity();
3384            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3385            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3386                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3387            if (config != null) {
3388                r.frozenBeforeDestroy = true;
3389                if (!updateConfigurationLocked(config, r, false, false)) {
3390                    mStackSupervisor.resumeTopActivitiesLocked();
3391                }
3392            }
3393            Binder.restoreCallingIdentity(origId);
3394        }
3395    }
3396
3397    @Override
3398    public int getRequestedOrientation(IBinder token) {
3399        synchronized (this) {
3400            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3401            if (r == null) {
3402                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3403            }
3404            return mWindowManager.getAppOrientation(r.appToken);
3405        }
3406    }
3407
3408    /**
3409     * This is the internal entry point for handling Activity.finish().
3410     *
3411     * @param token The Binder token referencing the Activity we want to finish.
3412     * @param resultCode Result code, if any, from this Activity.
3413     * @param resultData Result data (Intent), if any, from this Activity.
3414     *
3415     * @return Returns true if the activity successfully finished, or false if it is still running.
3416     */
3417    @Override
3418    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3419        // Refuse possible leaked file descriptors
3420        if (resultData != null && resultData.hasFileDescriptors() == true) {
3421            throw new IllegalArgumentException("File descriptors passed in Intent");
3422        }
3423
3424        synchronized(this) {
3425            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3426            if (r == null) {
3427                return true;
3428            }
3429            if (mController != null) {
3430                // Find the first activity that is not finishing.
3431                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3432                if (next != null) {
3433                    // ask watcher if this is allowed
3434                    boolean resumeOK = true;
3435                    try {
3436                        resumeOK = mController.activityResuming(next.packageName);
3437                    } catch (RemoteException e) {
3438                        mController = null;
3439                        Watchdog.getInstance().setActivityController(null);
3440                    }
3441
3442                    if (!resumeOK) {
3443                        return false;
3444                    }
3445                }
3446            }
3447            final long origId = Binder.clearCallingIdentity();
3448            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3449                    resultData, "app-request", true);
3450            Binder.restoreCallingIdentity(origId);
3451            return res;
3452        }
3453    }
3454
3455    @Override
3456    public final void finishHeavyWeightApp() {
3457        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3458                != PackageManager.PERMISSION_GRANTED) {
3459            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3460                    + Binder.getCallingPid()
3461                    + ", uid=" + Binder.getCallingUid()
3462                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3463            Slog.w(TAG, msg);
3464            throw new SecurityException(msg);
3465        }
3466
3467        synchronized(this) {
3468            if (mHeavyWeightProcess == null) {
3469                return;
3470            }
3471
3472            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3473                    mHeavyWeightProcess.activities);
3474            for (int i=0; i<activities.size(); i++) {
3475                ActivityRecord r = activities.get(i);
3476                if (!r.finishing) {
3477                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3478                            null, "finish-heavy", true);
3479                }
3480            }
3481
3482            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3483                    mHeavyWeightProcess.userId, 0));
3484            mHeavyWeightProcess = null;
3485        }
3486    }
3487
3488    @Override
3489    public void crashApplication(int uid, int initialPid, String packageName,
3490            String message) {
3491        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3492                != PackageManager.PERMISSION_GRANTED) {
3493            String msg = "Permission Denial: crashApplication() from pid="
3494                    + Binder.getCallingPid()
3495                    + ", uid=" + Binder.getCallingUid()
3496                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3497            Slog.w(TAG, msg);
3498            throw new SecurityException(msg);
3499        }
3500
3501        synchronized(this) {
3502            ProcessRecord proc = null;
3503
3504            // Figure out which process to kill.  We don't trust that initialPid
3505            // still has any relation to current pids, so must scan through the
3506            // list.
3507            synchronized (mPidsSelfLocked) {
3508                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3509                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3510                    if (p.uid != uid) {
3511                        continue;
3512                    }
3513                    if (p.pid == initialPid) {
3514                        proc = p;
3515                        break;
3516                    }
3517                    if (p.pkgList.containsKey(packageName)) {
3518                        proc = p;
3519                    }
3520                }
3521            }
3522
3523            if (proc == null) {
3524                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3525                        + " initialPid=" + initialPid
3526                        + " packageName=" + packageName);
3527                return;
3528            }
3529
3530            if (proc.thread != null) {
3531                if (proc.pid == Process.myPid()) {
3532                    Log.w(TAG, "crashApplication: trying to crash self!");
3533                    return;
3534                }
3535                long ident = Binder.clearCallingIdentity();
3536                try {
3537                    proc.thread.scheduleCrash(message);
3538                } catch (RemoteException e) {
3539                }
3540                Binder.restoreCallingIdentity(ident);
3541            }
3542        }
3543    }
3544
3545    @Override
3546    public final void finishSubActivity(IBinder token, String resultWho,
3547            int requestCode) {
3548        synchronized(this) {
3549            final long origId = Binder.clearCallingIdentity();
3550            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3551            if (r != null) {
3552                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3553            }
3554            Binder.restoreCallingIdentity(origId);
3555        }
3556    }
3557
3558    @Override
3559    public boolean finishActivityAffinity(IBinder token) {
3560        synchronized(this) {
3561            final long origId = Binder.clearCallingIdentity();
3562            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3563            boolean res = false;
3564            if (r != null) {
3565                res = r.task.stack.finishActivityAffinityLocked(r);
3566            }
3567            Binder.restoreCallingIdentity(origId);
3568            return res;
3569        }
3570    }
3571
3572    @Override
3573    public boolean willActivityBeVisible(IBinder token) {
3574        synchronized(this) {
3575            ActivityStack stack = ActivityRecord.getStackLocked(token);
3576            if (stack != null) {
3577                return stack.willActivityBeVisibleLocked(token);
3578            }
3579            return false;
3580        }
3581    }
3582
3583    @Override
3584    public void overridePendingTransition(IBinder token, String packageName,
3585            int enterAnim, int exitAnim) {
3586        synchronized(this) {
3587            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3588            if (self == null) {
3589                return;
3590            }
3591
3592            final long origId = Binder.clearCallingIdentity();
3593
3594            if (self.state == ActivityState.RESUMED
3595                    || self.state == ActivityState.PAUSING) {
3596                mWindowManager.overridePendingAppTransition(packageName,
3597                        enterAnim, exitAnim, null);
3598            }
3599
3600            Binder.restoreCallingIdentity(origId);
3601        }
3602    }
3603
3604    /**
3605     * Main function for removing an existing process from the activity manager
3606     * as a result of that process going away.  Clears out all connections
3607     * to the process.
3608     */
3609    private final void handleAppDiedLocked(ProcessRecord app,
3610            boolean restarting, boolean allowRestart) {
3611        int pid = app.pid;
3612        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3613        if (!restarting) {
3614            removeLruProcessLocked(app);
3615            if (pid > 0) {
3616                ProcessList.remove(pid);
3617            }
3618        }
3619
3620        if (mProfileProc == app) {
3621            clearProfilerLocked();
3622        }
3623
3624        // Remove this application's activities from active lists.
3625        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3626
3627        app.activities.clear();
3628
3629        if (app.instrumentationClass != null) {
3630            Slog.w(TAG, "Crash of app " + app.processName
3631                  + " running instrumentation " + app.instrumentationClass);
3632            Bundle info = new Bundle();
3633            info.putString("shortMsg", "Process crashed.");
3634            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3635        }
3636
3637        if (!restarting) {
3638            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3639                // If there was nothing to resume, and we are not already
3640                // restarting this process, but there is a visible activity that
3641                // is hosted by the process...  then make sure all visible
3642                // activities are running, taking care of restarting this
3643                // process.
3644                if (hasVisibleActivities) {
3645                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3646                }
3647            }
3648        }
3649    }
3650
3651    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3652        IBinder threadBinder = thread.asBinder();
3653        // Find the application record.
3654        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3655            ProcessRecord rec = mLruProcesses.get(i);
3656            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3657                return i;
3658            }
3659        }
3660        return -1;
3661    }
3662
3663    final ProcessRecord getRecordForAppLocked(
3664            IApplicationThread thread) {
3665        if (thread == null) {
3666            return null;
3667        }
3668
3669        int appIndex = getLRURecordIndexForAppLocked(thread);
3670        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3671    }
3672
3673    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3674        // If there are no longer any background processes running,
3675        // and the app that died was not running instrumentation,
3676        // then tell everyone we are now low on memory.
3677        boolean haveBg = false;
3678        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3679            ProcessRecord rec = mLruProcesses.get(i);
3680            if (rec.thread != null
3681                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3682                haveBg = true;
3683                break;
3684            }
3685        }
3686
3687        if (!haveBg) {
3688            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3689            if (doReport) {
3690                long now = SystemClock.uptimeMillis();
3691                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3692                    doReport = false;
3693                } else {
3694                    mLastMemUsageReportTime = now;
3695                }
3696            }
3697            final ArrayList<ProcessMemInfo> memInfos
3698                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3699            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3700            long now = SystemClock.uptimeMillis();
3701            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3702                ProcessRecord rec = mLruProcesses.get(i);
3703                if (rec == dyingProc || rec.thread == null) {
3704                    continue;
3705                }
3706                if (doReport) {
3707                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3708                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3709                }
3710                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3711                    // The low memory report is overriding any current
3712                    // state for a GC request.  Make sure to do
3713                    // heavy/important/visible/foreground processes first.
3714                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3715                        rec.lastRequestedGc = 0;
3716                    } else {
3717                        rec.lastRequestedGc = rec.lastLowMemory;
3718                    }
3719                    rec.reportLowMemory = true;
3720                    rec.lastLowMemory = now;
3721                    mProcessesToGc.remove(rec);
3722                    addProcessToGcListLocked(rec);
3723                }
3724            }
3725            if (doReport) {
3726                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3727                mHandler.sendMessage(msg);
3728            }
3729            scheduleAppGcsLocked();
3730        }
3731    }
3732
3733    final void appDiedLocked(ProcessRecord app, int pid,
3734            IApplicationThread thread) {
3735
3736        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3737        synchronized (stats) {
3738            stats.noteProcessDiedLocked(app.info.uid, pid);
3739        }
3740
3741        // Clean up already done if the process has been re-started.
3742        if (app.pid == pid && app.thread != null &&
3743                app.thread.asBinder() == thread.asBinder()) {
3744            boolean doLowMem = app.instrumentationClass == null;
3745            boolean doOomAdj = doLowMem;
3746            if (!app.killedByAm) {
3747                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3748                        + ") has died.");
3749                mAllowLowerMemLevel = true;
3750            } else {
3751                // Note that we always want to do oom adj to update our state with the
3752                // new number of procs.
3753                mAllowLowerMemLevel = false;
3754                doLowMem = false;
3755            }
3756            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3757            if (DEBUG_CLEANUP) Slog.v(
3758                TAG, "Dying app: " + app + ", pid: " + pid
3759                + ", thread: " + thread.asBinder());
3760            handleAppDiedLocked(app, false, true);
3761
3762            if (doOomAdj) {
3763                updateOomAdjLocked();
3764            }
3765            if (doLowMem) {
3766                doLowMemReportIfNeededLocked(app);
3767            }
3768        } else if (app.pid != pid) {
3769            // A new process has already been started.
3770            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3771                    + ") has died and restarted (pid " + app.pid + ").");
3772            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3773        } else if (DEBUG_PROCESSES) {
3774            Slog.d(TAG, "Received spurious death notification for thread "
3775                    + thread.asBinder());
3776        }
3777    }
3778
3779    /**
3780     * If a stack trace dump file is configured, dump process stack traces.
3781     * @param clearTraces causes the dump file to be erased prior to the new
3782     *    traces being written, if true; when false, the new traces will be
3783     *    appended to any existing file content.
3784     * @param firstPids of dalvik VM processes to dump stack traces for first
3785     * @param lastPids of dalvik VM processes to dump stack traces for last
3786     * @param nativeProcs optional list of native process names to dump stack crawls
3787     * @return file containing stack traces, or null if no dump file is configured
3788     */
3789    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3790            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3791        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3792        if (tracesPath == null || tracesPath.length() == 0) {
3793            return null;
3794        }
3795
3796        File tracesFile = new File(tracesPath);
3797        try {
3798            File tracesDir = tracesFile.getParentFile();
3799            if (!tracesDir.exists()) {
3800                tracesFile.mkdirs();
3801                if (!SELinux.restorecon(tracesDir)) {
3802                    return null;
3803                }
3804            }
3805            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3806
3807            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3808            tracesFile.createNewFile();
3809            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3810        } catch (IOException e) {
3811            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3812            return null;
3813        }
3814
3815        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3816        return tracesFile;
3817    }
3818
3819    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3820            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3821        // Use a FileObserver to detect when traces finish writing.
3822        // The order of traces is considered important to maintain for legibility.
3823        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3824            @Override
3825            public synchronized void onEvent(int event, String path) { notify(); }
3826        };
3827
3828        try {
3829            observer.startWatching();
3830
3831            // First collect all of the stacks of the most important pids.
3832            if (firstPids != null) {
3833                try {
3834                    int num = firstPids.size();
3835                    for (int i = 0; i < num; i++) {
3836                        synchronized (observer) {
3837                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3838                            observer.wait(200);  // Wait for write-close, give up after 200msec
3839                        }
3840                    }
3841                } catch (InterruptedException e) {
3842                    Log.wtf(TAG, e);
3843                }
3844            }
3845
3846            // Next collect the stacks of the native pids
3847            if (nativeProcs != null) {
3848                int[] pids = Process.getPidsForCommands(nativeProcs);
3849                if (pids != null) {
3850                    for (int pid : pids) {
3851                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3852                    }
3853                }
3854            }
3855
3856            // Lastly, measure CPU usage.
3857            if (processCpuTracker != null) {
3858                processCpuTracker.init();
3859                System.gc();
3860                processCpuTracker.update();
3861                try {
3862                    synchronized (processCpuTracker) {
3863                        processCpuTracker.wait(500); // measure over 1/2 second.
3864                    }
3865                } catch (InterruptedException e) {
3866                }
3867                processCpuTracker.update();
3868
3869                // We'll take the stack crawls of just the top apps using CPU.
3870                final int N = processCpuTracker.countWorkingStats();
3871                int numProcs = 0;
3872                for (int i=0; i<N && numProcs<5; i++) {
3873                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3874                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3875                        numProcs++;
3876                        try {
3877                            synchronized (observer) {
3878                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3879                                observer.wait(200);  // Wait for write-close, give up after 200msec
3880                            }
3881                        } catch (InterruptedException e) {
3882                            Log.wtf(TAG, e);
3883                        }
3884
3885                    }
3886                }
3887            }
3888        } finally {
3889            observer.stopWatching();
3890        }
3891    }
3892
3893    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3894        if (true || IS_USER_BUILD) {
3895            return;
3896        }
3897        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3898        if (tracesPath == null || tracesPath.length() == 0) {
3899            return;
3900        }
3901
3902        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3903        StrictMode.allowThreadDiskWrites();
3904        try {
3905            final File tracesFile = new File(tracesPath);
3906            final File tracesDir = tracesFile.getParentFile();
3907            final File tracesTmp = new File(tracesDir, "__tmp__");
3908            try {
3909                if (!tracesDir.exists()) {
3910                    tracesFile.mkdirs();
3911                    if (!SELinux.restorecon(tracesDir.getPath())) {
3912                        return;
3913                    }
3914                }
3915                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3916
3917                if (tracesFile.exists()) {
3918                    tracesTmp.delete();
3919                    tracesFile.renameTo(tracesTmp);
3920                }
3921                StringBuilder sb = new StringBuilder();
3922                Time tobj = new Time();
3923                tobj.set(System.currentTimeMillis());
3924                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3925                sb.append(": ");
3926                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3927                sb.append(" since ");
3928                sb.append(msg);
3929                FileOutputStream fos = new FileOutputStream(tracesFile);
3930                fos.write(sb.toString().getBytes());
3931                if (app == null) {
3932                    fos.write("\n*** No application process!".getBytes());
3933                }
3934                fos.close();
3935                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3936            } catch (IOException e) {
3937                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3938                return;
3939            }
3940
3941            if (app != null) {
3942                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3943                firstPids.add(app.pid);
3944                dumpStackTraces(tracesPath, firstPids, null, null, null);
3945            }
3946
3947            File lastTracesFile = null;
3948            File curTracesFile = null;
3949            for (int i=9; i>=0; i--) {
3950                String name = String.format(Locale.US, "slow%02d.txt", i);
3951                curTracesFile = new File(tracesDir, name);
3952                if (curTracesFile.exists()) {
3953                    if (lastTracesFile != null) {
3954                        curTracesFile.renameTo(lastTracesFile);
3955                    } else {
3956                        curTracesFile.delete();
3957                    }
3958                }
3959                lastTracesFile = curTracesFile;
3960            }
3961            tracesFile.renameTo(curTracesFile);
3962            if (tracesTmp.exists()) {
3963                tracesTmp.renameTo(tracesFile);
3964            }
3965        } finally {
3966            StrictMode.setThreadPolicy(oldPolicy);
3967        }
3968    }
3969
3970    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3971            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3972        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3973        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3974
3975        if (mController != null) {
3976            try {
3977                // 0 == continue, -1 = kill process immediately
3978                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3979                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3980            } catch (RemoteException e) {
3981                mController = null;
3982                Watchdog.getInstance().setActivityController(null);
3983            }
3984        }
3985
3986        long anrTime = SystemClock.uptimeMillis();
3987        if (MONITOR_CPU_USAGE) {
3988            updateCpuStatsNow();
3989        }
3990
3991        synchronized (this) {
3992            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3993            if (mShuttingDown) {
3994                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3995                return;
3996            } else if (app.notResponding) {
3997                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3998                return;
3999            } else if (app.crashing) {
4000                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4001                return;
4002            }
4003
4004            // In case we come through here for the same app before completing
4005            // this one, mark as anring now so we will bail out.
4006            app.notResponding = true;
4007
4008            // Log the ANR to the event log.
4009            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4010                    app.processName, app.info.flags, annotation);
4011
4012            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4013            firstPids.add(app.pid);
4014
4015            int parentPid = app.pid;
4016            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4017            if (parentPid != app.pid) firstPids.add(parentPid);
4018
4019            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4020
4021            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4022                ProcessRecord r = mLruProcesses.get(i);
4023                if (r != null && r.thread != null) {
4024                    int pid = r.pid;
4025                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4026                        if (r.persistent) {
4027                            firstPids.add(pid);
4028                        } else {
4029                            lastPids.put(pid, Boolean.TRUE);
4030                        }
4031                    }
4032                }
4033            }
4034        }
4035
4036        // Log the ANR to the main log.
4037        StringBuilder info = new StringBuilder();
4038        info.setLength(0);
4039        info.append("ANR in ").append(app.processName);
4040        if (activity != null && activity.shortComponentName != null) {
4041            info.append(" (").append(activity.shortComponentName).append(")");
4042        }
4043        info.append("\n");
4044        info.append("PID: ").append(app.pid).append("\n");
4045        if (annotation != null) {
4046            info.append("Reason: ").append(annotation).append("\n");
4047        }
4048        if (parent != null && parent != activity) {
4049            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4050        }
4051
4052        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4053
4054        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4055                NATIVE_STACKS_OF_INTEREST);
4056
4057        String cpuInfo = null;
4058        if (MONITOR_CPU_USAGE) {
4059            updateCpuStatsNow();
4060            synchronized (mProcessCpuThread) {
4061                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4062            }
4063            info.append(processCpuTracker.printCurrentLoad());
4064            info.append(cpuInfo);
4065        }
4066
4067        info.append(processCpuTracker.printCurrentState(anrTime));
4068
4069        Slog.e(TAG, info.toString());
4070        if (tracesFile == null) {
4071            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4072            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4073        }
4074
4075        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4076                cpuInfo, tracesFile, null);
4077
4078        if (mController != null) {
4079            try {
4080                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4081                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4082                if (res != 0) {
4083                    if (res < 0 && app.pid != MY_PID) {
4084                        Process.killProcess(app.pid);
4085                    } else {
4086                        synchronized (this) {
4087                            mServices.scheduleServiceTimeoutLocked(app);
4088                        }
4089                    }
4090                    return;
4091                }
4092            } catch (RemoteException e) {
4093                mController = null;
4094                Watchdog.getInstance().setActivityController(null);
4095            }
4096        }
4097
4098        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4099        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4100                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4101
4102        synchronized (this) {
4103            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4104                killUnneededProcessLocked(app, "background ANR");
4105                return;
4106            }
4107
4108            // Set the app's notResponding state, and look up the errorReportReceiver
4109            makeAppNotRespondingLocked(app,
4110                    activity != null ? activity.shortComponentName : null,
4111                    annotation != null ? "ANR " + annotation : "ANR",
4112                    info.toString());
4113
4114            // Bring up the infamous App Not Responding dialog
4115            Message msg = Message.obtain();
4116            HashMap<String, Object> map = new HashMap<String, Object>();
4117            msg.what = SHOW_NOT_RESPONDING_MSG;
4118            msg.obj = map;
4119            msg.arg1 = aboveSystem ? 1 : 0;
4120            map.put("app", app);
4121            if (activity != null) {
4122                map.put("activity", activity);
4123            }
4124
4125            mHandler.sendMessage(msg);
4126        }
4127    }
4128
4129    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4130        if (!mLaunchWarningShown) {
4131            mLaunchWarningShown = true;
4132            mHandler.post(new Runnable() {
4133                @Override
4134                public void run() {
4135                    synchronized (ActivityManagerService.this) {
4136                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4137                        d.show();
4138                        mHandler.postDelayed(new Runnable() {
4139                            @Override
4140                            public void run() {
4141                                synchronized (ActivityManagerService.this) {
4142                                    d.dismiss();
4143                                    mLaunchWarningShown = false;
4144                                }
4145                            }
4146                        }, 4000);
4147                    }
4148                }
4149            });
4150        }
4151    }
4152
4153    @Override
4154    public boolean clearApplicationUserData(final String packageName,
4155            final IPackageDataObserver observer, int userId) {
4156        enforceNotIsolatedCaller("clearApplicationUserData");
4157        int uid = Binder.getCallingUid();
4158        int pid = Binder.getCallingPid();
4159        userId = handleIncomingUser(pid, uid,
4160                userId, false, true, "clearApplicationUserData", null);
4161        long callingId = Binder.clearCallingIdentity();
4162        try {
4163            IPackageManager pm = AppGlobals.getPackageManager();
4164            int pkgUid = -1;
4165            synchronized(this) {
4166                try {
4167                    pkgUid = pm.getPackageUid(packageName, userId);
4168                } catch (RemoteException e) {
4169                }
4170                if (pkgUid == -1) {
4171                    Slog.w(TAG, "Invalid packageName: " + packageName);
4172                    if (observer != null) {
4173                        try {
4174                            observer.onRemoveCompleted(packageName, false);
4175                        } catch (RemoteException e) {
4176                            Slog.i(TAG, "Observer no longer exists.");
4177                        }
4178                    }
4179                    return false;
4180                }
4181                if (uid == pkgUid || checkComponentPermission(
4182                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4183                        pid, uid, -1, true)
4184                        == PackageManager.PERMISSION_GRANTED) {
4185                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4186                } else {
4187                    throw new SecurityException("PID " + pid + " does not have permission "
4188                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4189                                    + " of package " + packageName);
4190                }
4191            }
4192
4193            try {
4194                // Clear application user data
4195                pm.clearApplicationUserData(packageName, observer, userId);
4196
4197                // Remove all permissions granted from/to this package
4198                removeUriPermissionsForPackageLocked(packageName, userId, true);
4199
4200                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4201                        Uri.fromParts("package", packageName, null));
4202                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4203                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4204                        null, null, 0, null, null, null, false, false, userId);
4205            } catch (RemoteException e) {
4206            }
4207        } finally {
4208            Binder.restoreCallingIdentity(callingId);
4209        }
4210        return true;
4211    }
4212
4213    @Override
4214    public void killBackgroundProcesses(final String packageName, int userId) {
4215        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4216                != PackageManager.PERMISSION_GRANTED &&
4217                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4218                        != PackageManager.PERMISSION_GRANTED) {
4219            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4220                    + Binder.getCallingPid()
4221                    + ", uid=" + Binder.getCallingUid()
4222                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4223            Slog.w(TAG, msg);
4224            throw new SecurityException(msg);
4225        }
4226
4227        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4228                userId, true, true, "killBackgroundProcesses", null);
4229        long callingId = Binder.clearCallingIdentity();
4230        try {
4231            IPackageManager pm = AppGlobals.getPackageManager();
4232            synchronized(this) {
4233                int appId = -1;
4234                try {
4235                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4236                } catch (RemoteException e) {
4237                }
4238                if (appId == -1) {
4239                    Slog.w(TAG, "Invalid packageName: " + packageName);
4240                    return;
4241                }
4242                killPackageProcessesLocked(packageName, appId, userId,
4243                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4244            }
4245        } finally {
4246            Binder.restoreCallingIdentity(callingId);
4247        }
4248    }
4249
4250    @Override
4251    public void killAllBackgroundProcesses() {
4252        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4253                != PackageManager.PERMISSION_GRANTED) {
4254            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4255                    + Binder.getCallingPid()
4256                    + ", uid=" + Binder.getCallingUid()
4257                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4258            Slog.w(TAG, msg);
4259            throw new SecurityException(msg);
4260        }
4261
4262        long callingId = Binder.clearCallingIdentity();
4263        try {
4264            synchronized(this) {
4265                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4266                final int NP = mProcessNames.getMap().size();
4267                for (int ip=0; ip<NP; ip++) {
4268                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4269                    final int NA = apps.size();
4270                    for (int ia=0; ia<NA; ia++) {
4271                        ProcessRecord app = apps.valueAt(ia);
4272                        if (app.persistent) {
4273                            // we don't kill persistent processes
4274                            continue;
4275                        }
4276                        if (app.removed) {
4277                            procs.add(app);
4278                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4279                            app.removed = true;
4280                            procs.add(app);
4281                        }
4282                    }
4283                }
4284
4285                int N = procs.size();
4286                for (int i=0; i<N; i++) {
4287                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4288                }
4289                mAllowLowerMemLevel = true;
4290                updateOomAdjLocked();
4291                doLowMemReportIfNeededLocked(null);
4292            }
4293        } finally {
4294            Binder.restoreCallingIdentity(callingId);
4295        }
4296    }
4297
4298    @Override
4299    public void forceStopPackage(final String packageName, int userId) {
4300        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4301                != PackageManager.PERMISSION_GRANTED) {
4302            String msg = "Permission Denial: forceStopPackage() from pid="
4303                    + Binder.getCallingPid()
4304                    + ", uid=" + Binder.getCallingUid()
4305                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4306            Slog.w(TAG, msg);
4307            throw new SecurityException(msg);
4308        }
4309        final int callingPid = Binder.getCallingPid();
4310        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4311                userId, true, true, "forceStopPackage", null);
4312        long callingId = Binder.clearCallingIdentity();
4313        try {
4314            IPackageManager pm = AppGlobals.getPackageManager();
4315            synchronized(this) {
4316                int[] users = userId == UserHandle.USER_ALL
4317                        ? getUsersLocked() : new int[] { userId };
4318                for (int user : users) {
4319                    int pkgUid = -1;
4320                    try {
4321                        pkgUid = pm.getPackageUid(packageName, user);
4322                    } catch (RemoteException e) {
4323                    }
4324                    if (pkgUid == -1) {
4325                        Slog.w(TAG, "Invalid packageName: " + packageName);
4326                        continue;
4327                    }
4328                    try {
4329                        pm.setPackageStoppedState(packageName, true, user);
4330                    } catch (RemoteException e) {
4331                    } catch (IllegalArgumentException e) {
4332                        Slog.w(TAG, "Failed trying to unstop package "
4333                                + packageName + ": " + e);
4334                    }
4335                    if (isUserRunningLocked(user, false)) {
4336                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4337                    }
4338                }
4339            }
4340        } finally {
4341            Binder.restoreCallingIdentity(callingId);
4342        }
4343    }
4344
4345    /*
4346     * The pkg name and app id have to be specified.
4347     */
4348    @Override
4349    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4350        if (pkg == null) {
4351            return;
4352        }
4353        // Make sure the uid is valid.
4354        if (appid < 0) {
4355            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4356            return;
4357        }
4358        int callerUid = Binder.getCallingUid();
4359        // Only the system server can kill an application
4360        if (callerUid == Process.SYSTEM_UID) {
4361            // Post an aysnc message to kill the application
4362            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4363            msg.arg1 = appid;
4364            msg.arg2 = 0;
4365            Bundle bundle = new Bundle();
4366            bundle.putString("pkg", pkg);
4367            bundle.putString("reason", reason);
4368            msg.obj = bundle;
4369            mHandler.sendMessage(msg);
4370        } else {
4371            throw new SecurityException(callerUid + " cannot kill pkg: " +
4372                    pkg);
4373        }
4374    }
4375
4376    @Override
4377    public void closeSystemDialogs(String reason) {
4378        enforceNotIsolatedCaller("closeSystemDialogs");
4379
4380        final int pid = Binder.getCallingPid();
4381        final int uid = Binder.getCallingUid();
4382        final long origId = Binder.clearCallingIdentity();
4383        try {
4384            synchronized (this) {
4385                // Only allow this from foreground processes, so that background
4386                // applications can't abuse it to prevent system UI from being shown.
4387                if (uid >= Process.FIRST_APPLICATION_UID) {
4388                    ProcessRecord proc;
4389                    synchronized (mPidsSelfLocked) {
4390                        proc = mPidsSelfLocked.get(pid);
4391                    }
4392                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4393                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4394                                + " from background process " + proc);
4395                        return;
4396                    }
4397                }
4398                closeSystemDialogsLocked(reason);
4399            }
4400        } finally {
4401            Binder.restoreCallingIdentity(origId);
4402        }
4403    }
4404
4405    void closeSystemDialogsLocked(String reason) {
4406        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4407        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4408                | Intent.FLAG_RECEIVER_FOREGROUND);
4409        if (reason != null) {
4410            intent.putExtra("reason", reason);
4411        }
4412        mWindowManager.closeSystemDialogs(reason);
4413
4414        mStackSupervisor.closeSystemDialogsLocked();
4415
4416        broadcastIntentLocked(null, null, intent, null,
4417                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4418                Process.SYSTEM_UID, UserHandle.USER_ALL);
4419    }
4420
4421    @Override
4422    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4423        enforceNotIsolatedCaller("getProcessMemoryInfo");
4424        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4425        for (int i=pids.length-1; i>=0; i--) {
4426            ProcessRecord proc;
4427            int oomAdj;
4428            synchronized (this) {
4429                synchronized (mPidsSelfLocked) {
4430                    proc = mPidsSelfLocked.get(pids[i]);
4431                    oomAdj = proc != null ? proc.setAdj : 0;
4432                }
4433            }
4434            infos[i] = new Debug.MemoryInfo();
4435            Debug.getMemoryInfo(pids[i], infos[i]);
4436            if (proc != null) {
4437                synchronized (this) {
4438                    if (proc.thread != null && proc.setAdj == oomAdj) {
4439                        // Record this for posterity if the process has been stable.
4440                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4441                                infos[i].getTotalUss(), false, proc.pkgList);
4442                    }
4443                }
4444            }
4445        }
4446        return infos;
4447    }
4448
4449    @Override
4450    public long[] getProcessPss(int[] pids) {
4451        enforceNotIsolatedCaller("getProcessPss");
4452        long[] pss = new long[pids.length];
4453        for (int i=pids.length-1; i>=0; i--) {
4454            ProcessRecord proc;
4455            int oomAdj;
4456            synchronized (this) {
4457                synchronized (mPidsSelfLocked) {
4458                    proc = mPidsSelfLocked.get(pids[i]);
4459                    oomAdj = proc != null ? proc.setAdj : 0;
4460                }
4461            }
4462            long[] tmpUss = new long[1];
4463            pss[i] = Debug.getPss(pids[i], tmpUss);
4464            if (proc != null) {
4465                synchronized (this) {
4466                    if (proc.thread != null && proc.setAdj == oomAdj) {
4467                        // Record this for posterity if the process has been stable.
4468                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4469                    }
4470                }
4471            }
4472        }
4473        return pss;
4474    }
4475
4476    @Override
4477    public void killApplicationProcess(String processName, int uid) {
4478        if (processName == null) {
4479            return;
4480        }
4481
4482        int callerUid = Binder.getCallingUid();
4483        // Only the system server can kill an application
4484        if (callerUid == Process.SYSTEM_UID) {
4485            synchronized (this) {
4486                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4487                if (app != null && app.thread != null) {
4488                    try {
4489                        app.thread.scheduleSuicide();
4490                    } catch (RemoteException e) {
4491                        // If the other end already died, then our work here is done.
4492                    }
4493                } else {
4494                    Slog.w(TAG, "Process/uid not found attempting kill of "
4495                            + processName + " / " + uid);
4496                }
4497            }
4498        } else {
4499            throw new SecurityException(callerUid + " cannot kill app process: " +
4500                    processName);
4501        }
4502    }
4503
4504    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4505        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4506                false, true, false, false, UserHandle.getUserId(uid), reason);
4507        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4508                Uri.fromParts("package", packageName, null));
4509        if (!mProcessesReady) {
4510            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4511                    | Intent.FLAG_RECEIVER_FOREGROUND);
4512        }
4513        intent.putExtra(Intent.EXTRA_UID, uid);
4514        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4515        broadcastIntentLocked(null, null, intent,
4516                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4517                false, false,
4518                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4519    }
4520
4521    private void forceStopUserLocked(int userId, String reason) {
4522        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4523        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4524        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4525                | Intent.FLAG_RECEIVER_FOREGROUND);
4526        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4527        broadcastIntentLocked(null, null, intent,
4528                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4529                false, false,
4530                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4531    }
4532
4533    private final boolean killPackageProcessesLocked(String packageName, int appId,
4534            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4535            boolean doit, boolean evenPersistent, String reason) {
4536        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4537
4538        // Remove all processes this package may have touched: all with the
4539        // same UID (except for the system or root user), and all whose name
4540        // matches the package name.
4541        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4542        final int NP = mProcessNames.getMap().size();
4543        for (int ip=0; ip<NP; ip++) {
4544            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4545            final int NA = apps.size();
4546            for (int ia=0; ia<NA; ia++) {
4547                ProcessRecord app = apps.valueAt(ia);
4548                if (app.persistent && !evenPersistent) {
4549                    // we don't kill persistent processes
4550                    continue;
4551                }
4552                if (app.removed) {
4553                    if (doit) {
4554                        procs.add(app);
4555                    }
4556                    continue;
4557                }
4558
4559                // Skip process if it doesn't meet our oom adj requirement.
4560                if (app.setAdj < minOomAdj) {
4561                    continue;
4562                }
4563
4564                // If no package is specified, we call all processes under the
4565                // give user id.
4566                if (packageName == null) {
4567                    if (app.userId != userId) {
4568                        continue;
4569                    }
4570                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4571                        continue;
4572                    }
4573                // Package has been specified, we want to hit all processes
4574                // that match it.  We need to qualify this by the processes
4575                // that are running under the specified app and user ID.
4576                } else {
4577                    if (UserHandle.getAppId(app.uid) != appId) {
4578                        continue;
4579                    }
4580                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4581                        continue;
4582                    }
4583                    if (!app.pkgList.containsKey(packageName)) {
4584                        continue;
4585                    }
4586                }
4587
4588                // Process has passed all conditions, kill it!
4589                if (!doit) {
4590                    return true;
4591                }
4592                app.removed = true;
4593                procs.add(app);
4594            }
4595        }
4596
4597        int N = procs.size();
4598        for (int i=0; i<N; i++) {
4599            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4600        }
4601        updateOomAdjLocked();
4602        return N > 0;
4603    }
4604
4605    private final boolean forceStopPackageLocked(String name, int appId,
4606            boolean callerWillRestart, boolean purgeCache, boolean doit,
4607            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4608        int i;
4609        int N;
4610
4611        if (userId == UserHandle.USER_ALL && name == null) {
4612            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4613        }
4614
4615        if (appId < 0 && name != null) {
4616            try {
4617                appId = UserHandle.getAppId(
4618                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4619            } catch (RemoteException e) {
4620            }
4621        }
4622
4623        if (doit) {
4624            if (name != null) {
4625                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4626                        + " user=" + userId + ": " + reason);
4627            } else {
4628                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4629            }
4630
4631            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4632            for (int ip=pmap.size()-1; ip>=0; ip--) {
4633                SparseArray<Long> ba = pmap.valueAt(ip);
4634                for (i=ba.size()-1; i>=0; i--) {
4635                    boolean remove = false;
4636                    final int entUid = ba.keyAt(i);
4637                    if (name != null) {
4638                        if (userId == UserHandle.USER_ALL) {
4639                            if (UserHandle.getAppId(entUid) == appId) {
4640                                remove = true;
4641                            }
4642                        } else {
4643                            if (entUid == UserHandle.getUid(userId, appId)) {
4644                                remove = true;
4645                            }
4646                        }
4647                    } else if (UserHandle.getUserId(entUid) == userId) {
4648                        remove = true;
4649                    }
4650                    if (remove) {
4651                        ba.removeAt(i);
4652                    }
4653                }
4654                if (ba.size() == 0) {
4655                    pmap.removeAt(ip);
4656                }
4657            }
4658        }
4659
4660        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4661                -100, callerWillRestart, true, doit, evenPersistent,
4662                name == null ? ("stop user " + userId) : ("stop " + name));
4663
4664        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4665            if (!doit) {
4666                return true;
4667            }
4668            didSomething = true;
4669        }
4670
4671        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4672            if (!doit) {
4673                return true;
4674            }
4675            didSomething = true;
4676        }
4677
4678        if (name == null) {
4679            // Remove all sticky broadcasts from this user.
4680            mStickyBroadcasts.remove(userId);
4681        }
4682
4683        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4684        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4685                userId, providers)) {
4686            if (!doit) {
4687                return true;
4688            }
4689            didSomething = true;
4690        }
4691        N = providers.size();
4692        for (i=0; i<N; i++) {
4693            removeDyingProviderLocked(null, providers.get(i), true);
4694        }
4695
4696        // Remove transient permissions granted from/to this package/user
4697        removeUriPermissionsForPackageLocked(name, userId, false);
4698
4699        if (name == null || uninstalling) {
4700            // Remove pending intents.  For now we only do this when force
4701            // stopping users, because we have some problems when doing this
4702            // for packages -- app widgets are not currently cleaned up for
4703            // such packages, so they can be left with bad pending intents.
4704            if (mIntentSenderRecords.size() > 0) {
4705                Iterator<WeakReference<PendingIntentRecord>> it
4706                        = mIntentSenderRecords.values().iterator();
4707                while (it.hasNext()) {
4708                    WeakReference<PendingIntentRecord> wpir = it.next();
4709                    if (wpir == null) {
4710                        it.remove();
4711                        continue;
4712                    }
4713                    PendingIntentRecord pir = wpir.get();
4714                    if (pir == null) {
4715                        it.remove();
4716                        continue;
4717                    }
4718                    if (name == null) {
4719                        // Stopping user, remove all objects for the user.
4720                        if (pir.key.userId != userId) {
4721                            // Not the same user, skip it.
4722                            continue;
4723                        }
4724                    } else {
4725                        if (UserHandle.getAppId(pir.uid) != appId) {
4726                            // Different app id, skip it.
4727                            continue;
4728                        }
4729                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4730                            // Different user, skip it.
4731                            continue;
4732                        }
4733                        if (!pir.key.packageName.equals(name)) {
4734                            // Different package, skip it.
4735                            continue;
4736                        }
4737                    }
4738                    if (!doit) {
4739                        return true;
4740                    }
4741                    didSomething = true;
4742                    it.remove();
4743                    pir.canceled = true;
4744                    if (pir.key.activity != null) {
4745                        pir.key.activity.pendingResults.remove(pir.ref);
4746                    }
4747                }
4748            }
4749        }
4750
4751        if (doit) {
4752            if (purgeCache && name != null) {
4753                AttributeCache ac = AttributeCache.instance();
4754                if (ac != null) {
4755                    ac.removePackage(name);
4756                }
4757            }
4758            if (mBooted) {
4759                mStackSupervisor.resumeTopActivitiesLocked();
4760                mStackSupervisor.scheduleIdleLocked();
4761            }
4762        }
4763
4764        return didSomething;
4765    }
4766
4767    private final boolean removeProcessLocked(ProcessRecord app,
4768            boolean callerWillRestart, boolean allowRestart, String reason) {
4769        final String name = app.processName;
4770        final int uid = app.uid;
4771        if (DEBUG_PROCESSES) Slog.d(
4772            TAG, "Force removing proc " + app.toShortString() + " (" + name
4773            + "/" + uid + ")");
4774
4775        mProcessNames.remove(name, uid);
4776        mIsolatedProcesses.remove(app.uid);
4777        if (mHeavyWeightProcess == app) {
4778            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4779                    mHeavyWeightProcess.userId, 0));
4780            mHeavyWeightProcess = null;
4781        }
4782        boolean needRestart = false;
4783        if (app.pid > 0 && app.pid != MY_PID) {
4784            int pid = app.pid;
4785            synchronized (mPidsSelfLocked) {
4786                mPidsSelfLocked.remove(pid);
4787                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4788            }
4789            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4790                    app.processName, app.info.uid);
4791            if (app.isolated) {
4792                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4793            }
4794            killUnneededProcessLocked(app, reason);
4795            handleAppDiedLocked(app, true, allowRestart);
4796            removeLruProcessLocked(app);
4797
4798            if (app.persistent && !app.isolated) {
4799                if (!callerWillRestart) {
4800                    addAppLocked(app.info, false);
4801                } else {
4802                    needRestart = true;
4803                }
4804            }
4805        } else {
4806            mRemovedProcesses.add(app);
4807        }
4808
4809        return needRestart;
4810    }
4811
4812    private final void processStartTimedOutLocked(ProcessRecord app) {
4813        final int pid = app.pid;
4814        boolean gone = false;
4815        synchronized (mPidsSelfLocked) {
4816            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4817            if (knownApp != null && knownApp.thread == null) {
4818                mPidsSelfLocked.remove(pid);
4819                gone = true;
4820            }
4821        }
4822
4823        if (gone) {
4824            Slog.w(TAG, "Process " + app + " failed to attach");
4825            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4826                    pid, app.uid, app.processName);
4827            mProcessNames.remove(app.processName, app.uid);
4828            mIsolatedProcesses.remove(app.uid);
4829            if (mHeavyWeightProcess == app) {
4830                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4831                        mHeavyWeightProcess.userId, 0));
4832                mHeavyWeightProcess = null;
4833            }
4834            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4835                    app.processName, app.info.uid);
4836            if (app.isolated) {
4837                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4838            }
4839            // Take care of any launching providers waiting for this process.
4840            checkAppInLaunchingProvidersLocked(app, true);
4841            // Take care of any services that are waiting for the process.
4842            mServices.processStartTimedOutLocked(app);
4843            killUnneededProcessLocked(app, "start timeout");
4844            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4845                Slog.w(TAG, "Unattached app died before backup, skipping");
4846                try {
4847                    IBackupManager bm = IBackupManager.Stub.asInterface(
4848                            ServiceManager.getService(Context.BACKUP_SERVICE));
4849                    bm.agentDisconnected(app.info.packageName);
4850                } catch (RemoteException e) {
4851                    // Can't happen; the backup manager is local
4852                }
4853            }
4854            if (isPendingBroadcastProcessLocked(pid)) {
4855                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4856                skipPendingBroadcastLocked(pid);
4857            }
4858        } else {
4859            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4860        }
4861    }
4862
4863    private final boolean attachApplicationLocked(IApplicationThread thread,
4864            int pid) {
4865
4866        // Find the application record that is being attached...  either via
4867        // the pid if we are running in multiple processes, or just pull the
4868        // next app record if we are emulating process with anonymous threads.
4869        ProcessRecord app;
4870        if (pid != MY_PID && pid >= 0) {
4871            synchronized (mPidsSelfLocked) {
4872                app = mPidsSelfLocked.get(pid);
4873            }
4874        } else {
4875            app = null;
4876        }
4877
4878        if (app == null) {
4879            Slog.w(TAG, "No pending application record for pid " + pid
4880                    + " (IApplicationThread " + thread + "); dropping process");
4881            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4882            if (pid > 0 && pid != MY_PID) {
4883                Process.killProcessQuiet(pid);
4884            } else {
4885                try {
4886                    thread.scheduleExit();
4887                } catch (Exception e) {
4888                    // Ignore exceptions.
4889                }
4890            }
4891            return false;
4892        }
4893
4894        // If this application record is still attached to a previous
4895        // process, clean it up now.
4896        if (app.thread != null) {
4897            handleAppDiedLocked(app, true, true);
4898        }
4899
4900        // Tell the process all about itself.
4901
4902        if (localLOGV) Slog.v(
4903                TAG, "Binding process pid " + pid + " to record " + app);
4904
4905        final String processName = app.processName;
4906        try {
4907            AppDeathRecipient adr = new AppDeathRecipient(
4908                    app, pid, thread);
4909            thread.asBinder().linkToDeath(adr, 0);
4910            app.deathRecipient = adr;
4911        } catch (RemoteException e) {
4912            app.resetPackageList(mProcessStats);
4913            startProcessLocked(app, "link fail", processName);
4914            return false;
4915        }
4916
4917        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4918
4919        app.makeActive(thread, mProcessStats);
4920        app.curAdj = app.setAdj = -100;
4921        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4922        app.forcingToForeground = null;
4923        updateProcessForegroundLocked(app, false, false);
4924        app.hasShownUi = false;
4925        app.debugging = false;
4926        app.cached = false;
4927
4928        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4929
4930        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4931        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4932
4933        if (!normalMode) {
4934            Slog.i(TAG, "Launching preboot mode app: " + app);
4935        }
4936
4937        if (localLOGV) Slog.v(
4938            TAG, "New app record " + app
4939            + " thread=" + thread.asBinder() + " pid=" + pid);
4940        try {
4941            int testMode = IApplicationThread.DEBUG_OFF;
4942            if (mDebugApp != null && mDebugApp.equals(processName)) {
4943                testMode = mWaitForDebugger
4944                    ? IApplicationThread.DEBUG_WAIT
4945                    : IApplicationThread.DEBUG_ON;
4946                app.debugging = true;
4947                if (mDebugTransient) {
4948                    mDebugApp = mOrigDebugApp;
4949                    mWaitForDebugger = mOrigWaitForDebugger;
4950                }
4951            }
4952            String profileFile = app.instrumentationProfileFile;
4953            ParcelFileDescriptor profileFd = null;
4954            boolean profileAutoStop = false;
4955            if (mProfileApp != null && mProfileApp.equals(processName)) {
4956                mProfileProc = app;
4957                profileFile = mProfileFile;
4958                profileFd = mProfileFd;
4959                profileAutoStop = mAutoStopProfiler;
4960            }
4961            boolean enableOpenGlTrace = false;
4962            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4963                enableOpenGlTrace = true;
4964                mOpenGlTraceApp = null;
4965            }
4966
4967            // If the app is being launched for restore or full backup, set it up specially
4968            boolean isRestrictedBackupMode = false;
4969            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4970                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4971                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4972                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4973            }
4974
4975            ensurePackageDexOpt(app.instrumentationInfo != null
4976                    ? app.instrumentationInfo.packageName
4977                    : app.info.packageName);
4978            if (app.instrumentationClass != null) {
4979                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4980            }
4981            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4982                    + processName + " with config " + mConfiguration);
4983            ApplicationInfo appInfo = app.instrumentationInfo != null
4984                    ? app.instrumentationInfo : app.info;
4985            app.compat = compatibilityInfoForPackageLocked(appInfo);
4986            if (profileFd != null) {
4987                profileFd = profileFd.dup();
4988            }
4989            thread.bindApplication(processName, appInfo, providers,
4990                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4991                    app.instrumentationArguments, app.instrumentationWatcher,
4992                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4993                    isRestrictedBackupMode || !normalMode, app.persistent,
4994                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4995                    mCoreSettingsObserver.getCoreSettingsLocked());
4996            updateLruProcessLocked(app, false, null);
4997            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4998        } catch (Exception e) {
4999            // todo: Yikes!  What should we do?  For now we will try to
5000            // start another process, but that could easily get us in
5001            // an infinite loop of restarting processes...
5002            Slog.w(TAG, "Exception thrown during bind!", e);
5003
5004            app.resetPackageList(mProcessStats);
5005            app.unlinkDeathRecipient();
5006            startProcessLocked(app, "bind fail", processName);
5007            return false;
5008        }
5009
5010        // Remove this record from the list of starting applications.
5011        mPersistentStartingProcesses.remove(app);
5012        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5013                "Attach application locked removing on hold: " + app);
5014        mProcessesOnHold.remove(app);
5015
5016        boolean badApp = false;
5017        boolean didSomething = false;
5018
5019        // See if the top visible activity is waiting to run in this process...
5020        if (normalMode) {
5021            try {
5022                if (mStackSupervisor.attachApplicationLocked(app)) {
5023                    didSomething = true;
5024                }
5025            } catch (Exception e) {
5026                badApp = true;
5027            }
5028        }
5029
5030        // Find any services that should be running in this process...
5031        if (!badApp) {
5032            try {
5033                didSomething |= mServices.attachApplicationLocked(app, processName);
5034            } catch (Exception e) {
5035                badApp = true;
5036            }
5037        }
5038
5039        // Check if a next-broadcast receiver is in this process...
5040        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5041            try {
5042                didSomething |= sendPendingBroadcastsLocked(app);
5043            } catch (Exception e) {
5044                // If the app died trying to launch the receiver we declare it 'bad'
5045                badApp = true;
5046            }
5047        }
5048
5049        // Check whether the next backup agent is in this process...
5050        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5051            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5052            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5053            try {
5054                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5055                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5056                        mBackupTarget.backupMode);
5057            } catch (Exception e) {
5058                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5059                e.printStackTrace();
5060            }
5061        }
5062
5063        if (badApp) {
5064            // todo: Also need to kill application to deal with all
5065            // kinds of exceptions.
5066            handleAppDiedLocked(app, false, true);
5067            return false;
5068        }
5069
5070        if (!didSomething) {
5071            updateOomAdjLocked();
5072        }
5073
5074        return true;
5075    }
5076
5077    @Override
5078    public final void attachApplication(IApplicationThread thread) {
5079        synchronized (this) {
5080            int callingPid = Binder.getCallingPid();
5081            final long origId = Binder.clearCallingIdentity();
5082            attachApplicationLocked(thread, callingPid);
5083            Binder.restoreCallingIdentity(origId);
5084        }
5085    }
5086
5087    @Override
5088    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5089        final long origId = Binder.clearCallingIdentity();
5090        synchronized (this) {
5091            ActivityStack stack = ActivityRecord.getStackLocked(token);
5092            if (stack != null) {
5093                ActivityRecord r =
5094                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5095                if (stopProfiling) {
5096                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5097                        try {
5098                            mProfileFd.close();
5099                        } catch (IOException e) {
5100                        }
5101                        clearProfilerLocked();
5102                    }
5103                }
5104            }
5105        }
5106        Binder.restoreCallingIdentity(origId);
5107    }
5108
5109    void enableScreenAfterBoot() {
5110        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5111                SystemClock.uptimeMillis());
5112        mWindowManager.enableScreenAfterBoot();
5113
5114        synchronized (this) {
5115            updateEventDispatchingLocked();
5116        }
5117    }
5118
5119    @Override
5120    public void showBootMessage(final CharSequence msg, final boolean always) {
5121        enforceNotIsolatedCaller("showBootMessage");
5122        mWindowManager.showBootMessage(msg, always);
5123    }
5124
5125    @Override
5126    public void dismissKeyguardOnNextActivity() {
5127        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5128        final long token = Binder.clearCallingIdentity();
5129        try {
5130            synchronized (this) {
5131                if (DEBUG_LOCKSCREEN) logLockScreen("");
5132                if (mLockScreenShown) {
5133                    mLockScreenShown = false;
5134                    comeOutOfSleepIfNeededLocked();
5135                }
5136                mStackSupervisor.setDismissKeyguard(true);
5137            }
5138        } finally {
5139            Binder.restoreCallingIdentity(token);
5140        }
5141    }
5142
5143    final void finishBooting() {
5144        IntentFilter pkgFilter = new IntentFilter();
5145        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5146        pkgFilter.addDataScheme("package");
5147        mContext.registerReceiver(new BroadcastReceiver() {
5148            @Override
5149            public void onReceive(Context context, Intent intent) {
5150                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5151                if (pkgs != null) {
5152                    for (String pkg : pkgs) {
5153                        synchronized (ActivityManagerService.this) {
5154                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5155                                    "finished booting")) {
5156                                setResultCode(Activity.RESULT_OK);
5157                                return;
5158                            }
5159                        }
5160                    }
5161                }
5162            }
5163        }, pkgFilter);
5164
5165        synchronized (this) {
5166            // Ensure that any processes we had put on hold are now started
5167            // up.
5168            final int NP = mProcessesOnHold.size();
5169            if (NP > 0) {
5170                ArrayList<ProcessRecord> procs =
5171                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5172                for (int ip=0; ip<NP; ip++) {
5173                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5174                            + procs.get(ip));
5175                    startProcessLocked(procs.get(ip), "on-hold", null);
5176                }
5177            }
5178
5179            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5180                // Start looking for apps that are abusing wake locks.
5181                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5182                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5183                // Tell anyone interested that we are done booting!
5184                SystemProperties.set("sys.boot_completed", "1");
5185                SystemProperties.set("dev.bootcomplete", "1");
5186                for (int i=0; i<mStartedUsers.size(); i++) {
5187                    UserStartedState uss = mStartedUsers.valueAt(i);
5188                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5189                        uss.mState = UserStartedState.STATE_RUNNING;
5190                        final int userId = mStartedUsers.keyAt(i);
5191                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5192                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5193                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5194                        broadcastIntentLocked(null, null, intent, null,
5195                                new IIntentReceiver.Stub() {
5196                                    @Override
5197                                    public void performReceive(Intent intent, int resultCode,
5198                                            String data, Bundle extras, boolean ordered,
5199                                            boolean sticky, int sendingUser) {
5200                                        synchronized (ActivityManagerService.this) {
5201                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5202                                                    true, false);
5203                                        }
5204                                    }
5205                                },
5206                                0, null, null,
5207                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5208                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5209                                userId);
5210                    }
5211                }
5212                scheduleStartProfilesLocked();
5213            }
5214        }
5215    }
5216
5217    final void ensureBootCompleted() {
5218        boolean booting;
5219        boolean enableScreen;
5220        synchronized (this) {
5221            booting = mBooting;
5222            mBooting = false;
5223            enableScreen = !mBooted;
5224            mBooted = true;
5225        }
5226
5227        if (booting) {
5228            finishBooting();
5229        }
5230
5231        if (enableScreen) {
5232            enableScreenAfterBoot();
5233        }
5234    }
5235
5236    @Override
5237    public final void activityResumed(IBinder token) {
5238        final long origId = Binder.clearCallingIdentity();
5239        synchronized(this) {
5240            ActivityStack stack = ActivityRecord.getStackLocked(token);
5241            if (stack != null) {
5242                ActivityRecord.activityResumedLocked(token);
5243            }
5244        }
5245        Binder.restoreCallingIdentity(origId);
5246    }
5247
5248    @Override
5249    public final void activityPaused(IBinder token) {
5250        final long origId = Binder.clearCallingIdentity();
5251        synchronized(this) {
5252            ActivityStack stack = ActivityRecord.getStackLocked(token);
5253            if (stack != null) {
5254                stack.activityPausedLocked(token, false);
5255            }
5256        }
5257        Binder.restoreCallingIdentity(origId);
5258    }
5259
5260    @Override
5261    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5262            CharSequence description) {
5263        if (localLOGV) Slog.v(
5264            TAG, "Activity stopped: token=" + token);
5265
5266        // Refuse possible leaked file descriptors
5267        if (icicle != null && icicle.hasFileDescriptors()) {
5268            throw new IllegalArgumentException("File descriptors passed in Bundle");
5269        }
5270
5271        ActivityRecord r = null;
5272
5273        final long origId = Binder.clearCallingIdentity();
5274
5275        synchronized (this) {
5276            r = ActivityRecord.isInStackLocked(token);
5277            if (r != null) {
5278                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5279            }
5280        }
5281
5282        if (r != null) {
5283            sendPendingThumbnail(r, null, null, null, false);
5284        }
5285
5286        trimApplications();
5287
5288        Binder.restoreCallingIdentity(origId);
5289    }
5290
5291    @Override
5292    public final void activityDestroyed(IBinder token) {
5293        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5294        synchronized (this) {
5295            ActivityStack stack = ActivityRecord.getStackLocked(token);
5296            if (stack != null) {
5297                stack.activityDestroyedLocked(token);
5298            }
5299        }
5300    }
5301
5302    @Override
5303    public String getCallingPackage(IBinder token) {
5304        synchronized (this) {
5305            ActivityRecord r = getCallingRecordLocked(token);
5306            return r != null ? r.info.packageName : null;
5307        }
5308    }
5309
5310    @Override
5311    public ComponentName getCallingActivity(IBinder token) {
5312        synchronized (this) {
5313            ActivityRecord r = getCallingRecordLocked(token);
5314            return r != null ? r.intent.getComponent() : null;
5315        }
5316    }
5317
5318    private ActivityRecord getCallingRecordLocked(IBinder token) {
5319        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5320        if (r == null) {
5321            return null;
5322        }
5323        return r.resultTo;
5324    }
5325
5326    @Override
5327    public ComponentName getActivityClassForToken(IBinder token) {
5328        synchronized(this) {
5329            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5330            if (r == null) {
5331                return null;
5332            }
5333            return r.intent.getComponent();
5334        }
5335    }
5336
5337    @Override
5338    public String getPackageForToken(IBinder token) {
5339        synchronized(this) {
5340            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5341            if (r == null) {
5342                return null;
5343            }
5344            return r.packageName;
5345        }
5346    }
5347
5348    @Override
5349    public IIntentSender getIntentSender(int type,
5350            String packageName, IBinder token, String resultWho,
5351            int requestCode, Intent[] intents, String[] resolvedTypes,
5352            int flags, Bundle options, int userId) {
5353        enforceNotIsolatedCaller("getIntentSender");
5354        // Refuse possible leaked file descriptors
5355        if (intents != null) {
5356            if (intents.length < 1) {
5357                throw new IllegalArgumentException("Intents array length must be >= 1");
5358            }
5359            for (int i=0; i<intents.length; i++) {
5360                Intent intent = intents[i];
5361                if (intent != null) {
5362                    if (intent.hasFileDescriptors()) {
5363                        throw new IllegalArgumentException("File descriptors passed in Intent");
5364                    }
5365                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5366                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5367                        throw new IllegalArgumentException(
5368                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5369                    }
5370                    intents[i] = new Intent(intent);
5371                }
5372            }
5373            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5374                throw new IllegalArgumentException(
5375                        "Intent array length does not match resolvedTypes length");
5376            }
5377        }
5378        if (options != null) {
5379            if (options.hasFileDescriptors()) {
5380                throw new IllegalArgumentException("File descriptors passed in options");
5381            }
5382        }
5383
5384        synchronized(this) {
5385            int callingUid = Binder.getCallingUid();
5386            int origUserId = userId;
5387            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5388                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5389                    "getIntentSender", null);
5390            if (origUserId == UserHandle.USER_CURRENT) {
5391                // We don't want to evaluate this until the pending intent is
5392                // actually executed.  However, we do want to always do the
5393                // security checking for it above.
5394                userId = UserHandle.USER_CURRENT;
5395            }
5396            try {
5397                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5398                    int uid = AppGlobals.getPackageManager()
5399                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5400                    if (!UserHandle.isSameApp(callingUid, uid)) {
5401                        String msg = "Permission Denial: getIntentSender() from pid="
5402                            + Binder.getCallingPid()
5403                            + ", uid=" + Binder.getCallingUid()
5404                            + ", (need uid=" + uid + ")"
5405                            + " is not allowed to send as package " + packageName;
5406                        Slog.w(TAG, msg);
5407                        throw new SecurityException(msg);
5408                    }
5409                }
5410
5411                return getIntentSenderLocked(type, packageName, callingUid, userId,
5412                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5413
5414            } catch (RemoteException e) {
5415                throw new SecurityException(e);
5416            }
5417        }
5418    }
5419
5420    IIntentSender getIntentSenderLocked(int type, String packageName,
5421            int callingUid, int userId, IBinder token, String resultWho,
5422            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5423            Bundle options) {
5424        if (DEBUG_MU)
5425            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5426        ActivityRecord activity = null;
5427        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5428            activity = ActivityRecord.isInStackLocked(token);
5429            if (activity == null) {
5430                return null;
5431            }
5432            if (activity.finishing) {
5433                return null;
5434            }
5435        }
5436
5437        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5438        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5439        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5440        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5441                |PendingIntent.FLAG_UPDATE_CURRENT);
5442
5443        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5444                type, packageName, activity, resultWho,
5445                requestCode, intents, resolvedTypes, flags, options, userId);
5446        WeakReference<PendingIntentRecord> ref;
5447        ref = mIntentSenderRecords.get(key);
5448        PendingIntentRecord rec = ref != null ? ref.get() : null;
5449        if (rec != null) {
5450            if (!cancelCurrent) {
5451                if (updateCurrent) {
5452                    if (rec.key.requestIntent != null) {
5453                        rec.key.requestIntent.replaceExtras(intents != null ?
5454                                intents[intents.length - 1] : null);
5455                    }
5456                    if (intents != null) {
5457                        intents[intents.length-1] = rec.key.requestIntent;
5458                        rec.key.allIntents = intents;
5459                        rec.key.allResolvedTypes = resolvedTypes;
5460                    } else {
5461                        rec.key.allIntents = null;
5462                        rec.key.allResolvedTypes = null;
5463                    }
5464                }
5465                return rec;
5466            }
5467            rec.canceled = true;
5468            mIntentSenderRecords.remove(key);
5469        }
5470        if (noCreate) {
5471            return rec;
5472        }
5473        rec = new PendingIntentRecord(this, key, callingUid);
5474        mIntentSenderRecords.put(key, rec.ref);
5475        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5476            if (activity.pendingResults == null) {
5477                activity.pendingResults
5478                        = new HashSet<WeakReference<PendingIntentRecord>>();
5479            }
5480            activity.pendingResults.add(rec.ref);
5481        }
5482        return rec;
5483    }
5484
5485    @Override
5486    public void cancelIntentSender(IIntentSender sender) {
5487        if (!(sender instanceof PendingIntentRecord)) {
5488            return;
5489        }
5490        synchronized(this) {
5491            PendingIntentRecord rec = (PendingIntentRecord)sender;
5492            try {
5493                int uid = AppGlobals.getPackageManager()
5494                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5495                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5496                    String msg = "Permission Denial: cancelIntentSender() from pid="
5497                        + Binder.getCallingPid()
5498                        + ", uid=" + Binder.getCallingUid()
5499                        + " is not allowed to cancel packges "
5500                        + rec.key.packageName;
5501                    Slog.w(TAG, msg);
5502                    throw new SecurityException(msg);
5503                }
5504            } catch (RemoteException e) {
5505                throw new SecurityException(e);
5506            }
5507            cancelIntentSenderLocked(rec, true);
5508        }
5509    }
5510
5511    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5512        rec.canceled = true;
5513        mIntentSenderRecords.remove(rec.key);
5514        if (cleanActivity && rec.key.activity != null) {
5515            rec.key.activity.pendingResults.remove(rec.ref);
5516        }
5517    }
5518
5519    @Override
5520    public String getPackageForIntentSender(IIntentSender pendingResult) {
5521        if (!(pendingResult instanceof PendingIntentRecord)) {
5522            return null;
5523        }
5524        try {
5525            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5526            return res.key.packageName;
5527        } catch (ClassCastException e) {
5528        }
5529        return null;
5530    }
5531
5532    @Override
5533    public int getUidForIntentSender(IIntentSender sender) {
5534        if (sender instanceof PendingIntentRecord) {
5535            try {
5536                PendingIntentRecord res = (PendingIntentRecord)sender;
5537                return res.uid;
5538            } catch (ClassCastException e) {
5539            }
5540        }
5541        return -1;
5542    }
5543
5544    @Override
5545    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5546        if (!(pendingResult instanceof PendingIntentRecord)) {
5547            return false;
5548        }
5549        try {
5550            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5551            if (res.key.allIntents == null) {
5552                return false;
5553            }
5554            for (int i=0; i<res.key.allIntents.length; i++) {
5555                Intent intent = res.key.allIntents[i];
5556                if (intent.getPackage() != null && intent.getComponent() != null) {
5557                    return false;
5558                }
5559            }
5560            return true;
5561        } catch (ClassCastException e) {
5562        }
5563        return false;
5564    }
5565
5566    @Override
5567    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5568        if (!(pendingResult instanceof PendingIntentRecord)) {
5569            return false;
5570        }
5571        try {
5572            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5573            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5574                return true;
5575            }
5576            return false;
5577        } catch (ClassCastException e) {
5578        }
5579        return false;
5580    }
5581
5582    @Override
5583    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5584        if (!(pendingResult instanceof PendingIntentRecord)) {
5585            return null;
5586        }
5587        try {
5588            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5589            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5590        } catch (ClassCastException e) {
5591        }
5592        return null;
5593    }
5594
5595    @Override
5596    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5597        if (!(pendingResult instanceof PendingIntentRecord)) {
5598            return null;
5599        }
5600        try {
5601            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5602            Intent intent = res.key.requestIntent;
5603            if (intent != null) {
5604                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5605                        || res.lastTagPrefix.equals(prefix))) {
5606                    return res.lastTag;
5607                }
5608                res.lastTagPrefix = prefix;
5609                StringBuilder sb = new StringBuilder(128);
5610                if (prefix != null) {
5611                    sb.append(prefix);
5612                }
5613                if (intent.getAction() != null) {
5614                    sb.append(intent.getAction());
5615                } else if (intent.getComponent() != null) {
5616                    intent.getComponent().appendShortString(sb);
5617                } else {
5618                    sb.append("?");
5619                }
5620                return res.lastTag = sb.toString();
5621            }
5622        } catch (ClassCastException e) {
5623        }
5624        return null;
5625    }
5626
5627    @Override
5628    public void setProcessLimit(int max) {
5629        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5630                "setProcessLimit()");
5631        synchronized (this) {
5632            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5633            mProcessLimitOverride = max;
5634        }
5635        trimApplications();
5636    }
5637
5638    @Override
5639    public int getProcessLimit() {
5640        synchronized (this) {
5641            return mProcessLimitOverride;
5642        }
5643    }
5644
5645    void foregroundTokenDied(ForegroundToken token) {
5646        synchronized (ActivityManagerService.this) {
5647            synchronized (mPidsSelfLocked) {
5648                ForegroundToken cur
5649                    = mForegroundProcesses.get(token.pid);
5650                if (cur != token) {
5651                    return;
5652                }
5653                mForegroundProcesses.remove(token.pid);
5654                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5655                if (pr == null) {
5656                    return;
5657                }
5658                pr.forcingToForeground = null;
5659                updateProcessForegroundLocked(pr, false, false);
5660            }
5661            updateOomAdjLocked();
5662        }
5663    }
5664
5665    @Override
5666    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5667        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5668                "setProcessForeground()");
5669        synchronized(this) {
5670            boolean changed = false;
5671
5672            synchronized (mPidsSelfLocked) {
5673                ProcessRecord pr = mPidsSelfLocked.get(pid);
5674                if (pr == null && isForeground) {
5675                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5676                    return;
5677                }
5678                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5679                if (oldToken != null) {
5680                    oldToken.token.unlinkToDeath(oldToken, 0);
5681                    mForegroundProcesses.remove(pid);
5682                    if (pr != null) {
5683                        pr.forcingToForeground = null;
5684                    }
5685                    changed = true;
5686                }
5687                if (isForeground && token != null) {
5688                    ForegroundToken newToken = new ForegroundToken() {
5689                        @Override
5690                        public void binderDied() {
5691                            foregroundTokenDied(this);
5692                        }
5693                    };
5694                    newToken.pid = pid;
5695                    newToken.token = token;
5696                    try {
5697                        token.linkToDeath(newToken, 0);
5698                        mForegroundProcesses.put(pid, newToken);
5699                        pr.forcingToForeground = token;
5700                        changed = true;
5701                    } catch (RemoteException e) {
5702                        // If the process died while doing this, we will later
5703                        // do the cleanup with the process death link.
5704                    }
5705                }
5706            }
5707
5708            if (changed) {
5709                updateOomAdjLocked();
5710            }
5711        }
5712    }
5713
5714    // =========================================================
5715    // PERMISSIONS
5716    // =========================================================
5717
5718    static class PermissionController extends IPermissionController.Stub {
5719        ActivityManagerService mActivityManagerService;
5720        PermissionController(ActivityManagerService activityManagerService) {
5721            mActivityManagerService = activityManagerService;
5722        }
5723
5724        @Override
5725        public boolean checkPermission(String permission, int pid, int uid) {
5726            return mActivityManagerService.checkPermission(permission, pid,
5727                    uid) == PackageManager.PERMISSION_GRANTED;
5728        }
5729    }
5730
5731    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5732        @Override
5733        public int checkComponentPermission(String permission, int pid, int uid,
5734                int owningUid, boolean exported) {
5735            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5736                    owningUid, exported);
5737        }
5738
5739        @Override
5740        public Object getAMSLock() {
5741            return ActivityManagerService.this;
5742        }
5743    }
5744
5745    /**
5746     * This can be called with or without the global lock held.
5747     */
5748    int checkComponentPermission(String permission, int pid, int uid,
5749            int owningUid, boolean exported) {
5750        // We might be performing an operation on behalf of an indirect binder
5751        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5752        // client identity accordingly before proceeding.
5753        Identity tlsIdentity = sCallerIdentity.get();
5754        if (tlsIdentity != null) {
5755            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5756                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5757            uid = tlsIdentity.uid;
5758            pid = tlsIdentity.pid;
5759        }
5760
5761        if (pid == MY_PID) {
5762            return PackageManager.PERMISSION_GRANTED;
5763        }
5764
5765        return ActivityManager.checkComponentPermission(permission, uid,
5766                owningUid, exported);
5767    }
5768
5769    /**
5770     * As the only public entry point for permissions checking, this method
5771     * can enforce the semantic that requesting a check on a null global
5772     * permission is automatically denied.  (Internally a null permission
5773     * string is used when calling {@link #checkComponentPermission} in cases
5774     * when only uid-based security is needed.)
5775     *
5776     * This can be called with or without the global lock held.
5777     */
5778    @Override
5779    public int checkPermission(String permission, int pid, int uid) {
5780        if (permission == null) {
5781            return PackageManager.PERMISSION_DENIED;
5782        }
5783        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5784    }
5785
5786    /**
5787     * Binder IPC calls go through the public entry point.
5788     * This can be called with or without the global lock held.
5789     */
5790    int checkCallingPermission(String permission) {
5791        return checkPermission(permission,
5792                Binder.getCallingPid(),
5793                UserHandle.getAppId(Binder.getCallingUid()));
5794    }
5795
5796    /**
5797     * This can be called with or without the global lock held.
5798     */
5799    void enforceCallingPermission(String permission, String func) {
5800        if (checkCallingPermission(permission)
5801                == PackageManager.PERMISSION_GRANTED) {
5802            return;
5803        }
5804
5805        String msg = "Permission Denial: " + func + " from pid="
5806                + Binder.getCallingPid()
5807                + ", uid=" + Binder.getCallingUid()
5808                + " requires " + permission;
5809        Slog.w(TAG, msg);
5810        throw new SecurityException(msg);
5811    }
5812
5813    /**
5814     * Determine if UID is holding permissions required to access {@link Uri} in
5815     * the given {@link ProviderInfo}. Final permission checking is always done
5816     * in {@link ContentProvider}.
5817     */
5818    private final boolean checkHoldingPermissionsLocked(
5819            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5820        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5821                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5822
5823        if (pi.applicationInfo.uid == uid) {
5824            return true;
5825        } else if (!pi.exported) {
5826            return false;
5827        }
5828
5829        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5830        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5831        try {
5832            // check if target holds top-level <provider> permissions
5833            if (!readMet && pi.readPermission != null
5834                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5835                readMet = true;
5836            }
5837            if (!writeMet && pi.writePermission != null
5838                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5839                writeMet = true;
5840            }
5841
5842            // track if unprotected read/write is allowed; any denied
5843            // <path-permission> below removes this ability
5844            boolean allowDefaultRead = pi.readPermission == null;
5845            boolean allowDefaultWrite = pi.writePermission == null;
5846
5847            // check if target holds any <path-permission> that match uri
5848            final PathPermission[] pps = pi.pathPermissions;
5849            if (pps != null) {
5850                final String path = uri.getPath();
5851                int i = pps.length;
5852                while (i > 0 && (!readMet || !writeMet)) {
5853                    i--;
5854                    PathPermission pp = pps[i];
5855                    if (pp.match(path)) {
5856                        if (!readMet) {
5857                            final String pprperm = pp.getReadPermission();
5858                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5859                                    + pprperm + " for " + pp.getPath()
5860                                    + ": match=" + pp.match(path)
5861                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5862                            if (pprperm != null) {
5863                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5864                                    readMet = true;
5865                                } else {
5866                                    allowDefaultRead = false;
5867                                }
5868                            }
5869                        }
5870                        if (!writeMet) {
5871                            final String ppwperm = pp.getWritePermission();
5872                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5873                                    + ppwperm + " for " + pp.getPath()
5874                                    + ": match=" + pp.match(path)
5875                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5876                            if (ppwperm != null) {
5877                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5878                                    writeMet = true;
5879                                } else {
5880                                    allowDefaultWrite = false;
5881                                }
5882                            }
5883                        }
5884                    }
5885                }
5886            }
5887
5888            // grant unprotected <provider> read/write, if not blocked by
5889            // <path-permission> above
5890            if (allowDefaultRead) readMet = true;
5891            if (allowDefaultWrite) writeMet = true;
5892
5893        } catch (RemoteException e) {
5894            return false;
5895        }
5896
5897        return readMet && writeMet;
5898    }
5899
5900    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5901        ProviderInfo pi = null;
5902        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5903        if (cpr != null) {
5904            pi = cpr.info;
5905        } else {
5906            try {
5907                pi = AppGlobals.getPackageManager().resolveContentProvider(
5908                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5909            } catch (RemoteException ex) {
5910            }
5911        }
5912        return pi;
5913    }
5914
5915    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5916        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5917        if (targetUris != null) {
5918            return targetUris.get(uri);
5919        } else {
5920            return null;
5921        }
5922    }
5923
5924    private UriPermission findOrCreateUriPermissionLocked(
5925            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5926        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5927        if (targetUris == null) {
5928            targetUris = Maps.newArrayMap();
5929            mGrantedUriPermissions.put(targetUid, targetUris);
5930        }
5931
5932        UriPermission perm = targetUris.get(uri);
5933        if (perm == null) {
5934            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5935            targetUris.put(uri, perm);
5936        }
5937
5938        return perm;
5939    }
5940
5941    private final boolean checkUriPermissionLocked(
5942            Uri uri, int uid, int modeFlags, int minStrength) {
5943        // Root gets to do everything.
5944        if (uid == 0) {
5945            return true;
5946        }
5947        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5948        if (perms == null) return false;
5949        UriPermission perm = perms.get(uri);
5950        if (perm == null) return false;
5951        return perm.getStrength(modeFlags) >= minStrength;
5952    }
5953
5954    @Override
5955    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5956        enforceNotIsolatedCaller("checkUriPermission");
5957
5958        // Another redirected-binder-call permissions check as in
5959        // {@link checkComponentPermission}.
5960        Identity tlsIdentity = sCallerIdentity.get();
5961        if (tlsIdentity != null) {
5962            uid = tlsIdentity.uid;
5963            pid = tlsIdentity.pid;
5964        }
5965
5966        // Our own process gets to do everything.
5967        if (pid == MY_PID) {
5968            return PackageManager.PERMISSION_GRANTED;
5969        }
5970        synchronized(this) {
5971            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5972                    ? PackageManager.PERMISSION_GRANTED
5973                    : PackageManager.PERMISSION_DENIED;
5974        }
5975    }
5976
5977    /**
5978     * Check if the targetPkg can be granted permission to access uri by
5979     * the callingUid using the given modeFlags.  Throws a security exception
5980     * if callingUid is not allowed to do this.  Returns the uid of the target
5981     * if the URI permission grant should be performed; returns -1 if it is not
5982     * needed (for example targetPkg already has permission to access the URI).
5983     * If you already know the uid of the target, you can supply it in
5984     * lastTargetUid else set that to -1.
5985     */
5986    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5987            Uri uri, int modeFlags, int lastTargetUid) {
5988        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5989        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5990                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5991        if (modeFlags == 0) {
5992            return -1;
5993        }
5994
5995        if (targetPkg != null) {
5996            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5997                    "Checking grant " + targetPkg + " permission to " + uri);
5998        }
5999
6000        final IPackageManager pm = AppGlobals.getPackageManager();
6001
6002        // If this is not a content: uri, we can't do anything with it.
6003        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6004            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6005                    "Can't grant URI permission for non-content URI: " + uri);
6006            return -1;
6007        }
6008
6009        final String authority = uri.getAuthority();
6010        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6011        if (pi == null) {
6012            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6013            return -1;
6014        }
6015
6016        int targetUid = lastTargetUid;
6017        if (targetUid < 0 && targetPkg != null) {
6018            try {
6019                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6020                if (targetUid < 0) {
6021                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6022                            "Can't grant URI permission no uid for: " + targetPkg);
6023                    return -1;
6024                }
6025            } catch (RemoteException ex) {
6026                return -1;
6027            }
6028        }
6029
6030        if (targetUid >= 0) {
6031            // First...  does the target actually need this permission?
6032            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6033                // No need to grant the target this permission.
6034                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6035                        "Target " + targetPkg + " already has full permission to " + uri);
6036                return -1;
6037            }
6038        } else {
6039            // First...  there is no target package, so can anyone access it?
6040            boolean allowed = pi.exported;
6041            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6042                if (pi.readPermission != null) {
6043                    allowed = false;
6044                }
6045            }
6046            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6047                if (pi.writePermission != null) {
6048                    allowed = false;
6049                }
6050            }
6051            if (allowed) {
6052                return -1;
6053            }
6054        }
6055
6056        // Second...  is the provider allowing granting of URI permissions?
6057        if (!pi.grantUriPermissions) {
6058            throw new SecurityException("Provider " + pi.packageName
6059                    + "/" + pi.name
6060                    + " does not allow granting of Uri permissions (uri "
6061                    + uri + ")");
6062        }
6063        if (pi.uriPermissionPatterns != null) {
6064            final int N = pi.uriPermissionPatterns.length;
6065            boolean allowed = false;
6066            for (int i=0; i<N; i++) {
6067                if (pi.uriPermissionPatterns[i] != null
6068                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6069                    allowed = true;
6070                    break;
6071                }
6072            }
6073            if (!allowed) {
6074                throw new SecurityException("Provider " + pi.packageName
6075                        + "/" + pi.name
6076                        + " does not allow granting of permission to path of Uri "
6077                        + uri);
6078            }
6079        }
6080
6081        // Third...  does the caller itself have permission to access
6082        // this uri?
6083        if (callingUid != Process.myUid()) {
6084            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6085                // Require they hold a strong enough Uri permission
6086                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6087                        : UriPermission.STRENGTH_OWNED;
6088                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6089                    throw new SecurityException("Uid " + callingUid
6090                            + " does not have permission to uri " + uri);
6091                }
6092            }
6093        }
6094
6095        return targetUid;
6096    }
6097
6098    @Override
6099    public int checkGrantUriPermission(int callingUid, String targetPkg,
6100            Uri uri, int modeFlags) {
6101        enforceNotIsolatedCaller("checkGrantUriPermission");
6102        synchronized(this) {
6103            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6104        }
6105    }
6106
6107    void grantUriPermissionUncheckedLocked(
6108            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6109        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6110        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6111                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6112        if (modeFlags == 0) {
6113            return;
6114        }
6115
6116        // So here we are: the caller has the assumed permission
6117        // to the uri, and the target doesn't.  Let's now give this to
6118        // the target.
6119
6120        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6121                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6122
6123        final String authority = uri.getAuthority();
6124        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6125        if (pi == null) {
6126            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6127            return;
6128        }
6129
6130        final UriPermission perm = findOrCreateUriPermissionLocked(
6131                pi.packageName, targetPkg, targetUid, uri);
6132        perm.grantModes(modeFlags, persistable, owner);
6133    }
6134
6135    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6136            int modeFlags, UriPermissionOwner owner) {
6137        if (targetPkg == null) {
6138            throw new NullPointerException("targetPkg");
6139        }
6140
6141        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6142        if (targetUid < 0) {
6143            return;
6144        }
6145
6146        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6147    }
6148
6149    static class NeededUriGrants extends ArrayList<Uri> {
6150        final String targetPkg;
6151        final int targetUid;
6152        final int flags;
6153
6154        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6155            this.targetPkg = targetPkg;
6156            this.targetUid = targetUid;
6157            this.flags = flags;
6158        }
6159    }
6160
6161    /**
6162     * Like checkGrantUriPermissionLocked, but takes an Intent.
6163     */
6164    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6165            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6166        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6167                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6168                + " clip=" + (intent != null ? intent.getClipData() : null)
6169                + " from " + intent + "; flags=0x"
6170                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6171
6172        if (targetPkg == null) {
6173            throw new NullPointerException("targetPkg");
6174        }
6175
6176        if (intent == null) {
6177            return null;
6178        }
6179        Uri data = intent.getData();
6180        ClipData clip = intent.getClipData();
6181        if (data == null && clip == null) {
6182            return null;
6183        }
6184
6185        if (data != null) {
6186            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6187                mode, needed != null ? needed.targetUid : -1);
6188            if (targetUid > 0) {
6189                if (needed == null) {
6190                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6191                }
6192                needed.add(data);
6193            }
6194        }
6195        if (clip != null) {
6196            for (int i=0; i<clip.getItemCount(); i++) {
6197                Uri uri = clip.getItemAt(i).getUri();
6198                if (uri != null) {
6199                    int targetUid = -1;
6200                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6201                            mode, needed != null ? needed.targetUid : -1);
6202                    if (targetUid > 0) {
6203                        if (needed == null) {
6204                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6205                        }
6206                        needed.add(uri);
6207                    }
6208                } else {
6209                    Intent clipIntent = clip.getItemAt(i).getIntent();
6210                    if (clipIntent != null) {
6211                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6212                                callingUid, targetPkg, clipIntent, mode, needed);
6213                        if (newNeeded != null) {
6214                            needed = newNeeded;
6215                        }
6216                    }
6217                }
6218            }
6219        }
6220
6221        return needed;
6222    }
6223
6224    /**
6225     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6226     */
6227    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6228            UriPermissionOwner owner) {
6229        if (needed != null) {
6230            for (int i=0; i<needed.size(); i++) {
6231                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6232                        needed.get(i), needed.flags, owner);
6233            }
6234        }
6235    }
6236
6237    void grantUriPermissionFromIntentLocked(int callingUid,
6238            String targetPkg, Intent intent, UriPermissionOwner owner) {
6239        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6240                intent, intent != null ? intent.getFlags() : 0, null);
6241        if (needed == null) {
6242            return;
6243        }
6244
6245        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6246    }
6247
6248    @Override
6249    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6250            Uri uri, int modeFlags) {
6251        enforceNotIsolatedCaller("grantUriPermission");
6252        synchronized(this) {
6253            final ProcessRecord r = getRecordForAppLocked(caller);
6254            if (r == null) {
6255                throw new SecurityException("Unable to find app for caller "
6256                        + caller
6257                        + " when granting permission to uri " + uri);
6258            }
6259            if (targetPkg == null) {
6260                throw new IllegalArgumentException("null target");
6261            }
6262            if (uri == null) {
6263                throw new IllegalArgumentException("null uri");
6264            }
6265
6266            // Persistable only supported through Intents
6267            Preconditions.checkFlagsArgument(modeFlags,
6268                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6269
6270            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6271                    null);
6272        }
6273    }
6274
6275    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6276        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6277                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6278            ArrayMap<Uri, UriPermission> perms
6279                    = mGrantedUriPermissions.get(perm.targetUid);
6280            if (perms != null) {
6281                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6282                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6283                perms.remove(perm.uri);
6284                if (perms.size() == 0) {
6285                    mGrantedUriPermissions.remove(perm.targetUid);
6286                }
6287            }
6288        }
6289    }
6290
6291    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6292        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6293
6294        final IPackageManager pm = AppGlobals.getPackageManager();
6295        final String authority = uri.getAuthority();
6296        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6297        if (pi == null) {
6298            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6299            return;
6300        }
6301
6302        // Does the caller have this permission on the URI?
6303        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6304            // Right now, if you are not the original owner of the permission,
6305            // you are not allowed to revoke it.
6306            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6307                throw new SecurityException("Uid " + callingUid
6308                        + " does not have permission to uri " + uri);
6309            //}
6310        }
6311
6312        boolean persistChanged = false;
6313
6314        // Go through all of the permissions and remove any that match.
6315        final List<String> SEGMENTS = uri.getPathSegments();
6316        if (SEGMENTS != null) {
6317            final int NS = SEGMENTS.size();
6318            int N = mGrantedUriPermissions.size();
6319            for (int i=0; i<N; i++) {
6320                ArrayMap<Uri, UriPermission> perms
6321                        = mGrantedUriPermissions.valueAt(i);
6322                Iterator<UriPermission> it = perms.values().iterator();
6323            toploop:
6324                while (it.hasNext()) {
6325                    UriPermission perm = it.next();
6326                    Uri targetUri = perm.uri;
6327                    if (!authority.equals(targetUri.getAuthority())) {
6328                        continue;
6329                    }
6330                    List<String> targetSegments = targetUri.getPathSegments();
6331                    if (targetSegments == null) {
6332                        continue;
6333                    }
6334                    if (targetSegments.size() < NS) {
6335                        continue;
6336                    }
6337                    for (int j=0; j<NS; j++) {
6338                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6339                            continue toploop;
6340                        }
6341                    }
6342                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6343                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6344                    persistChanged |= perm.clearModes(modeFlags, true);
6345                    if (perm.modeFlags == 0) {
6346                        it.remove();
6347                    }
6348                }
6349                if (perms.size() == 0) {
6350                    mGrantedUriPermissions.remove(
6351                            mGrantedUriPermissions.keyAt(i));
6352                    N--;
6353                    i--;
6354                }
6355            }
6356        }
6357
6358        if (persistChanged) {
6359            schedulePersistUriGrants();
6360        }
6361    }
6362
6363    @Override
6364    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6365            int modeFlags) {
6366        enforceNotIsolatedCaller("revokeUriPermission");
6367        synchronized(this) {
6368            final ProcessRecord r = getRecordForAppLocked(caller);
6369            if (r == null) {
6370                throw new SecurityException("Unable to find app for caller "
6371                        + caller
6372                        + " when revoking permission to uri " + uri);
6373            }
6374            if (uri == null) {
6375                Slog.w(TAG, "revokeUriPermission: null uri");
6376                return;
6377            }
6378
6379            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6380                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6381            if (modeFlags == 0) {
6382                return;
6383            }
6384
6385            final IPackageManager pm = AppGlobals.getPackageManager();
6386            final String authority = uri.getAuthority();
6387            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6388            if (pi == null) {
6389                Slog.w(TAG, "No content provider found for permission revoke: "
6390                        + uri.toSafeString());
6391                return;
6392            }
6393
6394            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6395        }
6396    }
6397
6398    /**
6399     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6400     * given package.
6401     *
6402     * @param packageName Package name to match, or {@code null} to apply to all
6403     *            packages.
6404     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6405     *            to all users.
6406     * @param persistable If persistable grants should be removed.
6407     */
6408    private void removeUriPermissionsForPackageLocked(
6409            String packageName, int userHandle, boolean persistable) {
6410        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6411            throw new IllegalArgumentException("Must narrow by either package or user");
6412        }
6413
6414        boolean persistChanged = false;
6415
6416        final int size = mGrantedUriPermissions.size();
6417        for (int i = 0; i < size; i++) {
6418            // Only inspect grants matching user
6419            if (userHandle == UserHandle.USER_ALL
6420                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6421                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6422                        .values().iterator();
6423                while (it.hasNext()) {
6424                    final UriPermission perm = it.next();
6425
6426                    // Only inspect grants matching package
6427                    if (packageName == null || perm.sourcePkg.equals(packageName)
6428                            || perm.targetPkg.equals(packageName)) {
6429                        persistChanged |= perm.clearModes(~0, persistable);
6430
6431                        // Only remove when no modes remain; any persisted grants
6432                        // will keep this alive.
6433                        if (perm.modeFlags == 0) {
6434                            it.remove();
6435                        }
6436                    }
6437                }
6438            }
6439        }
6440
6441        if (persistChanged) {
6442            schedulePersistUriGrants();
6443        }
6444    }
6445
6446    @Override
6447    public IBinder newUriPermissionOwner(String name) {
6448        enforceNotIsolatedCaller("newUriPermissionOwner");
6449        synchronized(this) {
6450            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6451            return owner.getExternalTokenLocked();
6452        }
6453    }
6454
6455    @Override
6456    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6457            Uri uri, int modeFlags) {
6458        synchronized(this) {
6459            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6460            if (owner == null) {
6461                throw new IllegalArgumentException("Unknown owner: " + token);
6462            }
6463            if (fromUid != Binder.getCallingUid()) {
6464                if (Binder.getCallingUid() != Process.myUid()) {
6465                    // Only system code can grant URI permissions on behalf
6466                    // of other users.
6467                    throw new SecurityException("nice try");
6468                }
6469            }
6470            if (targetPkg == null) {
6471                throw new IllegalArgumentException("null target");
6472            }
6473            if (uri == null) {
6474                throw new IllegalArgumentException("null uri");
6475            }
6476
6477            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6478        }
6479    }
6480
6481    @Override
6482    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6483        synchronized(this) {
6484            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6485            if (owner == null) {
6486                throw new IllegalArgumentException("Unknown owner: " + token);
6487            }
6488
6489            if (uri == null) {
6490                owner.removeUriPermissionsLocked(mode);
6491            } else {
6492                owner.removeUriPermissionLocked(uri, mode);
6493            }
6494        }
6495    }
6496
6497    private void schedulePersistUriGrants() {
6498        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6499            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6500                    10 * DateUtils.SECOND_IN_MILLIS);
6501        }
6502    }
6503
6504    private void writeGrantedUriPermissions() {
6505        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6506
6507        // Snapshot permissions so we can persist without lock
6508        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6509        synchronized (this) {
6510            final int size = mGrantedUriPermissions.size();
6511            for (int i = 0 ; i < size; i++) {
6512                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6513                    if (perm.persistedModeFlags != 0) {
6514                        persist.add(perm.snapshot());
6515                    }
6516                }
6517            }
6518        }
6519
6520        FileOutputStream fos = null;
6521        try {
6522            fos = mGrantFile.startWrite();
6523
6524            XmlSerializer out = new FastXmlSerializer();
6525            out.setOutput(fos, "utf-8");
6526            out.startDocument(null, true);
6527            out.startTag(null, TAG_URI_GRANTS);
6528            for (UriPermission.Snapshot perm : persist) {
6529                out.startTag(null, TAG_URI_GRANT);
6530                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6531                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6532                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6533                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6534                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6535                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6536                out.endTag(null, TAG_URI_GRANT);
6537            }
6538            out.endTag(null, TAG_URI_GRANTS);
6539            out.endDocument();
6540
6541            mGrantFile.finishWrite(fos);
6542        } catch (IOException e) {
6543            if (fos != null) {
6544                mGrantFile.failWrite(fos);
6545            }
6546        }
6547    }
6548
6549    private void readGrantedUriPermissionsLocked() {
6550        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6551
6552        final long now = System.currentTimeMillis();
6553
6554        FileInputStream fis = null;
6555        try {
6556            fis = mGrantFile.openRead();
6557            final XmlPullParser in = Xml.newPullParser();
6558            in.setInput(fis, null);
6559
6560            int type;
6561            while ((type = in.next()) != END_DOCUMENT) {
6562                final String tag = in.getName();
6563                if (type == START_TAG) {
6564                    if (TAG_URI_GRANT.equals(tag)) {
6565                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6566                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6567                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6568                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6569                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6570                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6571
6572                        // Sanity check that provider still belongs to source package
6573                        final ProviderInfo pi = getProviderInfoLocked(
6574                                uri.getAuthority(), userHandle);
6575                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6576                            int targetUid = -1;
6577                            try {
6578                                targetUid = AppGlobals.getPackageManager()
6579                                        .getPackageUid(targetPkg, userHandle);
6580                            } catch (RemoteException e) {
6581                            }
6582                            if (targetUid != -1) {
6583                                final UriPermission perm = findOrCreateUriPermissionLocked(
6584                                        sourcePkg, targetPkg, targetUid, uri);
6585                                perm.initPersistedModes(modeFlags, createdTime);
6586                            }
6587                        } else {
6588                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6589                                    + " but instead found " + pi);
6590                        }
6591                    }
6592                }
6593            }
6594        } catch (FileNotFoundException e) {
6595            // Missing grants is okay
6596        } catch (IOException e) {
6597            Log.wtf(TAG, "Failed reading Uri grants", e);
6598        } catch (XmlPullParserException e) {
6599            Log.wtf(TAG, "Failed reading Uri grants", e);
6600        } finally {
6601            IoUtils.closeQuietly(fis);
6602        }
6603    }
6604
6605    @Override
6606    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6607        enforceNotIsolatedCaller("takePersistableUriPermission");
6608
6609        Preconditions.checkFlagsArgument(modeFlags,
6610                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6611
6612        synchronized (this) {
6613            final int callingUid = Binder.getCallingUid();
6614            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6615            if (perm == null) {
6616                throw new SecurityException("No permission grant found for UID " + callingUid
6617                        + " and Uri " + uri.toSafeString());
6618            }
6619
6620            boolean persistChanged = perm.takePersistableModes(modeFlags);
6621            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6622
6623            if (persistChanged) {
6624                schedulePersistUriGrants();
6625            }
6626        }
6627    }
6628
6629    @Override
6630    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6631        enforceNotIsolatedCaller("releasePersistableUriPermission");
6632
6633        Preconditions.checkFlagsArgument(modeFlags,
6634                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6635
6636        synchronized (this) {
6637            final int callingUid = Binder.getCallingUid();
6638
6639            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6640            if (perm == null) {
6641                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6642                        + uri.toSafeString());
6643                return;
6644            }
6645
6646            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6647            removeUriPermissionIfNeededLocked(perm);
6648            if (persistChanged) {
6649                schedulePersistUriGrants();
6650            }
6651        }
6652    }
6653
6654    /**
6655     * Prune any older {@link UriPermission} for the given UID until outstanding
6656     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6657     *
6658     * @return if any mutations occured that require persisting.
6659     */
6660    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6661        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6662        if (perms == null) return false;
6663        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6664
6665        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6666        for (UriPermission perm : perms.values()) {
6667            if (perm.persistedModeFlags != 0) {
6668                persisted.add(perm);
6669            }
6670        }
6671
6672        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6673        if (trimCount <= 0) return false;
6674
6675        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6676        for (int i = 0; i < trimCount; i++) {
6677            final UriPermission perm = persisted.get(i);
6678
6679            if (DEBUG_URI_PERMISSION) {
6680                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6681            }
6682
6683            perm.releasePersistableModes(~0);
6684            removeUriPermissionIfNeededLocked(perm);
6685        }
6686
6687        return true;
6688    }
6689
6690    @Override
6691    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6692            String packageName, boolean incoming) {
6693        enforceNotIsolatedCaller("getPersistedUriPermissions");
6694        Preconditions.checkNotNull(packageName, "packageName");
6695
6696        final int callingUid = Binder.getCallingUid();
6697        final IPackageManager pm = AppGlobals.getPackageManager();
6698        try {
6699            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6700            if (packageUid != callingUid) {
6701                throw new SecurityException(
6702                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6703            }
6704        } catch (RemoteException e) {
6705            throw new SecurityException("Failed to verify package name ownership");
6706        }
6707
6708        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6709        synchronized (this) {
6710            if (incoming) {
6711                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6712                if (perms == null) {
6713                    Slog.w(TAG, "No permission grants found for " + packageName);
6714                } else {
6715                    final int size = perms.size();
6716                    for (int i = 0; i < size; i++) {
6717                        final UriPermission perm = perms.valueAt(i);
6718                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6719                            result.add(perm.buildPersistedPublicApiObject());
6720                        }
6721                    }
6722                }
6723            } else {
6724                final int size = mGrantedUriPermissions.size();
6725                for (int i = 0; i < size; i++) {
6726                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6727                    final int permsSize = perms.size();
6728                    for (int j = 0; j < permsSize; j++) {
6729                        final UriPermission perm = perms.valueAt(j);
6730                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6731                            result.add(perm.buildPersistedPublicApiObject());
6732                        }
6733                    }
6734                }
6735            }
6736        }
6737        return new ParceledListSlice<android.content.UriPermission>(result);
6738    }
6739
6740    @Override
6741    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6742        synchronized (this) {
6743            ProcessRecord app =
6744                who != null ? getRecordForAppLocked(who) : null;
6745            if (app == null) return;
6746
6747            Message msg = Message.obtain();
6748            msg.what = WAIT_FOR_DEBUGGER_MSG;
6749            msg.obj = app;
6750            msg.arg1 = waiting ? 1 : 0;
6751            mHandler.sendMessage(msg);
6752        }
6753    }
6754
6755    @Override
6756    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6757        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6758        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6759        outInfo.availMem = Process.getFreeMemory();
6760        outInfo.totalMem = Process.getTotalMemory();
6761        outInfo.threshold = homeAppMem;
6762        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6763        outInfo.hiddenAppThreshold = cachedAppMem;
6764        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6765                ProcessList.SERVICE_ADJ);
6766        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6767                ProcessList.VISIBLE_APP_ADJ);
6768        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6769                ProcessList.FOREGROUND_APP_ADJ);
6770    }
6771
6772    // =========================================================
6773    // TASK MANAGEMENT
6774    // =========================================================
6775
6776    @Override
6777    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6778                         IThumbnailReceiver receiver) {
6779        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6780
6781        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6782        ActivityRecord topRecord = null;
6783
6784        synchronized(this) {
6785            if (localLOGV) Slog.v(
6786                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6787                + ", receiver=" + receiver);
6788
6789            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6790                    != PackageManager.PERMISSION_GRANTED) {
6791                if (receiver != null) {
6792                    // If the caller wants to wait for pending thumbnails,
6793                    // it ain't gonna get them.
6794                    try {
6795                        receiver.finished();
6796                    } catch (RemoteException ex) {
6797                    }
6798                }
6799                String msg = "Permission Denial: getTasks() from pid="
6800                        + Binder.getCallingPid()
6801                        + ", uid=" + Binder.getCallingUid()
6802                        + " requires " + android.Manifest.permission.GET_TASKS;
6803                Slog.w(TAG, msg);
6804                throw new SecurityException(msg);
6805            }
6806
6807            // TODO: Improve with MRU list from all ActivityStacks.
6808            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6809
6810            if (!pending.pendingRecords.isEmpty()) {
6811                mPendingThumbnails.add(pending);
6812            }
6813        }
6814
6815        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6816
6817        if (topRecord != null) {
6818            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6819            try {
6820                IApplicationThread topThumbnail = topRecord.app.thread;
6821                topThumbnail.requestThumbnail(topRecord.appToken);
6822            } catch (Exception e) {
6823                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6824                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6825            }
6826        }
6827
6828        if (pending.pendingRecords.isEmpty() && receiver != null) {
6829            // In this case all thumbnails were available and the client
6830            // is being asked to be told when the remaining ones come in...
6831            // which is unusually, since the top-most currently running
6832            // activity should never have a canned thumbnail!  Oh well.
6833            try {
6834                receiver.finished();
6835            } catch (RemoteException ex) {
6836            }
6837        }
6838
6839        return list;
6840    }
6841
6842    TaskRecord getMostRecentTask() {
6843        return mRecentTasks.get(0);
6844    }
6845
6846    @Override
6847    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6848            int flags, int userId) {
6849        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6850                false, true, "getRecentTasks", null);
6851
6852        synchronized (this) {
6853            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6854                    "getRecentTasks()");
6855            final boolean detailed = checkCallingPermission(
6856                    android.Manifest.permission.GET_DETAILED_TASKS)
6857                    == PackageManager.PERMISSION_GRANTED;
6858
6859            IPackageManager pm = AppGlobals.getPackageManager();
6860
6861            final int N = mRecentTasks.size();
6862            ArrayList<ActivityManager.RecentTaskInfo> res
6863                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6864                            maxNum < N ? maxNum : N);
6865
6866            final Set<Integer> includedUsers;
6867            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
6868                includedUsers = getProfileIdsLocked(userId);
6869            } else {
6870                includedUsers = new HashSet<Integer>();
6871            }
6872            includedUsers.add(Integer.valueOf(userId));
6873            for (int i=0; i<N && maxNum > 0; i++) {
6874                TaskRecord tr = mRecentTasks.get(i);
6875                // Only add calling user or related users recent tasks
6876                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
6877
6878                // Return the entry if desired by the caller.  We always return
6879                // the first entry, because callers always expect this to be the
6880                // foreground app.  We may filter others if the caller has
6881                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6882                // we should exclude the entry.
6883
6884                if (i == 0
6885                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6886                        || (tr.intent == null)
6887                        || ((tr.intent.getFlags()
6888                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6889                    ActivityManager.RecentTaskInfo rti
6890                            = new ActivityManager.RecentTaskInfo();
6891                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6892                    rti.persistentId = tr.taskId;
6893                    rti.baseIntent = new Intent(
6894                            tr.intent != null ? tr.intent : tr.affinityIntent);
6895                    if (!detailed) {
6896                        rti.baseIntent.replaceExtras((Bundle)null);
6897                    }
6898                    rti.origActivity = tr.origActivity;
6899                    rti.description = tr.lastDescription;
6900                    rti.stackId = tr.stack.mStackId;
6901                    rti.userId = tr.userId;
6902
6903                    final ArrayList<ActivityRecord> activities = tr.mActivities;
6904                    int numSet = 0;
6905                    for (int activityNdx = activities.size() - 1; activityNdx >= 0 && numSet < 2;
6906                            --activityNdx) {
6907                        final ActivityRecord r = activities.get(activityNdx);
6908                        if (rti.activityLabel == null && r.recentsLabel != null) {
6909                            rti.activityLabel = r.recentsLabel;
6910                            ++numSet;
6911                        }
6912                        if (rti.activityIcon == null && r.recentsIcon != null) {
6913                            rti.activityIcon = r.recentsIcon;
6914                            ++numSet;
6915                        }
6916                    }
6917
6918                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6919                        // Check whether this activity is currently available.
6920                        try {
6921                            if (rti.origActivity != null) {
6922                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6923                                        == null) {
6924                                    continue;
6925                                }
6926                            } else if (rti.baseIntent != null) {
6927                                if (pm.queryIntentActivities(rti.baseIntent,
6928                                        null, 0, userId) == null) {
6929                                    continue;
6930                                }
6931                            }
6932                        } catch (RemoteException e) {
6933                            // Will never happen.
6934                        }
6935                    }
6936
6937                    res.add(rti);
6938                    maxNum--;
6939                }
6940            }
6941            return res;
6942        }
6943    }
6944
6945    private TaskRecord recentTaskForIdLocked(int id) {
6946        final int N = mRecentTasks.size();
6947            for (int i=0; i<N; i++) {
6948                TaskRecord tr = mRecentTasks.get(i);
6949                if (tr.taskId == id) {
6950                    return tr;
6951                }
6952            }
6953            return null;
6954    }
6955
6956    @Override
6957    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6958        synchronized (this) {
6959            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6960                    "getTaskThumbnails()");
6961            TaskRecord tr = recentTaskForIdLocked(id);
6962            if (tr != null) {
6963                return tr.getTaskThumbnailsLocked();
6964            }
6965        }
6966        return null;
6967    }
6968
6969    @Override
6970    public Bitmap getTaskTopThumbnail(int id) {
6971        synchronized (this) {
6972            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6973                    "getTaskTopThumbnail()");
6974            TaskRecord tr = recentTaskForIdLocked(id);
6975            if (tr != null) {
6976                return tr.getTaskTopThumbnailLocked();
6977            }
6978        }
6979        return null;
6980    }
6981
6982    @Override
6983    public void setRecentsLabel(IBinder token, CharSequence recentsLabel) {
6984        synchronized (this) {
6985            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6986            if (r != null) {
6987                r.recentsLabel = recentsLabel.toString();
6988            }
6989        }
6990    }
6991
6992    @Override
6993    public void setRecentsIcon(IBinder token, Bitmap recentsIcon) {
6994        synchronized (this) {
6995            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6996            if (r != null) {
6997                r.recentsIcon = recentsIcon;
6998            }
6999        }
7000    }
7001
7002    @Override
7003    public boolean removeSubTask(int taskId, int subTaskIndex) {
7004        synchronized (this) {
7005            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7006                    "removeSubTask()");
7007            long ident = Binder.clearCallingIdentity();
7008            try {
7009                TaskRecord tr = recentTaskForIdLocked(taskId);
7010                if (tr != null) {
7011                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7012                }
7013                return false;
7014            } finally {
7015                Binder.restoreCallingIdentity(ident);
7016            }
7017        }
7018    }
7019
7020    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7021        if (!pr.killedByAm) {
7022            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7023            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7024                    pr.processName, pr.setAdj, reason);
7025            pr.killedByAm = true;
7026            Process.killProcessQuiet(pr.pid);
7027        }
7028    }
7029
7030    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7031        tr.disposeThumbnail();
7032        mRecentTasks.remove(tr);
7033        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7034        Intent baseIntent = new Intent(
7035                tr.intent != null ? tr.intent : tr.affinityIntent);
7036        ComponentName component = baseIntent.getComponent();
7037        if (component == null) {
7038            Slog.w(TAG, "Now component for base intent of task: " + tr);
7039            return;
7040        }
7041
7042        // Find any running services associated with this app.
7043        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7044
7045        if (killProcesses) {
7046            // Find any running processes associated with this app.
7047            final String pkg = component.getPackageName();
7048            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7049            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7050            for (int i=0; i<pmap.size(); i++) {
7051                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7052                for (int j=0; j<uids.size(); j++) {
7053                    ProcessRecord proc = uids.valueAt(j);
7054                    if (proc.userId != tr.userId) {
7055                        continue;
7056                    }
7057                    if (!proc.pkgList.containsKey(pkg)) {
7058                        continue;
7059                    }
7060                    procs.add(proc);
7061                }
7062            }
7063
7064            // Kill the running processes.
7065            for (int i=0; i<procs.size(); i++) {
7066                ProcessRecord pr = procs.get(i);
7067                if (pr == mHomeProcess) {
7068                    // Don't kill the home process along with tasks from the same package.
7069                    continue;
7070                }
7071                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7072                    killUnneededProcessLocked(pr, "remove task");
7073                } else {
7074                    pr.waitingToKill = "remove task";
7075                }
7076            }
7077        }
7078    }
7079
7080    @Override
7081    public boolean removeTask(int taskId, int flags) {
7082        synchronized (this) {
7083            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7084                    "removeTask()");
7085            long ident = Binder.clearCallingIdentity();
7086            try {
7087                TaskRecord tr = recentTaskForIdLocked(taskId);
7088                if (tr != null) {
7089                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7090                    if (r != null) {
7091                        cleanUpRemovedTaskLocked(tr, flags);
7092                        return true;
7093                    }
7094                    if (tr.mActivities.size() == 0) {
7095                        // Caller is just removing a recent task that is
7096                        // not actively running.  That is easy!
7097                        cleanUpRemovedTaskLocked(tr, flags);
7098                        return true;
7099                    }
7100                    Slog.w(TAG, "removeTask: task " + taskId
7101                            + " does not have activities to remove, "
7102                            + " but numActivities=" + tr.numActivities
7103                            + ": " + tr);
7104                }
7105            } finally {
7106                Binder.restoreCallingIdentity(ident);
7107            }
7108        }
7109        return false;
7110    }
7111
7112    /**
7113     * TODO: Add mController hook
7114     */
7115    @Override
7116    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7117        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7118                "moveTaskToFront()");
7119
7120        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7121        synchronized(this) {
7122            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7123                    Binder.getCallingUid(), "Task to front")) {
7124                ActivityOptions.abort(options);
7125                return;
7126            }
7127            final long origId = Binder.clearCallingIdentity();
7128            try {
7129                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7130                if (task == null) {
7131                    return;
7132                }
7133                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7134                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7135                    return;
7136                }
7137                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7138            } finally {
7139                Binder.restoreCallingIdentity(origId);
7140            }
7141            ActivityOptions.abort(options);
7142        }
7143    }
7144
7145    @Override
7146    public void moveTaskToBack(int taskId) {
7147        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7148                "moveTaskToBack()");
7149
7150        synchronized(this) {
7151            TaskRecord tr = recentTaskForIdLocked(taskId);
7152            if (tr != null) {
7153                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7154                ActivityStack stack = tr.stack;
7155                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7156                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7157                            Binder.getCallingUid(), "Task to back")) {
7158                        return;
7159                    }
7160                }
7161                final long origId = Binder.clearCallingIdentity();
7162                try {
7163                    stack.moveTaskToBackLocked(taskId, null);
7164                } finally {
7165                    Binder.restoreCallingIdentity(origId);
7166                }
7167            }
7168        }
7169    }
7170
7171    /**
7172     * Moves an activity, and all of the other activities within the same task, to the bottom
7173     * of the history stack.  The activity's order within the task is unchanged.
7174     *
7175     * @param token A reference to the activity we wish to move
7176     * @param nonRoot If false then this only works if the activity is the root
7177     *                of a task; if true it will work for any activity in a task.
7178     * @return Returns true if the move completed, false if not.
7179     */
7180    @Override
7181    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7182        enforceNotIsolatedCaller("moveActivityTaskToBack");
7183        synchronized(this) {
7184            final long origId = Binder.clearCallingIdentity();
7185            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7186            if (taskId >= 0) {
7187                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7188            }
7189            Binder.restoreCallingIdentity(origId);
7190        }
7191        return false;
7192    }
7193
7194    @Override
7195    public void moveTaskBackwards(int task) {
7196        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7197                "moveTaskBackwards()");
7198
7199        synchronized(this) {
7200            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7201                    Binder.getCallingUid(), "Task backwards")) {
7202                return;
7203            }
7204            final long origId = Binder.clearCallingIdentity();
7205            moveTaskBackwardsLocked(task);
7206            Binder.restoreCallingIdentity(origId);
7207        }
7208    }
7209
7210    private final void moveTaskBackwardsLocked(int task) {
7211        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7212    }
7213
7214    @Override
7215    public IBinder getHomeActivityToken() throws RemoteException {
7216        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7217                "getHomeActivityToken()");
7218        synchronized (this) {
7219            return mStackSupervisor.getHomeActivityToken();
7220        }
7221    }
7222
7223    @Override
7224    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7225            IActivityContainerCallback callback) throws RemoteException {
7226        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7227                "createActivityContainer()");
7228        synchronized (this) {
7229            if (parentActivityToken == null) {
7230                throw new IllegalArgumentException("parent token must not be null");
7231            }
7232            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7233            if (r == null) {
7234                return null;
7235            }
7236            return mStackSupervisor.createActivityContainer(r, callback);
7237        }
7238    }
7239
7240    @Override
7241    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7242        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7243                "deleteActivityContainer()");
7244        synchronized (this) {
7245            mStackSupervisor.deleteActivityContainer(container);
7246        }
7247    }
7248
7249    @Override
7250    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7251            throws RemoteException {
7252        synchronized (this) {
7253            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7254            if (stack != null) {
7255                return stack.mActivityContainer;
7256            }
7257            return null;
7258        }
7259    }
7260
7261    @Override
7262    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7263        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7264                "moveTaskToStack()");
7265        if (stackId == HOME_STACK_ID) {
7266            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7267                    new RuntimeException("here").fillInStackTrace());
7268        }
7269        synchronized (this) {
7270            long ident = Binder.clearCallingIdentity();
7271            try {
7272                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7273                        + stackId + " toTop=" + toTop);
7274                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7275            } finally {
7276                Binder.restoreCallingIdentity(ident);
7277            }
7278        }
7279    }
7280
7281    @Override
7282    public void resizeStack(int stackBoxId, Rect bounds) {
7283        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7284                "resizeStackBox()");
7285        long ident = Binder.clearCallingIdentity();
7286        try {
7287            mWindowManager.resizeStack(stackBoxId, bounds);
7288        } finally {
7289            Binder.restoreCallingIdentity(ident);
7290        }
7291    }
7292
7293    @Override
7294    public List<StackInfo> getAllStackInfos() {
7295        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7296                "getAllStackInfos()");
7297        long ident = Binder.clearCallingIdentity();
7298        try {
7299            synchronized (this) {
7300                return mStackSupervisor.getAllStackInfosLocked();
7301            }
7302        } finally {
7303            Binder.restoreCallingIdentity(ident);
7304        }
7305    }
7306
7307    @Override
7308    public StackInfo getStackInfo(int stackId) {
7309        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7310                "getStackInfo()");
7311        long ident = Binder.clearCallingIdentity();
7312        try {
7313            synchronized (this) {
7314                return mStackSupervisor.getStackInfoLocked(stackId);
7315            }
7316        } finally {
7317            Binder.restoreCallingIdentity(ident);
7318        }
7319    }
7320
7321    @Override
7322    public boolean isInHomeStack(int taskId) {
7323        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7324                "getStackInfo()");
7325        long ident = Binder.clearCallingIdentity();
7326        try {
7327            synchronized (this) {
7328                TaskRecord tr = recentTaskForIdLocked(taskId);
7329                if (tr != null) {
7330                    return tr.stack.isHomeStack();
7331                }
7332            }
7333        } finally {
7334            Binder.restoreCallingIdentity(ident);
7335        }
7336        return false;
7337    }
7338
7339    @Override
7340    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7341        synchronized(this) {
7342            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7343        }
7344    }
7345
7346    private boolean isLockTaskAuthorized(ComponentName name) {
7347//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7348//                "startLockTaskMode()");
7349//        DevicePolicyManager dpm = (DevicePolicyManager)
7350//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7351//        return dpm != null && dpm.isLockTaskPermitted(name);
7352        return true;
7353    }
7354
7355    private void startLockTaskMode(TaskRecord task) {
7356        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7357            return;
7358        }
7359        long ident = Binder.clearCallingIdentity();
7360        try {
7361            synchronized (this) {
7362                // Since we lost lock on task, make sure it is still there.
7363                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7364                if (task != null) {
7365                    mStackSupervisor.setLockTaskModeLocked(task);
7366                }
7367            }
7368        } finally {
7369            Binder.restoreCallingIdentity(ident);
7370        }
7371    }
7372
7373    @Override
7374    public void startLockTaskMode(int taskId) {
7375        long ident = Binder.clearCallingIdentity();
7376        try {
7377            final TaskRecord task;
7378            synchronized (this) {
7379                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7380            }
7381            if (task != null) {
7382                startLockTaskMode(task);
7383            }
7384        } finally {
7385            Binder.restoreCallingIdentity(ident);
7386        }
7387    }
7388
7389    @Override
7390    public void startLockTaskMode(IBinder token) {
7391        long ident = Binder.clearCallingIdentity();
7392        try {
7393            final TaskRecord task;
7394            synchronized (this) {
7395                final ActivityRecord r = ActivityRecord.forToken(token);
7396                if (r == null) {
7397                    return;
7398                }
7399                task = r.task;
7400            }
7401            if (task != null) {
7402                startLockTaskMode(task);
7403            }
7404        } finally {
7405            Binder.restoreCallingIdentity(ident);
7406        }
7407    }
7408
7409    @Override
7410    public void stopLockTaskMode() {
7411//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7412//                "stopLockTaskMode()");
7413        synchronized (this) {
7414            mStackSupervisor.setLockTaskModeLocked(null);
7415        }
7416    }
7417
7418    @Override
7419    public boolean isInLockTaskMode() {
7420        synchronized (this) {
7421            return mStackSupervisor.isInLockTaskMode();
7422        }
7423    }
7424
7425    // =========================================================
7426    // THUMBNAILS
7427    // =========================================================
7428
7429    public void reportThumbnail(IBinder token,
7430            Bitmap thumbnail, CharSequence description) {
7431        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7432        final long origId = Binder.clearCallingIdentity();
7433        sendPendingThumbnail(null, token, thumbnail, description, true);
7434        Binder.restoreCallingIdentity(origId);
7435    }
7436
7437    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7438            Bitmap thumbnail, CharSequence description, boolean always) {
7439        TaskRecord task;
7440        ArrayList<PendingThumbnailsRecord> receivers = null;
7441
7442        //System.out.println("Send pending thumbnail: " + r);
7443
7444        synchronized(this) {
7445            if (r == null) {
7446                r = ActivityRecord.isInStackLocked(token);
7447                if (r == null) {
7448                    return;
7449                }
7450            }
7451            if (thumbnail == null && r.thumbHolder != null) {
7452                thumbnail = r.thumbHolder.lastThumbnail;
7453                description = r.thumbHolder.lastDescription;
7454            }
7455            if (thumbnail == null && !always) {
7456                // If there is no thumbnail, and this entry is not actually
7457                // going away, then abort for now and pick up the next
7458                // thumbnail we get.
7459                return;
7460            }
7461            task = r.task;
7462
7463            int N = mPendingThumbnails.size();
7464            int i=0;
7465            while (i<N) {
7466                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7467                //System.out.println("Looking in " + pr.pendingRecords);
7468                if (pr.pendingRecords.remove(r)) {
7469                    if (receivers == null) {
7470                        receivers = new ArrayList<PendingThumbnailsRecord>();
7471                    }
7472                    receivers.add(pr);
7473                    if (pr.pendingRecords.size() == 0) {
7474                        pr.finished = true;
7475                        mPendingThumbnails.remove(i);
7476                        N--;
7477                        continue;
7478                    }
7479                }
7480                i++;
7481            }
7482        }
7483
7484        if (receivers != null) {
7485            final int N = receivers.size();
7486            for (int i=0; i<N; i++) {
7487                try {
7488                    PendingThumbnailsRecord pr = receivers.get(i);
7489                    pr.receiver.newThumbnail(
7490                        task != null ? task.taskId : -1, thumbnail, description);
7491                    if (pr.finished) {
7492                        pr.receiver.finished();
7493                    }
7494                } catch (Exception e) {
7495                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7496                }
7497            }
7498        }
7499    }
7500
7501    // =========================================================
7502    // CONTENT PROVIDERS
7503    // =========================================================
7504
7505    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7506        List<ProviderInfo> providers = null;
7507        try {
7508            providers = AppGlobals.getPackageManager().
7509                queryContentProviders(app.processName, app.uid,
7510                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7511        } catch (RemoteException ex) {
7512        }
7513        if (DEBUG_MU)
7514            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7515        int userId = app.userId;
7516        if (providers != null) {
7517            int N = providers.size();
7518            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7519            for (int i=0; i<N; i++) {
7520                ProviderInfo cpi =
7521                    (ProviderInfo)providers.get(i);
7522                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7523                        cpi.name, cpi.flags);
7524                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7525                    // This is a singleton provider, but a user besides the
7526                    // default user is asking to initialize a process it runs
7527                    // in...  well, no, it doesn't actually run in this process,
7528                    // it runs in the process of the default user.  Get rid of it.
7529                    providers.remove(i);
7530                    N--;
7531                    i--;
7532                    continue;
7533                }
7534
7535                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7536                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7537                if (cpr == null) {
7538                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7539                    mProviderMap.putProviderByClass(comp, cpr);
7540                }
7541                if (DEBUG_MU)
7542                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7543                app.pubProviders.put(cpi.name, cpr);
7544                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7545                    // Don't add this if it is a platform component that is marked
7546                    // to run in multiple processes, because this is actually
7547                    // part of the framework so doesn't make sense to track as a
7548                    // separate apk in the process.
7549                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7550                }
7551                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7552            }
7553        }
7554        return providers;
7555    }
7556
7557    /**
7558     * Check if {@link ProcessRecord} has a possible chance at accessing the
7559     * given {@link ProviderInfo}. Final permission checking is always done
7560     * in {@link ContentProvider}.
7561     */
7562    private final String checkContentProviderPermissionLocked(
7563            ProviderInfo cpi, ProcessRecord r) {
7564        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7565        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7566        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7567                cpi.applicationInfo.uid, cpi.exported)
7568                == PackageManager.PERMISSION_GRANTED) {
7569            return null;
7570        }
7571        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7572                cpi.applicationInfo.uid, cpi.exported)
7573                == PackageManager.PERMISSION_GRANTED) {
7574            return null;
7575        }
7576
7577        PathPermission[] pps = cpi.pathPermissions;
7578        if (pps != null) {
7579            int i = pps.length;
7580            while (i > 0) {
7581                i--;
7582                PathPermission pp = pps[i];
7583                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7584                        cpi.applicationInfo.uid, cpi.exported)
7585                        == PackageManager.PERMISSION_GRANTED) {
7586                    return null;
7587                }
7588                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7589                        cpi.applicationInfo.uid, cpi.exported)
7590                        == PackageManager.PERMISSION_GRANTED) {
7591                    return null;
7592                }
7593            }
7594        }
7595
7596        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7597        if (perms != null) {
7598            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7599                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7600                    return null;
7601                }
7602            }
7603        }
7604
7605        String msg;
7606        if (!cpi.exported) {
7607            msg = "Permission Denial: opening provider " + cpi.name
7608                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7609                    + ", uid=" + callingUid + ") that is not exported from uid "
7610                    + cpi.applicationInfo.uid;
7611        } else {
7612            msg = "Permission Denial: opening provider " + cpi.name
7613                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7614                    + ", uid=" + callingUid + ") requires "
7615                    + cpi.readPermission + " or " + cpi.writePermission;
7616        }
7617        Slog.w(TAG, msg);
7618        return msg;
7619    }
7620
7621    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7622            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7623        if (r != null) {
7624            for (int i=0; i<r.conProviders.size(); i++) {
7625                ContentProviderConnection conn = r.conProviders.get(i);
7626                if (conn.provider == cpr) {
7627                    if (DEBUG_PROVIDER) Slog.v(TAG,
7628                            "Adding provider requested by "
7629                            + r.processName + " from process "
7630                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7631                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7632                    if (stable) {
7633                        conn.stableCount++;
7634                        conn.numStableIncs++;
7635                    } else {
7636                        conn.unstableCount++;
7637                        conn.numUnstableIncs++;
7638                    }
7639                    return conn;
7640                }
7641            }
7642            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7643            if (stable) {
7644                conn.stableCount = 1;
7645                conn.numStableIncs = 1;
7646            } else {
7647                conn.unstableCount = 1;
7648                conn.numUnstableIncs = 1;
7649            }
7650            cpr.connections.add(conn);
7651            r.conProviders.add(conn);
7652            return conn;
7653        }
7654        cpr.addExternalProcessHandleLocked(externalProcessToken);
7655        return null;
7656    }
7657
7658    boolean decProviderCountLocked(ContentProviderConnection conn,
7659            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7660        if (conn != null) {
7661            cpr = conn.provider;
7662            if (DEBUG_PROVIDER) Slog.v(TAG,
7663                    "Removing provider requested by "
7664                    + conn.client.processName + " from process "
7665                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7666                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7667            if (stable) {
7668                conn.stableCount--;
7669            } else {
7670                conn.unstableCount--;
7671            }
7672            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7673                cpr.connections.remove(conn);
7674                conn.client.conProviders.remove(conn);
7675                return true;
7676            }
7677            return false;
7678        }
7679        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7680        return false;
7681    }
7682
7683    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7684            String name, IBinder token, boolean stable, int userId) {
7685        ContentProviderRecord cpr;
7686        ContentProviderConnection conn = null;
7687        ProviderInfo cpi = null;
7688
7689        synchronized(this) {
7690            ProcessRecord r = null;
7691            if (caller != null) {
7692                r = getRecordForAppLocked(caller);
7693                if (r == null) {
7694                    throw new SecurityException(
7695                            "Unable to find app for caller " + caller
7696                          + " (pid=" + Binder.getCallingPid()
7697                          + ") when getting content provider " + name);
7698                }
7699            }
7700
7701            // First check if this content provider has been published...
7702            cpr = mProviderMap.getProviderByName(name, userId);
7703            boolean providerRunning = cpr != null;
7704            if (providerRunning) {
7705                cpi = cpr.info;
7706                String msg;
7707                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7708                    throw new SecurityException(msg);
7709                }
7710
7711                if (r != null && cpr.canRunHere(r)) {
7712                    // This provider has been published or is in the process
7713                    // of being published...  but it is also allowed to run
7714                    // in the caller's process, so don't make a connection
7715                    // and just let the caller instantiate its own instance.
7716                    ContentProviderHolder holder = cpr.newHolder(null);
7717                    // don't give caller the provider object, it needs
7718                    // to make its own.
7719                    holder.provider = null;
7720                    return holder;
7721                }
7722
7723                final long origId = Binder.clearCallingIdentity();
7724
7725                // In this case the provider instance already exists, so we can
7726                // return it right away.
7727                conn = incProviderCountLocked(r, cpr, token, stable);
7728                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7729                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7730                        // If this is a perceptible app accessing the provider,
7731                        // make sure to count it as being accessed and thus
7732                        // back up on the LRU list.  This is good because
7733                        // content providers are often expensive to start.
7734                        updateLruProcessLocked(cpr.proc, false, null);
7735                    }
7736                }
7737
7738                if (cpr.proc != null) {
7739                    if (false) {
7740                        if (cpr.name.flattenToShortString().equals(
7741                                "com.android.providers.calendar/.CalendarProvider2")) {
7742                            Slog.v(TAG, "****************** KILLING "
7743                                + cpr.name.flattenToShortString());
7744                            Process.killProcess(cpr.proc.pid);
7745                        }
7746                    }
7747                    boolean success = updateOomAdjLocked(cpr.proc);
7748                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7749                    // NOTE: there is still a race here where a signal could be
7750                    // pending on the process even though we managed to update its
7751                    // adj level.  Not sure what to do about this, but at least
7752                    // the race is now smaller.
7753                    if (!success) {
7754                        // Uh oh...  it looks like the provider's process
7755                        // has been killed on us.  We need to wait for a new
7756                        // process to be started, and make sure its death
7757                        // doesn't kill our process.
7758                        Slog.i(TAG,
7759                                "Existing provider " + cpr.name.flattenToShortString()
7760                                + " is crashing; detaching " + r);
7761                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7762                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7763                        if (!lastRef) {
7764                            // This wasn't the last ref our process had on
7765                            // the provider...  we have now been killed, bail.
7766                            return null;
7767                        }
7768                        providerRunning = false;
7769                        conn = null;
7770                    }
7771                }
7772
7773                Binder.restoreCallingIdentity(origId);
7774            }
7775
7776            boolean singleton;
7777            if (!providerRunning) {
7778                try {
7779                    cpi = AppGlobals.getPackageManager().
7780                        resolveContentProvider(name,
7781                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7782                } catch (RemoteException ex) {
7783                }
7784                if (cpi == null) {
7785                    return null;
7786                }
7787                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7788                        cpi.name, cpi.flags);
7789                if (singleton) {
7790                    userId = 0;
7791                }
7792                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7793
7794                String msg;
7795                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7796                    throw new SecurityException(msg);
7797                }
7798
7799                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7800                        && !cpi.processName.equals("system")) {
7801                    // If this content provider does not run in the system
7802                    // process, and the system is not yet ready to run other
7803                    // processes, then fail fast instead of hanging.
7804                    throw new IllegalArgumentException(
7805                            "Attempt to launch content provider before system ready");
7806                }
7807
7808                // Make sure that the user who owns this provider is started.  If not,
7809                // we don't want to allow it to run.
7810                if (mStartedUsers.get(userId) == null) {
7811                    Slog.w(TAG, "Unable to launch app "
7812                            + cpi.applicationInfo.packageName + "/"
7813                            + cpi.applicationInfo.uid + " for provider "
7814                            + name + ": user " + userId + " is stopped");
7815                    return null;
7816                }
7817
7818                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7819                cpr = mProviderMap.getProviderByClass(comp, userId);
7820                final boolean firstClass = cpr == null;
7821                if (firstClass) {
7822                    try {
7823                        ApplicationInfo ai =
7824                            AppGlobals.getPackageManager().
7825                                getApplicationInfo(
7826                                        cpi.applicationInfo.packageName,
7827                                        STOCK_PM_FLAGS, userId);
7828                        if (ai == null) {
7829                            Slog.w(TAG, "No package info for content provider "
7830                                    + cpi.name);
7831                            return null;
7832                        }
7833                        ai = getAppInfoForUser(ai, userId);
7834                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7835                    } catch (RemoteException ex) {
7836                        // pm is in same process, this will never happen.
7837                    }
7838                }
7839
7840                if (r != null && cpr.canRunHere(r)) {
7841                    // If this is a multiprocess provider, then just return its
7842                    // info and allow the caller to instantiate it.  Only do
7843                    // this if the provider is the same user as the caller's
7844                    // process, or can run as root (so can be in any process).
7845                    return cpr.newHolder(null);
7846                }
7847
7848                if (DEBUG_PROVIDER) {
7849                    RuntimeException e = new RuntimeException("here");
7850                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7851                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7852                }
7853
7854                // This is single process, and our app is now connecting to it.
7855                // See if we are already in the process of launching this
7856                // provider.
7857                final int N = mLaunchingProviders.size();
7858                int i;
7859                for (i=0; i<N; i++) {
7860                    if (mLaunchingProviders.get(i) == cpr) {
7861                        break;
7862                    }
7863                }
7864
7865                // If the provider is not already being launched, then get it
7866                // started.
7867                if (i >= N) {
7868                    final long origId = Binder.clearCallingIdentity();
7869
7870                    try {
7871                        // Content provider is now in use, its package can't be stopped.
7872                        try {
7873                            AppGlobals.getPackageManager().setPackageStoppedState(
7874                                    cpr.appInfo.packageName, false, userId);
7875                        } catch (RemoteException e) {
7876                        } catch (IllegalArgumentException e) {
7877                            Slog.w(TAG, "Failed trying to unstop package "
7878                                    + cpr.appInfo.packageName + ": " + e);
7879                        }
7880
7881                        // Use existing process if already started
7882                        ProcessRecord proc = getProcessRecordLocked(
7883                                cpi.processName, cpr.appInfo.uid, false);
7884                        if (proc != null && proc.thread != null) {
7885                            if (DEBUG_PROVIDER) {
7886                                Slog.d(TAG, "Installing in existing process " + proc);
7887                            }
7888                            proc.pubProviders.put(cpi.name, cpr);
7889                            try {
7890                                proc.thread.scheduleInstallProvider(cpi);
7891                            } catch (RemoteException e) {
7892                            }
7893                        } else {
7894                            proc = startProcessLocked(cpi.processName,
7895                                    cpr.appInfo, false, 0, "content provider",
7896                                    new ComponentName(cpi.applicationInfo.packageName,
7897                                            cpi.name), false, false, false);
7898                            if (proc == null) {
7899                                Slog.w(TAG, "Unable to launch app "
7900                                        + cpi.applicationInfo.packageName + "/"
7901                                        + cpi.applicationInfo.uid + " for provider "
7902                                        + name + ": process is bad");
7903                                return null;
7904                            }
7905                        }
7906                        cpr.launchingApp = proc;
7907                        mLaunchingProviders.add(cpr);
7908                    } finally {
7909                        Binder.restoreCallingIdentity(origId);
7910                    }
7911                }
7912
7913                // Make sure the provider is published (the same provider class
7914                // may be published under multiple names).
7915                if (firstClass) {
7916                    mProviderMap.putProviderByClass(comp, cpr);
7917                }
7918
7919                mProviderMap.putProviderByName(name, cpr);
7920                conn = incProviderCountLocked(r, cpr, token, stable);
7921                if (conn != null) {
7922                    conn.waiting = true;
7923                }
7924            }
7925        }
7926
7927        // Wait for the provider to be published...
7928        synchronized (cpr) {
7929            while (cpr.provider == null) {
7930                if (cpr.launchingApp == null) {
7931                    Slog.w(TAG, "Unable to launch app "
7932                            + cpi.applicationInfo.packageName + "/"
7933                            + cpi.applicationInfo.uid + " for provider "
7934                            + name + ": launching app became null");
7935                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7936                            UserHandle.getUserId(cpi.applicationInfo.uid),
7937                            cpi.applicationInfo.packageName,
7938                            cpi.applicationInfo.uid, name);
7939                    return null;
7940                }
7941                try {
7942                    if (DEBUG_MU) {
7943                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7944                                + cpr.launchingApp);
7945                    }
7946                    if (conn != null) {
7947                        conn.waiting = true;
7948                    }
7949                    cpr.wait();
7950                } catch (InterruptedException ex) {
7951                } finally {
7952                    if (conn != null) {
7953                        conn.waiting = false;
7954                    }
7955                }
7956            }
7957        }
7958        return cpr != null ? cpr.newHolder(conn) : null;
7959    }
7960
7961    public final ContentProviderHolder getContentProvider(
7962            IApplicationThread caller, String name, int userId, boolean stable) {
7963        enforceNotIsolatedCaller("getContentProvider");
7964        if (caller == null) {
7965            String msg = "null IApplicationThread when getting content provider "
7966                    + name;
7967            Slog.w(TAG, msg);
7968            throw new SecurityException(msg);
7969        }
7970
7971        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7972                false, true, "getContentProvider", null);
7973        return getContentProviderImpl(caller, name, null, stable, userId);
7974    }
7975
7976    public ContentProviderHolder getContentProviderExternal(
7977            String name, int userId, IBinder token) {
7978        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7979            "Do not have permission in call getContentProviderExternal()");
7980        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7981                false, true, "getContentProvider", null);
7982        return getContentProviderExternalUnchecked(name, token, userId);
7983    }
7984
7985    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7986            IBinder token, int userId) {
7987        return getContentProviderImpl(null, name, token, true, userId);
7988    }
7989
7990    /**
7991     * Drop a content provider from a ProcessRecord's bookkeeping
7992     */
7993    public void removeContentProvider(IBinder connection, boolean stable) {
7994        enforceNotIsolatedCaller("removeContentProvider");
7995        long ident = Binder.clearCallingIdentity();
7996        try {
7997            synchronized (this) {
7998                ContentProviderConnection conn;
7999                try {
8000                    conn = (ContentProviderConnection)connection;
8001                } catch (ClassCastException e) {
8002                    String msg ="removeContentProvider: " + connection
8003                            + " not a ContentProviderConnection";
8004                    Slog.w(TAG, msg);
8005                    throw new IllegalArgumentException(msg);
8006                }
8007                if (conn == null) {
8008                    throw new NullPointerException("connection is null");
8009                }
8010                if (decProviderCountLocked(conn, null, null, stable)) {
8011                    updateOomAdjLocked();
8012                }
8013            }
8014        } finally {
8015            Binder.restoreCallingIdentity(ident);
8016        }
8017    }
8018
8019    public void removeContentProviderExternal(String name, IBinder token) {
8020        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8021            "Do not have permission in call removeContentProviderExternal()");
8022        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8023    }
8024
8025    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8026        synchronized (this) {
8027            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8028            if(cpr == null) {
8029                //remove from mProvidersByClass
8030                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8031                return;
8032            }
8033
8034            //update content provider record entry info
8035            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8036            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8037            if (localCpr.hasExternalProcessHandles()) {
8038                if (localCpr.removeExternalProcessHandleLocked(token)) {
8039                    updateOomAdjLocked();
8040                } else {
8041                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8042                            + " with no external reference for token: "
8043                            + token + ".");
8044                }
8045            } else {
8046                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8047                        + " with no external references.");
8048            }
8049        }
8050    }
8051
8052    public final void publishContentProviders(IApplicationThread caller,
8053            List<ContentProviderHolder> providers) {
8054        if (providers == null) {
8055            return;
8056        }
8057
8058        enforceNotIsolatedCaller("publishContentProviders");
8059        synchronized (this) {
8060            final ProcessRecord r = getRecordForAppLocked(caller);
8061            if (DEBUG_MU)
8062                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8063            if (r == null) {
8064                throw new SecurityException(
8065                        "Unable to find app for caller " + caller
8066                      + " (pid=" + Binder.getCallingPid()
8067                      + ") when publishing content providers");
8068            }
8069
8070            final long origId = Binder.clearCallingIdentity();
8071
8072            final int N = providers.size();
8073            for (int i=0; i<N; i++) {
8074                ContentProviderHolder src = providers.get(i);
8075                if (src == null || src.info == null || src.provider == null) {
8076                    continue;
8077                }
8078                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8079                if (DEBUG_MU)
8080                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8081                if (dst != null) {
8082                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8083                    mProviderMap.putProviderByClass(comp, dst);
8084                    String names[] = dst.info.authority.split(";");
8085                    for (int j = 0; j < names.length; j++) {
8086                        mProviderMap.putProviderByName(names[j], dst);
8087                    }
8088
8089                    int NL = mLaunchingProviders.size();
8090                    int j;
8091                    for (j=0; j<NL; j++) {
8092                        if (mLaunchingProviders.get(j) == dst) {
8093                            mLaunchingProviders.remove(j);
8094                            j--;
8095                            NL--;
8096                        }
8097                    }
8098                    synchronized (dst) {
8099                        dst.provider = src.provider;
8100                        dst.proc = r;
8101                        dst.notifyAll();
8102                    }
8103                    updateOomAdjLocked(r);
8104                }
8105            }
8106
8107            Binder.restoreCallingIdentity(origId);
8108        }
8109    }
8110
8111    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8112        ContentProviderConnection conn;
8113        try {
8114            conn = (ContentProviderConnection)connection;
8115        } catch (ClassCastException e) {
8116            String msg ="refContentProvider: " + connection
8117                    + " not a ContentProviderConnection";
8118            Slog.w(TAG, msg);
8119            throw new IllegalArgumentException(msg);
8120        }
8121        if (conn == null) {
8122            throw new NullPointerException("connection is null");
8123        }
8124
8125        synchronized (this) {
8126            if (stable > 0) {
8127                conn.numStableIncs += stable;
8128            }
8129            stable = conn.stableCount + stable;
8130            if (stable < 0) {
8131                throw new IllegalStateException("stableCount < 0: " + stable);
8132            }
8133
8134            if (unstable > 0) {
8135                conn.numUnstableIncs += unstable;
8136            }
8137            unstable = conn.unstableCount + unstable;
8138            if (unstable < 0) {
8139                throw new IllegalStateException("unstableCount < 0: " + unstable);
8140            }
8141
8142            if ((stable+unstable) <= 0) {
8143                throw new IllegalStateException("ref counts can't go to zero here: stable="
8144                        + stable + " unstable=" + unstable);
8145            }
8146            conn.stableCount = stable;
8147            conn.unstableCount = unstable;
8148            return !conn.dead;
8149        }
8150    }
8151
8152    public void unstableProviderDied(IBinder connection) {
8153        ContentProviderConnection conn;
8154        try {
8155            conn = (ContentProviderConnection)connection;
8156        } catch (ClassCastException e) {
8157            String msg ="refContentProvider: " + connection
8158                    + " not a ContentProviderConnection";
8159            Slog.w(TAG, msg);
8160            throw new IllegalArgumentException(msg);
8161        }
8162        if (conn == null) {
8163            throw new NullPointerException("connection is null");
8164        }
8165
8166        // Safely retrieve the content provider associated with the connection.
8167        IContentProvider provider;
8168        synchronized (this) {
8169            provider = conn.provider.provider;
8170        }
8171
8172        if (provider == null) {
8173            // Um, yeah, we're way ahead of you.
8174            return;
8175        }
8176
8177        // Make sure the caller is being honest with us.
8178        if (provider.asBinder().pingBinder()) {
8179            // Er, no, still looks good to us.
8180            synchronized (this) {
8181                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8182                        + " says " + conn + " died, but we don't agree");
8183                return;
8184            }
8185        }
8186
8187        // Well look at that!  It's dead!
8188        synchronized (this) {
8189            if (conn.provider.provider != provider) {
8190                // But something changed...  good enough.
8191                return;
8192            }
8193
8194            ProcessRecord proc = conn.provider.proc;
8195            if (proc == null || proc.thread == null) {
8196                // Seems like the process is already cleaned up.
8197                return;
8198            }
8199
8200            // As far as we're concerned, this is just like receiving a
8201            // death notification...  just a bit prematurely.
8202            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8203                    + ") early provider death");
8204            final long ident = Binder.clearCallingIdentity();
8205            try {
8206                appDiedLocked(proc, proc.pid, proc.thread);
8207            } finally {
8208                Binder.restoreCallingIdentity(ident);
8209            }
8210        }
8211    }
8212
8213    @Override
8214    public void appNotRespondingViaProvider(IBinder connection) {
8215        enforceCallingPermission(
8216                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8217
8218        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8219        if (conn == null) {
8220            Slog.w(TAG, "ContentProviderConnection is null");
8221            return;
8222        }
8223
8224        final ProcessRecord host = conn.provider.proc;
8225        if (host == null) {
8226            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8227            return;
8228        }
8229
8230        final long token = Binder.clearCallingIdentity();
8231        try {
8232            appNotResponding(host, null, null, false, "ContentProvider not responding");
8233        } finally {
8234            Binder.restoreCallingIdentity(token);
8235        }
8236    }
8237
8238    public final void installSystemProviders() {
8239        List<ProviderInfo> providers;
8240        synchronized (this) {
8241            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8242            providers = generateApplicationProvidersLocked(app);
8243            if (providers != null) {
8244                for (int i=providers.size()-1; i>=0; i--) {
8245                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8246                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8247                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8248                                + ": not system .apk");
8249                        providers.remove(i);
8250                    }
8251                }
8252            }
8253        }
8254        if (providers != null) {
8255            mSystemThread.installSystemProviders(providers);
8256        }
8257
8258        mCoreSettingsObserver = new CoreSettingsObserver(this);
8259
8260        mUsageStatsService.monitorPackages();
8261    }
8262
8263    /**
8264     * Allows app to retrieve the MIME type of a URI without having permission
8265     * to access its content provider.
8266     *
8267     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8268     *
8269     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8270     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8271     */
8272    public String getProviderMimeType(Uri uri, int userId) {
8273        enforceNotIsolatedCaller("getProviderMimeType");
8274        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8275                userId, false, true, "getProviderMimeType", null);
8276        final String name = uri.getAuthority();
8277        final long ident = Binder.clearCallingIdentity();
8278        ContentProviderHolder holder = null;
8279
8280        try {
8281            holder = getContentProviderExternalUnchecked(name, null, userId);
8282            if (holder != null) {
8283                return holder.provider.getType(uri);
8284            }
8285        } catch (RemoteException e) {
8286            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8287            return null;
8288        } finally {
8289            if (holder != null) {
8290                removeContentProviderExternalUnchecked(name, null, userId);
8291            }
8292            Binder.restoreCallingIdentity(ident);
8293        }
8294
8295        return null;
8296    }
8297
8298    // =========================================================
8299    // GLOBAL MANAGEMENT
8300    // =========================================================
8301
8302    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8303            boolean isolated) {
8304        String proc = customProcess != null ? customProcess : info.processName;
8305        BatteryStatsImpl.Uid.Proc ps = null;
8306        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8307        int uid = info.uid;
8308        if (isolated) {
8309            int userId = UserHandle.getUserId(uid);
8310            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8311            while (true) {
8312                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8313                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8314                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8315                }
8316                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8317                mNextIsolatedProcessUid++;
8318                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8319                    // No process for this uid, use it.
8320                    break;
8321                }
8322                stepsLeft--;
8323                if (stepsLeft <= 0) {
8324                    return null;
8325                }
8326            }
8327        }
8328        return new ProcessRecord(stats, info, proc, uid);
8329    }
8330
8331    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8332        ProcessRecord app;
8333        if (!isolated) {
8334            app = getProcessRecordLocked(info.processName, info.uid, true);
8335        } else {
8336            app = null;
8337        }
8338
8339        if (app == null) {
8340            app = newProcessRecordLocked(info, null, isolated);
8341            mProcessNames.put(info.processName, app.uid, app);
8342            if (isolated) {
8343                mIsolatedProcesses.put(app.uid, app);
8344            }
8345            updateLruProcessLocked(app, false, null);
8346            updateOomAdjLocked();
8347        }
8348
8349        // This package really, really can not be stopped.
8350        try {
8351            AppGlobals.getPackageManager().setPackageStoppedState(
8352                    info.packageName, false, UserHandle.getUserId(app.uid));
8353        } catch (RemoteException e) {
8354        } catch (IllegalArgumentException e) {
8355            Slog.w(TAG, "Failed trying to unstop package "
8356                    + info.packageName + ": " + e);
8357        }
8358
8359        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8360                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8361            app.persistent = true;
8362            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8363        }
8364        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8365            mPersistentStartingProcesses.add(app);
8366            startProcessLocked(app, "added application", app.processName);
8367        }
8368
8369        return app;
8370    }
8371
8372    public void unhandledBack() {
8373        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8374                "unhandledBack()");
8375
8376        synchronized(this) {
8377            final long origId = Binder.clearCallingIdentity();
8378            try {
8379                getFocusedStack().unhandledBackLocked();
8380            } finally {
8381                Binder.restoreCallingIdentity(origId);
8382            }
8383        }
8384    }
8385
8386    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8387        enforceNotIsolatedCaller("openContentUri");
8388        final int userId = UserHandle.getCallingUserId();
8389        String name = uri.getAuthority();
8390        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8391        ParcelFileDescriptor pfd = null;
8392        if (cph != null) {
8393            // We record the binder invoker's uid in thread-local storage before
8394            // going to the content provider to open the file.  Later, in the code
8395            // that handles all permissions checks, we look for this uid and use
8396            // that rather than the Activity Manager's own uid.  The effect is that
8397            // we do the check against the caller's permissions even though it looks
8398            // to the content provider like the Activity Manager itself is making
8399            // the request.
8400            sCallerIdentity.set(new Identity(
8401                    Binder.getCallingPid(), Binder.getCallingUid()));
8402            try {
8403                pfd = cph.provider.openFile(null, uri, "r", null);
8404            } catch (FileNotFoundException e) {
8405                // do nothing; pfd will be returned null
8406            } finally {
8407                // Ensure that whatever happens, we clean up the identity state
8408                sCallerIdentity.remove();
8409            }
8410
8411            // We've got the fd now, so we're done with the provider.
8412            removeContentProviderExternalUnchecked(name, null, userId);
8413        } else {
8414            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8415        }
8416        return pfd;
8417    }
8418
8419    // Actually is sleeping or shutting down or whatever else in the future
8420    // is an inactive state.
8421    public boolean isSleepingOrShuttingDown() {
8422        return mSleeping || mShuttingDown;
8423    }
8424
8425    public void goingToSleep() {
8426        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8427                != PackageManager.PERMISSION_GRANTED) {
8428            throw new SecurityException("Requires permission "
8429                    + android.Manifest.permission.DEVICE_POWER);
8430        }
8431
8432        synchronized(this) {
8433            mWentToSleep = true;
8434            updateEventDispatchingLocked();
8435
8436            if (!mSleeping) {
8437                mSleeping = true;
8438                mStackSupervisor.goingToSleepLocked();
8439
8440                // Initialize the wake times of all processes.
8441                checkExcessivePowerUsageLocked(false);
8442                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8443                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8444                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8445            }
8446        }
8447    }
8448
8449    @Override
8450    public boolean shutdown(int timeout) {
8451        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8452                != PackageManager.PERMISSION_GRANTED) {
8453            throw new SecurityException("Requires permission "
8454                    + android.Manifest.permission.SHUTDOWN);
8455        }
8456
8457        boolean timedout = false;
8458
8459        synchronized(this) {
8460            mShuttingDown = true;
8461            updateEventDispatchingLocked();
8462            timedout = mStackSupervisor.shutdownLocked(timeout);
8463        }
8464
8465        mAppOpsService.shutdown();
8466        mUsageStatsService.shutdown();
8467        mBatteryStatsService.shutdown();
8468        synchronized (this) {
8469            mProcessStats.shutdownLocked();
8470        }
8471
8472        return timedout;
8473    }
8474
8475    public final void activitySlept(IBinder token) {
8476        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8477
8478        final long origId = Binder.clearCallingIdentity();
8479
8480        synchronized (this) {
8481            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8482            if (r != null) {
8483                mStackSupervisor.activitySleptLocked(r);
8484            }
8485        }
8486
8487        Binder.restoreCallingIdentity(origId);
8488    }
8489
8490    void logLockScreen(String msg) {
8491        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8492                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8493                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8494                mStackSupervisor.mDismissKeyguardOnNextActivity);
8495    }
8496
8497    private void comeOutOfSleepIfNeededLocked() {
8498        if (!mWentToSleep && !mLockScreenShown) {
8499            if (mSleeping) {
8500                mSleeping = false;
8501                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8502            }
8503        }
8504    }
8505
8506    public void wakingUp() {
8507        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8508                != PackageManager.PERMISSION_GRANTED) {
8509            throw new SecurityException("Requires permission "
8510                    + android.Manifest.permission.DEVICE_POWER);
8511        }
8512
8513        synchronized(this) {
8514            mWentToSleep = false;
8515            updateEventDispatchingLocked();
8516            comeOutOfSleepIfNeededLocked();
8517        }
8518    }
8519
8520    private void updateEventDispatchingLocked() {
8521        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8522    }
8523
8524    public void setLockScreenShown(boolean shown) {
8525        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8526                != PackageManager.PERMISSION_GRANTED) {
8527            throw new SecurityException("Requires permission "
8528                    + android.Manifest.permission.DEVICE_POWER);
8529        }
8530
8531        synchronized(this) {
8532            long ident = Binder.clearCallingIdentity();
8533            try {
8534                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8535                mLockScreenShown = shown;
8536                comeOutOfSleepIfNeededLocked();
8537            } finally {
8538                Binder.restoreCallingIdentity(ident);
8539            }
8540        }
8541    }
8542
8543    public void stopAppSwitches() {
8544        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8545                != PackageManager.PERMISSION_GRANTED) {
8546            throw new SecurityException("Requires permission "
8547                    + android.Manifest.permission.STOP_APP_SWITCHES);
8548        }
8549
8550        synchronized(this) {
8551            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8552                    + APP_SWITCH_DELAY_TIME;
8553            mDidAppSwitch = false;
8554            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8555            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8556            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8557        }
8558    }
8559
8560    public void resumeAppSwitches() {
8561        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8562                != PackageManager.PERMISSION_GRANTED) {
8563            throw new SecurityException("Requires permission "
8564                    + android.Manifest.permission.STOP_APP_SWITCHES);
8565        }
8566
8567        synchronized(this) {
8568            // Note that we don't execute any pending app switches... we will
8569            // let those wait until either the timeout, or the next start
8570            // activity request.
8571            mAppSwitchesAllowedTime = 0;
8572        }
8573    }
8574
8575    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8576            String name) {
8577        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8578            return true;
8579        }
8580
8581        final int perm = checkComponentPermission(
8582                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8583                callingUid, -1, true);
8584        if (perm == PackageManager.PERMISSION_GRANTED) {
8585            return true;
8586        }
8587
8588        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8589        return false;
8590    }
8591
8592    public void setDebugApp(String packageName, boolean waitForDebugger,
8593            boolean persistent) {
8594        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8595                "setDebugApp()");
8596
8597        long ident = Binder.clearCallingIdentity();
8598        try {
8599            // Note that this is not really thread safe if there are multiple
8600            // callers into it at the same time, but that's not a situation we
8601            // care about.
8602            if (persistent) {
8603                final ContentResolver resolver = mContext.getContentResolver();
8604                Settings.Global.putString(
8605                    resolver, Settings.Global.DEBUG_APP,
8606                    packageName);
8607                Settings.Global.putInt(
8608                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8609                    waitForDebugger ? 1 : 0);
8610            }
8611
8612            synchronized (this) {
8613                if (!persistent) {
8614                    mOrigDebugApp = mDebugApp;
8615                    mOrigWaitForDebugger = mWaitForDebugger;
8616                }
8617                mDebugApp = packageName;
8618                mWaitForDebugger = waitForDebugger;
8619                mDebugTransient = !persistent;
8620                if (packageName != null) {
8621                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8622                            false, UserHandle.USER_ALL, "set debug app");
8623                }
8624            }
8625        } finally {
8626            Binder.restoreCallingIdentity(ident);
8627        }
8628    }
8629
8630    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8631        synchronized (this) {
8632            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8633            if (!isDebuggable) {
8634                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8635                    throw new SecurityException("Process not debuggable: " + app.packageName);
8636                }
8637            }
8638
8639            mOpenGlTraceApp = processName;
8640        }
8641    }
8642
8643    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8644            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8645        synchronized (this) {
8646            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8647            if (!isDebuggable) {
8648                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8649                    throw new SecurityException("Process not debuggable: " + app.packageName);
8650                }
8651            }
8652            mProfileApp = processName;
8653            mProfileFile = profileFile;
8654            if (mProfileFd != null) {
8655                try {
8656                    mProfileFd.close();
8657                } catch (IOException e) {
8658                }
8659                mProfileFd = null;
8660            }
8661            mProfileFd = profileFd;
8662            mProfileType = 0;
8663            mAutoStopProfiler = autoStopProfiler;
8664        }
8665    }
8666
8667    @Override
8668    public void setAlwaysFinish(boolean enabled) {
8669        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8670                "setAlwaysFinish()");
8671
8672        Settings.Global.putInt(
8673                mContext.getContentResolver(),
8674                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8675
8676        synchronized (this) {
8677            mAlwaysFinishActivities = enabled;
8678        }
8679    }
8680
8681    @Override
8682    public void setActivityController(IActivityController controller) {
8683        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8684                "setActivityController()");
8685        synchronized (this) {
8686            mController = controller;
8687            Watchdog.getInstance().setActivityController(controller);
8688        }
8689    }
8690
8691    @Override
8692    public void setUserIsMonkey(boolean userIsMonkey) {
8693        synchronized (this) {
8694            synchronized (mPidsSelfLocked) {
8695                final int callingPid = Binder.getCallingPid();
8696                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8697                if (precessRecord == null) {
8698                    throw new SecurityException("Unknown process: " + callingPid);
8699                }
8700                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8701                    throw new SecurityException("Only an instrumentation process "
8702                            + "with a UiAutomation can call setUserIsMonkey");
8703                }
8704            }
8705            mUserIsMonkey = userIsMonkey;
8706        }
8707    }
8708
8709    @Override
8710    public boolean isUserAMonkey() {
8711        synchronized (this) {
8712            // If there is a controller also implies the user is a monkey.
8713            return (mUserIsMonkey || mController != null);
8714        }
8715    }
8716
8717    public void requestBugReport() {
8718        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8719        SystemProperties.set("ctl.start", "bugreport");
8720    }
8721
8722    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8723        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8724    }
8725
8726    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8727        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8728            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8729        }
8730        return KEY_DISPATCHING_TIMEOUT;
8731    }
8732
8733    @Override
8734    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8735        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8736                != PackageManager.PERMISSION_GRANTED) {
8737            throw new SecurityException("Requires permission "
8738                    + android.Manifest.permission.FILTER_EVENTS);
8739        }
8740        ProcessRecord proc;
8741        long timeout;
8742        synchronized (this) {
8743            synchronized (mPidsSelfLocked) {
8744                proc = mPidsSelfLocked.get(pid);
8745            }
8746            timeout = getInputDispatchingTimeoutLocked(proc);
8747        }
8748
8749        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8750            return -1;
8751        }
8752
8753        return timeout;
8754    }
8755
8756    /**
8757     * Handle input dispatching timeouts.
8758     * Returns whether input dispatching should be aborted or not.
8759     */
8760    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8761            final ActivityRecord activity, final ActivityRecord parent,
8762            final boolean aboveSystem, String reason) {
8763        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8764                != PackageManager.PERMISSION_GRANTED) {
8765            throw new SecurityException("Requires permission "
8766                    + android.Manifest.permission.FILTER_EVENTS);
8767        }
8768
8769        final String annotation;
8770        if (reason == null) {
8771            annotation = "Input dispatching timed out";
8772        } else {
8773            annotation = "Input dispatching timed out (" + reason + ")";
8774        }
8775
8776        if (proc != null) {
8777            synchronized (this) {
8778                if (proc.debugging) {
8779                    return false;
8780                }
8781
8782                if (mDidDexOpt) {
8783                    // Give more time since we were dexopting.
8784                    mDidDexOpt = false;
8785                    return false;
8786                }
8787
8788                if (proc.instrumentationClass != null) {
8789                    Bundle info = new Bundle();
8790                    info.putString("shortMsg", "keyDispatchingTimedOut");
8791                    info.putString("longMsg", annotation);
8792                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8793                    return true;
8794                }
8795            }
8796            mHandler.post(new Runnable() {
8797                @Override
8798                public void run() {
8799                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8800                }
8801            });
8802        }
8803
8804        return true;
8805    }
8806
8807    public Bundle getAssistContextExtras(int requestType) {
8808        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8809                "getAssistContextExtras()");
8810        PendingAssistExtras pae;
8811        Bundle extras = new Bundle();
8812        synchronized (this) {
8813            ActivityRecord activity = getFocusedStack().mResumedActivity;
8814            if (activity == null) {
8815                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8816                return null;
8817            }
8818            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8819            if (activity.app == null || activity.app.thread == null) {
8820                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8821                return extras;
8822            }
8823            if (activity.app.pid == Binder.getCallingPid()) {
8824                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8825                return extras;
8826            }
8827            pae = new PendingAssistExtras(activity);
8828            try {
8829                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8830                        requestType);
8831                mPendingAssistExtras.add(pae);
8832                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8833            } catch (RemoteException e) {
8834                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8835                return extras;
8836            }
8837        }
8838        synchronized (pae) {
8839            while (!pae.haveResult) {
8840                try {
8841                    pae.wait();
8842                } catch (InterruptedException e) {
8843                }
8844            }
8845            if (pae.result != null) {
8846                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8847            }
8848        }
8849        synchronized (this) {
8850            mPendingAssistExtras.remove(pae);
8851            mHandler.removeCallbacks(pae);
8852        }
8853        return extras;
8854    }
8855
8856    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8857        PendingAssistExtras pae = (PendingAssistExtras)token;
8858        synchronized (pae) {
8859            pae.result = extras;
8860            pae.haveResult = true;
8861            pae.notifyAll();
8862        }
8863    }
8864
8865    public void registerProcessObserver(IProcessObserver observer) {
8866        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8867                "registerProcessObserver()");
8868        synchronized (this) {
8869            mProcessObservers.register(observer);
8870        }
8871    }
8872
8873    @Override
8874    public void unregisterProcessObserver(IProcessObserver observer) {
8875        synchronized (this) {
8876            mProcessObservers.unregister(observer);
8877        }
8878    }
8879
8880    @Override
8881    public boolean convertFromTranslucent(IBinder token) {
8882        final long origId = Binder.clearCallingIdentity();
8883        try {
8884            synchronized (this) {
8885                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8886                if (r == null) {
8887                    return false;
8888                }
8889                if (r.changeWindowTranslucency(true)) {
8890                    mWindowManager.setAppFullscreen(token, true);
8891                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8892                    return true;
8893                }
8894                return false;
8895            }
8896        } finally {
8897            Binder.restoreCallingIdentity(origId);
8898        }
8899    }
8900
8901    @Override
8902    public boolean convertToTranslucent(IBinder token) {
8903        final long origId = Binder.clearCallingIdentity();
8904        try {
8905            synchronized (this) {
8906                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8907                if (r == null) {
8908                    return false;
8909                }
8910                if (r.changeWindowTranslucency(false)) {
8911                    r.task.stack.convertToTranslucent(r);
8912                    mWindowManager.setAppFullscreen(token, false);
8913                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8914                    return true;
8915                }
8916                return false;
8917            }
8918        } finally {
8919            Binder.restoreCallingIdentity(origId);
8920        }
8921    }
8922
8923    @Override
8924    public void setImmersive(IBinder token, boolean immersive) {
8925        synchronized(this) {
8926            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8927            if (r == null) {
8928                throw new IllegalArgumentException();
8929            }
8930            r.immersive = immersive;
8931
8932            // update associated state if we're frontmost
8933            if (r == mFocusedActivity) {
8934                if (DEBUG_IMMERSIVE) {
8935                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8936                }
8937                applyUpdateLockStateLocked(r);
8938            }
8939        }
8940    }
8941
8942    @Override
8943    public boolean isImmersive(IBinder token) {
8944        synchronized (this) {
8945            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8946            if (r == null) {
8947                throw new IllegalArgumentException();
8948            }
8949            return r.immersive;
8950        }
8951    }
8952
8953    public boolean isTopActivityImmersive() {
8954        enforceNotIsolatedCaller("startActivity");
8955        synchronized (this) {
8956            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8957            return (r != null) ? r.immersive : false;
8958        }
8959    }
8960
8961    public final void enterSafeMode() {
8962        synchronized(this) {
8963            // It only makes sense to do this before the system is ready
8964            // and started launching other packages.
8965            if (!mSystemReady) {
8966                try {
8967                    AppGlobals.getPackageManager().enterSafeMode();
8968                } catch (RemoteException e) {
8969                }
8970            }
8971
8972            mSafeMode = true;
8973        }
8974    }
8975
8976    public final void showSafeModeOverlay() {
8977        View v = LayoutInflater.from(mContext).inflate(
8978                com.android.internal.R.layout.safe_mode, null);
8979        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8980        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8981        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8982        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8983        lp.gravity = Gravity.BOTTOM | Gravity.START;
8984        lp.format = v.getBackground().getOpacity();
8985        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8986                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8987        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8988        ((WindowManager)mContext.getSystemService(
8989                Context.WINDOW_SERVICE)).addView(v, lp);
8990    }
8991
8992    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8993        if (!(sender instanceof PendingIntentRecord)) {
8994            return;
8995        }
8996        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8997        synchronized (stats) {
8998            if (mBatteryStatsService.isOnBattery()) {
8999                mBatteryStatsService.enforceCallingPermission();
9000                PendingIntentRecord rec = (PendingIntentRecord)sender;
9001                int MY_UID = Binder.getCallingUid();
9002                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9003                BatteryStatsImpl.Uid.Pkg pkg =
9004                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9005                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9006                pkg.incWakeupsLocked();
9007            }
9008        }
9009    }
9010
9011    public boolean killPids(int[] pids, String pReason, boolean secure) {
9012        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9013            throw new SecurityException("killPids only available to the system");
9014        }
9015        String reason = (pReason == null) ? "Unknown" : pReason;
9016        // XXX Note: don't acquire main activity lock here, because the window
9017        // manager calls in with its locks held.
9018
9019        boolean killed = false;
9020        synchronized (mPidsSelfLocked) {
9021            int[] types = new int[pids.length];
9022            int worstType = 0;
9023            for (int i=0; i<pids.length; i++) {
9024                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9025                if (proc != null) {
9026                    int type = proc.setAdj;
9027                    types[i] = type;
9028                    if (type > worstType) {
9029                        worstType = type;
9030                    }
9031                }
9032            }
9033
9034            // If the worst oom_adj is somewhere in the cached proc LRU range,
9035            // then constrain it so we will kill all cached procs.
9036            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9037                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9038                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9039            }
9040
9041            // If this is not a secure call, don't let it kill processes that
9042            // are important.
9043            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9044                worstType = ProcessList.SERVICE_ADJ;
9045            }
9046
9047            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9048            for (int i=0; i<pids.length; i++) {
9049                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9050                if (proc == null) {
9051                    continue;
9052                }
9053                int adj = proc.setAdj;
9054                if (adj >= worstType && !proc.killedByAm) {
9055                    killUnneededProcessLocked(proc, reason);
9056                    killed = true;
9057                }
9058            }
9059        }
9060        return killed;
9061    }
9062
9063    @Override
9064    public void killUid(int uid, String reason) {
9065        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9066            throw new SecurityException("killUid only available to the system");
9067        }
9068        synchronized (this) {
9069            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9070                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9071                    reason != null ? reason : "kill uid");
9072        }
9073    }
9074
9075    @Override
9076    public boolean killProcessesBelowForeground(String reason) {
9077        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9078            throw new SecurityException("killProcessesBelowForeground() only available to system");
9079        }
9080
9081        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9082    }
9083
9084    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9085        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9086            throw new SecurityException("killProcessesBelowAdj() only available to system");
9087        }
9088
9089        boolean killed = false;
9090        synchronized (mPidsSelfLocked) {
9091            final int size = mPidsSelfLocked.size();
9092            for (int i = 0; i < size; i++) {
9093                final int pid = mPidsSelfLocked.keyAt(i);
9094                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9095                if (proc == null) continue;
9096
9097                final int adj = proc.setAdj;
9098                if (adj > belowAdj && !proc.killedByAm) {
9099                    killUnneededProcessLocked(proc, reason);
9100                    killed = true;
9101                }
9102            }
9103        }
9104        return killed;
9105    }
9106
9107    @Override
9108    public void hang(final IBinder who, boolean allowRestart) {
9109        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9110                != PackageManager.PERMISSION_GRANTED) {
9111            throw new SecurityException("Requires permission "
9112                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9113        }
9114
9115        final IBinder.DeathRecipient death = new DeathRecipient() {
9116            @Override
9117            public void binderDied() {
9118                synchronized (this) {
9119                    notifyAll();
9120                }
9121            }
9122        };
9123
9124        try {
9125            who.linkToDeath(death, 0);
9126        } catch (RemoteException e) {
9127            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9128            return;
9129        }
9130
9131        synchronized (this) {
9132            Watchdog.getInstance().setAllowRestart(allowRestart);
9133            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9134            synchronized (death) {
9135                while (who.isBinderAlive()) {
9136                    try {
9137                        death.wait();
9138                    } catch (InterruptedException e) {
9139                    }
9140                }
9141            }
9142            Watchdog.getInstance().setAllowRestart(true);
9143        }
9144    }
9145
9146    @Override
9147    public void restart() {
9148        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9149                != PackageManager.PERMISSION_GRANTED) {
9150            throw new SecurityException("Requires permission "
9151                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9152        }
9153
9154        Log.i(TAG, "Sending shutdown broadcast...");
9155
9156        BroadcastReceiver br = new BroadcastReceiver() {
9157            @Override public void onReceive(Context context, Intent intent) {
9158                // Now the broadcast is done, finish up the low-level shutdown.
9159                Log.i(TAG, "Shutting down activity manager...");
9160                shutdown(10000);
9161                Log.i(TAG, "Shutdown complete, restarting!");
9162                Process.killProcess(Process.myPid());
9163                System.exit(10);
9164            }
9165        };
9166
9167        // First send the high-level shut down broadcast.
9168        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9169        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9170        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9171        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9172        mContext.sendOrderedBroadcastAsUser(intent,
9173                UserHandle.ALL, null, br, mHandler, 0, null, null);
9174        */
9175        br.onReceive(mContext, intent);
9176    }
9177
9178    private long getLowRamTimeSinceIdle(long now) {
9179        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9180    }
9181
9182    @Override
9183    public void performIdleMaintenance() {
9184        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9185                != PackageManager.PERMISSION_GRANTED) {
9186            throw new SecurityException("Requires permission "
9187                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9188        }
9189
9190        synchronized (this) {
9191            final long now = SystemClock.uptimeMillis();
9192            final long timeSinceLastIdle = now - mLastIdleTime;
9193            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9194            mLastIdleTime = now;
9195            mLowRamTimeSinceLastIdle = 0;
9196            if (mLowRamStartTime != 0) {
9197                mLowRamStartTime = now;
9198            }
9199
9200            StringBuilder sb = new StringBuilder(128);
9201            sb.append("Idle maintenance over ");
9202            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9203            sb.append(" low RAM for ");
9204            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9205            Slog.i(TAG, sb.toString());
9206
9207            // If at least 1/3 of our time since the last idle period has been spent
9208            // with RAM low, then we want to kill processes.
9209            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9210
9211            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9212                ProcessRecord proc = mLruProcesses.get(i);
9213                if (proc.notCachedSinceIdle) {
9214                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9215                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9216                        if (doKilling && proc.initialIdlePss != 0
9217                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9218                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9219                                    + " from " + proc.initialIdlePss + ")");
9220                        }
9221                    }
9222                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9223                    proc.notCachedSinceIdle = true;
9224                    proc.initialIdlePss = 0;
9225                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9226                            mSleeping, now);
9227                }
9228            }
9229
9230            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9231            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9232        }
9233    }
9234
9235    public final void startRunning(String pkg, String cls, String action,
9236            String data) {
9237        synchronized(this) {
9238            if (mStartRunning) {
9239                return;
9240            }
9241            mStartRunning = true;
9242            mTopComponent = pkg != null && cls != null
9243                    ? new ComponentName(pkg, cls) : null;
9244            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9245            mTopData = data;
9246            if (!mSystemReady) {
9247                return;
9248            }
9249        }
9250
9251        systemReady(null);
9252    }
9253
9254    private void retrieveSettings() {
9255        final ContentResolver resolver = mContext.getContentResolver();
9256        String debugApp = Settings.Global.getString(
9257            resolver, Settings.Global.DEBUG_APP);
9258        boolean waitForDebugger = Settings.Global.getInt(
9259            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9260        boolean alwaysFinishActivities = Settings.Global.getInt(
9261            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9262        boolean forceRtl = Settings.Global.getInt(
9263                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9264        // Transfer any global setting for forcing RTL layout, into a System Property
9265        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9266
9267        Configuration configuration = new Configuration();
9268        Settings.System.getConfiguration(resolver, configuration);
9269        if (forceRtl) {
9270            // This will take care of setting the correct layout direction flags
9271            configuration.setLayoutDirection(configuration.locale);
9272        }
9273
9274        synchronized (this) {
9275            mDebugApp = mOrigDebugApp = debugApp;
9276            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9277            mAlwaysFinishActivities = alwaysFinishActivities;
9278            // This happens before any activities are started, so we can
9279            // change mConfiguration in-place.
9280            updateConfigurationLocked(configuration, null, false, true);
9281            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9282        }
9283    }
9284
9285    public boolean testIsSystemReady() {
9286        // no need to synchronize(this) just to read & return the value
9287        return mSystemReady;
9288    }
9289
9290    private static File getCalledPreBootReceiversFile() {
9291        File dataDir = Environment.getDataDirectory();
9292        File systemDir = new File(dataDir, "system");
9293        File fname = new File(systemDir, "called_pre_boots.dat");
9294        return fname;
9295    }
9296
9297    static final int LAST_DONE_VERSION = 10000;
9298
9299    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9300        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9301        File file = getCalledPreBootReceiversFile();
9302        FileInputStream fis = null;
9303        try {
9304            fis = new FileInputStream(file);
9305            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9306            int fvers = dis.readInt();
9307            if (fvers == LAST_DONE_VERSION) {
9308                String vers = dis.readUTF();
9309                String codename = dis.readUTF();
9310                String build = dis.readUTF();
9311                if (android.os.Build.VERSION.RELEASE.equals(vers)
9312                        && android.os.Build.VERSION.CODENAME.equals(codename)
9313                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9314                    int num = dis.readInt();
9315                    while (num > 0) {
9316                        num--;
9317                        String pkg = dis.readUTF();
9318                        String cls = dis.readUTF();
9319                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9320                    }
9321                }
9322            }
9323        } catch (FileNotFoundException e) {
9324        } catch (IOException e) {
9325            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9326        } finally {
9327            if (fis != null) {
9328                try {
9329                    fis.close();
9330                } catch (IOException e) {
9331                }
9332            }
9333        }
9334        return lastDoneReceivers;
9335    }
9336
9337    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9338        File file = getCalledPreBootReceiversFile();
9339        FileOutputStream fos = null;
9340        DataOutputStream dos = null;
9341        try {
9342            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9343            fos = new FileOutputStream(file);
9344            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9345            dos.writeInt(LAST_DONE_VERSION);
9346            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9347            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9348            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9349            dos.writeInt(list.size());
9350            for (int i=0; i<list.size(); i++) {
9351                dos.writeUTF(list.get(i).getPackageName());
9352                dos.writeUTF(list.get(i).getClassName());
9353            }
9354        } catch (IOException e) {
9355            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9356            file.delete();
9357        } finally {
9358            FileUtils.sync(fos);
9359            if (dos != null) {
9360                try {
9361                    dos.close();
9362                } catch (IOException e) {
9363                    // TODO Auto-generated catch block
9364                    e.printStackTrace();
9365                }
9366            }
9367        }
9368    }
9369
9370    public void systemReady(final Runnable goingCallback) {
9371        synchronized(this) {
9372            if (mSystemReady) {
9373                if (goingCallback != null) goingCallback.run();
9374                return;
9375            }
9376
9377            // Check to see if there are any update receivers to run.
9378            if (!mDidUpdate) {
9379                if (mWaitingUpdate) {
9380                    return;
9381                }
9382                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9383                List<ResolveInfo> ris = null;
9384                try {
9385                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9386                            intent, null, 0, 0);
9387                } catch (RemoteException e) {
9388                }
9389                if (ris != null) {
9390                    for (int i=ris.size()-1; i>=0; i--) {
9391                        if ((ris.get(i).activityInfo.applicationInfo.flags
9392                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9393                            ris.remove(i);
9394                        }
9395                    }
9396                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9397
9398                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9399
9400                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9401                    for (int i=0; i<ris.size(); i++) {
9402                        ActivityInfo ai = ris.get(i).activityInfo;
9403                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9404                        if (lastDoneReceivers.contains(comp)) {
9405                            // We already did the pre boot receiver for this app with the current
9406                            // platform version, so don't do it again...
9407                            ris.remove(i);
9408                            i--;
9409                            // ...however, do keep it as one that has been done, so we don't
9410                            // forget about it when rewriting the file of last done receivers.
9411                            doneReceivers.add(comp);
9412                        }
9413                    }
9414
9415                    final int[] users = getUsersLocked();
9416                    for (int i=0; i<ris.size(); i++) {
9417                        ActivityInfo ai = ris.get(i).activityInfo;
9418                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9419                        doneReceivers.add(comp);
9420                        intent.setComponent(comp);
9421                        for (int j=0; j<users.length; j++) {
9422                            IIntentReceiver finisher = null;
9423                            if (i == ris.size()-1 && j == users.length-1) {
9424                                finisher = new IIntentReceiver.Stub() {
9425                                    public void performReceive(Intent intent, int resultCode,
9426                                            String data, Bundle extras, boolean ordered,
9427                                            boolean sticky, int sendingUser) {
9428                                        // The raw IIntentReceiver interface is called
9429                                        // with the AM lock held, so redispatch to
9430                                        // execute our code without the lock.
9431                                        mHandler.post(new Runnable() {
9432                                            public void run() {
9433                                                synchronized (ActivityManagerService.this) {
9434                                                    mDidUpdate = true;
9435                                                }
9436                                                writeLastDonePreBootReceivers(doneReceivers);
9437                                                showBootMessage(mContext.getText(
9438                                                        R.string.android_upgrading_complete),
9439                                                        false);
9440                                                systemReady(goingCallback);
9441                                            }
9442                                        });
9443                                    }
9444                                };
9445                            }
9446                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9447                                    + " for user " + users[j]);
9448                            broadcastIntentLocked(null, null, intent, null, finisher,
9449                                    0, null, null, null, AppOpsManager.OP_NONE,
9450                                    true, false, MY_PID, Process.SYSTEM_UID,
9451                                    users[j]);
9452                            if (finisher != null) {
9453                                mWaitingUpdate = true;
9454                            }
9455                        }
9456                    }
9457                }
9458                if (mWaitingUpdate) {
9459                    return;
9460                }
9461                mDidUpdate = true;
9462            }
9463
9464            mAppOpsService.systemReady();
9465            mSystemReady = true;
9466            if (!mStartRunning) {
9467                return;
9468            }
9469        }
9470
9471        ArrayList<ProcessRecord> procsToKill = null;
9472        synchronized(mPidsSelfLocked) {
9473            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9474                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9475                if (!isAllowedWhileBooting(proc.info)){
9476                    if (procsToKill == null) {
9477                        procsToKill = new ArrayList<ProcessRecord>();
9478                    }
9479                    procsToKill.add(proc);
9480                }
9481            }
9482        }
9483
9484        synchronized(this) {
9485            if (procsToKill != null) {
9486                for (int i=procsToKill.size()-1; i>=0; i--) {
9487                    ProcessRecord proc = procsToKill.get(i);
9488                    Slog.i(TAG, "Removing system update proc: " + proc);
9489                    removeProcessLocked(proc, true, false, "system update done");
9490                }
9491            }
9492
9493            // Now that we have cleaned up any update processes, we
9494            // are ready to start launching real processes and know that
9495            // we won't trample on them any more.
9496            mProcessesReady = true;
9497        }
9498
9499        Slog.i(TAG, "System now ready");
9500        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9501            SystemClock.uptimeMillis());
9502
9503        synchronized(this) {
9504            // Make sure we have no pre-ready processes sitting around.
9505
9506            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9507                ResolveInfo ri = mContext.getPackageManager()
9508                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9509                                STOCK_PM_FLAGS);
9510                CharSequence errorMsg = null;
9511                if (ri != null) {
9512                    ActivityInfo ai = ri.activityInfo;
9513                    ApplicationInfo app = ai.applicationInfo;
9514                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9515                        mTopAction = Intent.ACTION_FACTORY_TEST;
9516                        mTopData = null;
9517                        mTopComponent = new ComponentName(app.packageName,
9518                                ai.name);
9519                    } else {
9520                        errorMsg = mContext.getResources().getText(
9521                                com.android.internal.R.string.factorytest_not_system);
9522                    }
9523                } else {
9524                    errorMsg = mContext.getResources().getText(
9525                            com.android.internal.R.string.factorytest_no_action);
9526                }
9527                if (errorMsg != null) {
9528                    mTopAction = null;
9529                    mTopData = null;
9530                    mTopComponent = null;
9531                    Message msg = Message.obtain();
9532                    msg.what = SHOW_FACTORY_ERROR_MSG;
9533                    msg.getData().putCharSequence("msg", errorMsg);
9534                    mHandler.sendMessage(msg);
9535                }
9536            }
9537        }
9538
9539        retrieveSettings();
9540
9541        synchronized (this) {
9542            readGrantedUriPermissionsLocked();
9543        }
9544
9545        if (goingCallback != null) goingCallback.run();
9546
9547        synchronized (this) {
9548            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9549                try {
9550                    List apps = AppGlobals.getPackageManager().
9551                        getPersistentApplications(STOCK_PM_FLAGS);
9552                    if (apps != null) {
9553                        int N = apps.size();
9554                        int i;
9555                        for (i=0; i<N; i++) {
9556                            ApplicationInfo info
9557                                = (ApplicationInfo)apps.get(i);
9558                            if (info != null &&
9559                                    !info.packageName.equals("android")) {
9560                                addAppLocked(info, false);
9561                            }
9562                        }
9563                    }
9564                } catch (RemoteException ex) {
9565                    // pm is in same process, this will never happen.
9566                }
9567            }
9568
9569            // Start up initial activity.
9570            mBooting = true;
9571
9572            try {
9573                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9574                    Message msg = Message.obtain();
9575                    msg.what = SHOW_UID_ERROR_MSG;
9576                    mHandler.sendMessage(msg);
9577                }
9578            } catch (RemoteException e) {
9579            }
9580
9581            long ident = Binder.clearCallingIdentity();
9582            try {
9583                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9584                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9585                        | Intent.FLAG_RECEIVER_FOREGROUND);
9586                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9587                broadcastIntentLocked(null, null, intent,
9588                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9589                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9590                intent = new Intent(Intent.ACTION_USER_STARTING);
9591                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9592                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9593                broadcastIntentLocked(null, null, intent,
9594                        null, new IIntentReceiver.Stub() {
9595                            @Override
9596                            public void performReceive(Intent intent, int resultCode, String data,
9597                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9598                                    throws RemoteException {
9599                            }
9600                        }, 0, null, null,
9601                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9602                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9603            } finally {
9604                Binder.restoreCallingIdentity(ident);
9605            }
9606            mStackSupervisor.resumeTopActivitiesLocked();
9607            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9608        }
9609    }
9610
9611    private boolean makeAppCrashingLocked(ProcessRecord app,
9612            String shortMsg, String longMsg, String stackTrace) {
9613        app.crashing = true;
9614        app.crashingReport = generateProcessError(app,
9615                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9616        startAppProblemLocked(app);
9617        app.stopFreezingAllLocked();
9618        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9619    }
9620
9621    private void makeAppNotRespondingLocked(ProcessRecord app,
9622            String activity, String shortMsg, String longMsg) {
9623        app.notResponding = true;
9624        app.notRespondingReport = generateProcessError(app,
9625                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9626                activity, shortMsg, longMsg, null);
9627        startAppProblemLocked(app);
9628        app.stopFreezingAllLocked();
9629    }
9630
9631    /**
9632     * Generate a process error record, suitable for attachment to a ProcessRecord.
9633     *
9634     * @param app The ProcessRecord in which the error occurred.
9635     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9636     *                      ActivityManager.AppErrorStateInfo
9637     * @param activity The activity associated with the crash, if known.
9638     * @param shortMsg Short message describing the crash.
9639     * @param longMsg Long message describing the crash.
9640     * @param stackTrace Full crash stack trace, may be null.
9641     *
9642     * @return Returns a fully-formed AppErrorStateInfo record.
9643     */
9644    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9645            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9646        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9647
9648        report.condition = condition;
9649        report.processName = app.processName;
9650        report.pid = app.pid;
9651        report.uid = app.info.uid;
9652        report.tag = activity;
9653        report.shortMsg = shortMsg;
9654        report.longMsg = longMsg;
9655        report.stackTrace = stackTrace;
9656
9657        return report;
9658    }
9659
9660    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9661        synchronized (this) {
9662            app.crashing = false;
9663            app.crashingReport = null;
9664            app.notResponding = false;
9665            app.notRespondingReport = null;
9666            if (app.anrDialog == fromDialog) {
9667                app.anrDialog = null;
9668            }
9669            if (app.waitDialog == fromDialog) {
9670                app.waitDialog = null;
9671            }
9672            if (app.pid > 0 && app.pid != MY_PID) {
9673                handleAppCrashLocked(app, null, null, null);
9674                killUnneededProcessLocked(app, "user request after error");
9675            }
9676        }
9677    }
9678
9679    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9680            String stackTrace) {
9681        long now = SystemClock.uptimeMillis();
9682
9683        Long crashTime;
9684        if (!app.isolated) {
9685            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9686        } else {
9687            crashTime = null;
9688        }
9689        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9690            // This process loses!
9691            Slog.w(TAG, "Process " + app.info.processName
9692                    + " has crashed too many times: killing!");
9693            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9694                    app.userId, app.info.processName, app.uid);
9695            mStackSupervisor.handleAppCrashLocked(app);
9696            if (!app.persistent) {
9697                // We don't want to start this process again until the user
9698                // explicitly does so...  but for persistent process, we really
9699                // need to keep it running.  If a persistent process is actually
9700                // repeatedly crashing, then badness for everyone.
9701                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9702                        app.info.processName);
9703                if (!app.isolated) {
9704                    // XXX We don't have a way to mark isolated processes
9705                    // as bad, since they don't have a peristent identity.
9706                    mBadProcesses.put(app.info.processName, app.uid,
9707                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9708                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9709                }
9710                app.bad = true;
9711                app.removed = true;
9712                // Don't let services in this process be restarted and potentially
9713                // annoy the user repeatedly.  Unless it is persistent, since those
9714                // processes run critical code.
9715                removeProcessLocked(app, false, false, "crash");
9716                mStackSupervisor.resumeTopActivitiesLocked();
9717                return false;
9718            }
9719            mStackSupervisor.resumeTopActivitiesLocked();
9720        } else {
9721            mStackSupervisor.finishTopRunningActivityLocked(app);
9722        }
9723
9724        // Bump up the crash count of any services currently running in the proc.
9725        for (int i=app.services.size()-1; i>=0; i--) {
9726            // Any services running in the application need to be placed
9727            // back in the pending list.
9728            ServiceRecord sr = app.services.valueAt(i);
9729            sr.crashCount++;
9730        }
9731
9732        // If the crashing process is what we consider to be the "home process" and it has been
9733        // replaced by a third-party app, clear the package preferred activities from packages
9734        // with a home activity running in the process to prevent a repeatedly crashing app
9735        // from blocking the user to manually clear the list.
9736        final ArrayList<ActivityRecord> activities = app.activities;
9737        if (app == mHomeProcess && activities.size() > 0
9738                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9739            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9740                final ActivityRecord r = activities.get(activityNdx);
9741                if (r.isHomeActivity()) {
9742                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9743                    try {
9744                        ActivityThread.getPackageManager()
9745                                .clearPackagePreferredActivities(r.packageName);
9746                    } catch (RemoteException c) {
9747                        // pm is in same process, this will never happen.
9748                    }
9749                }
9750            }
9751        }
9752
9753        if (!app.isolated) {
9754            // XXX Can't keep track of crash times for isolated processes,
9755            // because they don't have a perisistent identity.
9756            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9757        }
9758
9759        return true;
9760    }
9761
9762    void startAppProblemLocked(ProcessRecord app) {
9763        if (app.userId == mCurrentUserId) {
9764            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9765                    mContext, app.info.packageName, app.info.flags);
9766        } else {
9767            // If this app is not running under the current user, then we
9768            // can't give it a report button because that would require
9769            // launching the report UI under a different user.
9770            app.errorReportReceiver = null;
9771        }
9772        skipCurrentReceiverLocked(app);
9773    }
9774
9775    void skipCurrentReceiverLocked(ProcessRecord app) {
9776        for (BroadcastQueue queue : mBroadcastQueues) {
9777            queue.skipCurrentReceiverLocked(app);
9778        }
9779    }
9780
9781    /**
9782     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9783     * The application process will exit immediately after this call returns.
9784     * @param app object of the crashing app, null for the system server
9785     * @param crashInfo describing the exception
9786     */
9787    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9788        ProcessRecord r = findAppProcess(app, "Crash");
9789        final String processName = app == null ? "system_server"
9790                : (r == null ? "unknown" : r.processName);
9791
9792        handleApplicationCrashInner("crash", r, processName, crashInfo);
9793    }
9794
9795    /* Native crash reporting uses this inner version because it needs to be somewhat
9796     * decoupled from the AM-managed cleanup lifecycle
9797     */
9798    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9799            ApplicationErrorReport.CrashInfo crashInfo) {
9800        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9801                UserHandle.getUserId(Binder.getCallingUid()), processName,
9802                r == null ? -1 : r.info.flags,
9803                crashInfo.exceptionClassName,
9804                crashInfo.exceptionMessage,
9805                crashInfo.throwFileName,
9806                crashInfo.throwLineNumber);
9807
9808        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9809
9810        crashApplication(r, crashInfo);
9811    }
9812
9813    public void handleApplicationStrictModeViolation(
9814            IBinder app,
9815            int violationMask,
9816            StrictMode.ViolationInfo info) {
9817        ProcessRecord r = findAppProcess(app, "StrictMode");
9818        if (r == null) {
9819            return;
9820        }
9821
9822        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9823            Integer stackFingerprint = info.hashCode();
9824            boolean logIt = true;
9825            synchronized (mAlreadyLoggedViolatedStacks) {
9826                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9827                    logIt = false;
9828                    // TODO: sub-sample into EventLog for these, with
9829                    // the info.durationMillis?  Then we'd get
9830                    // the relative pain numbers, without logging all
9831                    // the stack traces repeatedly.  We'd want to do
9832                    // likewise in the client code, which also does
9833                    // dup suppression, before the Binder call.
9834                } else {
9835                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9836                        mAlreadyLoggedViolatedStacks.clear();
9837                    }
9838                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9839                }
9840            }
9841            if (logIt) {
9842                logStrictModeViolationToDropBox(r, info);
9843            }
9844        }
9845
9846        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9847            AppErrorResult result = new AppErrorResult();
9848            synchronized (this) {
9849                final long origId = Binder.clearCallingIdentity();
9850
9851                Message msg = Message.obtain();
9852                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9853                HashMap<String, Object> data = new HashMap<String, Object>();
9854                data.put("result", result);
9855                data.put("app", r);
9856                data.put("violationMask", violationMask);
9857                data.put("info", info);
9858                msg.obj = data;
9859                mHandler.sendMessage(msg);
9860
9861                Binder.restoreCallingIdentity(origId);
9862            }
9863            int res = result.get();
9864            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9865        }
9866    }
9867
9868    // Depending on the policy in effect, there could be a bunch of
9869    // these in quick succession so we try to batch these together to
9870    // minimize disk writes, number of dropbox entries, and maximize
9871    // compression, by having more fewer, larger records.
9872    private void logStrictModeViolationToDropBox(
9873            ProcessRecord process,
9874            StrictMode.ViolationInfo info) {
9875        if (info == null) {
9876            return;
9877        }
9878        final boolean isSystemApp = process == null ||
9879                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9880                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9881        final String processName = process == null ? "unknown" : process.processName;
9882        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9883        final DropBoxManager dbox = (DropBoxManager)
9884                mContext.getSystemService(Context.DROPBOX_SERVICE);
9885
9886        // Exit early if the dropbox isn't configured to accept this report type.
9887        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9888
9889        boolean bufferWasEmpty;
9890        boolean needsFlush;
9891        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9892        synchronized (sb) {
9893            bufferWasEmpty = sb.length() == 0;
9894            appendDropBoxProcessHeaders(process, processName, sb);
9895            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9896            sb.append("System-App: ").append(isSystemApp).append("\n");
9897            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9898            if (info.violationNumThisLoop != 0) {
9899                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9900            }
9901            if (info.numAnimationsRunning != 0) {
9902                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9903            }
9904            if (info.broadcastIntentAction != null) {
9905                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9906            }
9907            if (info.durationMillis != -1) {
9908                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9909            }
9910            if (info.numInstances != -1) {
9911                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9912            }
9913            if (info.tags != null) {
9914                for (String tag : info.tags) {
9915                    sb.append("Span-Tag: ").append(tag).append("\n");
9916                }
9917            }
9918            sb.append("\n");
9919            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9920                sb.append(info.crashInfo.stackTrace);
9921            }
9922            sb.append("\n");
9923
9924            // Only buffer up to ~64k.  Various logging bits truncate
9925            // things at 128k.
9926            needsFlush = (sb.length() > 64 * 1024);
9927        }
9928
9929        // Flush immediately if the buffer's grown too large, or this
9930        // is a non-system app.  Non-system apps are isolated with a
9931        // different tag & policy and not batched.
9932        //
9933        // Batching is useful during internal testing with
9934        // StrictMode settings turned up high.  Without batching,
9935        // thousands of separate files could be created on boot.
9936        if (!isSystemApp || needsFlush) {
9937            new Thread("Error dump: " + dropboxTag) {
9938                @Override
9939                public void run() {
9940                    String report;
9941                    synchronized (sb) {
9942                        report = sb.toString();
9943                        sb.delete(0, sb.length());
9944                        sb.trimToSize();
9945                    }
9946                    if (report.length() != 0) {
9947                        dbox.addText(dropboxTag, report);
9948                    }
9949                }
9950            }.start();
9951            return;
9952        }
9953
9954        // System app batching:
9955        if (!bufferWasEmpty) {
9956            // An existing dropbox-writing thread is outstanding, so
9957            // we don't need to start it up.  The existing thread will
9958            // catch the buffer appends we just did.
9959            return;
9960        }
9961
9962        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9963        // (After this point, we shouldn't access AMS internal data structures.)
9964        new Thread("Error dump: " + dropboxTag) {
9965            @Override
9966            public void run() {
9967                // 5 second sleep to let stacks arrive and be batched together
9968                try {
9969                    Thread.sleep(5000);  // 5 seconds
9970                } catch (InterruptedException e) {}
9971
9972                String errorReport;
9973                synchronized (mStrictModeBuffer) {
9974                    errorReport = mStrictModeBuffer.toString();
9975                    if (errorReport.length() == 0) {
9976                        return;
9977                    }
9978                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9979                    mStrictModeBuffer.trimToSize();
9980                }
9981                dbox.addText(dropboxTag, errorReport);
9982            }
9983        }.start();
9984    }
9985
9986    /**
9987     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9988     * @param app object of the crashing app, null for the system server
9989     * @param tag reported by the caller
9990     * @param crashInfo describing the context of the error
9991     * @return true if the process should exit immediately (WTF is fatal)
9992     */
9993    public boolean handleApplicationWtf(IBinder app, String tag,
9994            ApplicationErrorReport.CrashInfo crashInfo) {
9995        ProcessRecord r = findAppProcess(app, "WTF");
9996        final String processName = app == null ? "system_server"
9997                : (r == null ? "unknown" : r.processName);
9998
9999        EventLog.writeEvent(EventLogTags.AM_WTF,
10000                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10001                processName,
10002                r == null ? -1 : r.info.flags,
10003                tag, crashInfo.exceptionMessage);
10004
10005        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10006
10007        if (r != null && r.pid != Process.myPid() &&
10008                Settings.Global.getInt(mContext.getContentResolver(),
10009                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10010            crashApplication(r, crashInfo);
10011            return true;
10012        } else {
10013            return false;
10014        }
10015    }
10016
10017    /**
10018     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10019     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10020     */
10021    private ProcessRecord findAppProcess(IBinder app, String reason) {
10022        if (app == null) {
10023            return null;
10024        }
10025
10026        synchronized (this) {
10027            final int NP = mProcessNames.getMap().size();
10028            for (int ip=0; ip<NP; ip++) {
10029                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10030                final int NA = apps.size();
10031                for (int ia=0; ia<NA; ia++) {
10032                    ProcessRecord p = apps.valueAt(ia);
10033                    if (p.thread != null && p.thread.asBinder() == app) {
10034                        return p;
10035                    }
10036                }
10037            }
10038
10039            Slog.w(TAG, "Can't find mystery application for " + reason
10040                    + " from pid=" + Binder.getCallingPid()
10041                    + " uid=" + Binder.getCallingUid() + ": " + app);
10042            return null;
10043        }
10044    }
10045
10046    /**
10047     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10048     * to append various headers to the dropbox log text.
10049     */
10050    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10051            StringBuilder sb) {
10052        // Watchdog thread ends up invoking this function (with
10053        // a null ProcessRecord) to add the stack file to dropbox.
10054        // Do not acquire a lock on this (am) in such cases, as it
10055        // could cause a potential deadlock, if and when watchdog
10056        // is invoked due to unavailability of lock on am and it
10057        // would prevent watchdog from killing system_server.
10058        if (process == null) {
10059            sb.append("Process: ").append(processName).append("\n");
10060            return;
10061        }
10062        // Note: ProcessRecord 'process' is guarded by the service
10063        // instance.  (notably process.pkgList, which could otherwise change
10064        // concurrently during execution of this method)
10065        synchronized (this) {
10066            sb.append("Process: ").append(processName).append("\n");
10067            int flags = process.info.flags;
10068            IPackageManager pm = AppGlobals.getPackageManager();
10069            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10070            for (int ip=0; ip<process.pkgList.size(); ip++) {
10071                String pkg = process.pkgList.keyAt(ip);
10072                sb.append("Package: ").append(pkg);
10073                try {
10074                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10075                    if (pi != null) {
10076                        sb.append(" v").append(pi.versionCode);
10077                        if (pi.versionName != null) {
10078                            sb.append(" (").append(pi.versionName).append(")");
10079                        }
10080                    }
10081                } catch (RemoteException e) {
10082                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10083                }
10084                sb.append("\n");
10085            }
10086        }
10087    }
10088
10089    private static String processClass(ProcessRecord process) {
10090        if (process == null || process.pid == MY_PID) {
10091            return "system_server";
10092        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10093            return "system_app";
10094        } else {
10095            return "data_app";
10096        }
10097    }
10098
10099    /**
10100     * Write a description of an error (crash, WTF, ANR) to the drop box.
10101     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10102     * @param process which caused the error, null means the system server
10103     * @param activity which triggered the error, null if unknown
10104     * @param parent activity related to the error, null if unknown
10105     * @param subject line related to the error, null if absent
10106     * @param report in long form describing the error, null if absent
10107     * @param logFile to include in the report, null if none
10108     * @param crashInfo giving an application stack trace, null if absent
10109     */
10110    public void addErrorToDropBox(String eventType,
10111            ProcessRecord process, String processName, ActivityRecord activity,
10112            ActivityRecord parent, String subject,
10113            final String report, final File logFile,
10114            final ApplicationErrorReport.CrashInfo crashInfo) {
10115        // NOTE -- this must never acquire the ActivityManagerService lock,
10116        // otherwise the watchdog may be prevented from resetting the system.
10117
10118        final String dropboxTag = processClass(process) + "_" + eventType;
10119        final DropBoxManager dbox = (DropBoxManager)
10120                mContext.getSystemService(Context.DROPBOX_SERVICE);
10121
10122        // Exit early if the dropbox isn't configured to accept this report type.
10123        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10124
10125        final StringBuilder sb = new StringBuilder(1024);
10126        appendDropBoxProcessHeaders(process, processName, sb);
10127        if (activity != null) {
10128            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10129        }
10130        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10131            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10132        }
10133        if (parent != null && parent != activity) {
10134            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10135        }
10136        if (subject != null) {
10137            sb.append("Subject: ").append(subject).append("\n");
10138        }
10139        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10140        if (Debug.isDebuggerConnected()) {
10141            sb.append("Debugger: Connected\n");
10142        }
10143        sb.append("\n");
10144
10145        // Do the rest in a worker thread to avoid blocking the caller on I/O
10146        // (After this point, we shouldn't access AMS internal data structures.)
10147        Thread worker = new Thread("Error dump: " + dropboxTag) {
10148            @Override
10149            public void run() {
10150                if (report != null) {
10151                    sb.append(report);
10152                }
10153                if (logFile != null) {
10154                    try {
10155                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10156                                    "\n\n[[TRUNCATED]]"));
10157                    } catch (IOException e) {
10158                        Slog.e(TAG, "Error reading " + logFile, e);
10159                    }
10160                }
10161                if (crashInfo != null && crashInfo.stackTrace != null) {
10162                    sb.append(crashInfo.stackTrace);
10163                }
10164
10165                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10166                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10167                if (lines > 0) {
10168                    sb.append("\n");
10169
10170                    // Merge several logcat streams, and take the last N lines
10171                    InputStreamReader input = null;
10172                    try {
10173                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10174                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10175                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10176
10177                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10178                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10179                        input = new InputStreamReader(logcat.getInputStream());
10180
10181                        int num;
10182                        char[] buf = new char[8192];
10183                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10184                    } catch (IOException e) {
10185                        Slog.e(TAG, "Error running logcat", e);
10186                    } finally {
10187                        if (input != null) try { input.close(); } catch (IOException e) {}
10188                    }
10189                }
10190
10191                dbox.addText(dropboxTag, sb.toString());
10192            }
10193        };
10194
10195        if (process == null) {
10196            // If process is null, we are being called from some internal code
10197            // and may be about to die -- run this synchronously.
10198            worker.run();
10199        } else {
10200            worker.start();
10201        }
10202    }
10203
10204    /**
10205     * Bring up the "unexpected error" dialog box for a crashing app.
10206     * Deal with edge cases (intercepts from instrumented applications,
10207     * ActivityController, error intent receivers, that sort of thing).
10208     * @param r the application crashing
10209     * @param crashInfo describing the failure
10210     */
10211    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10212        long timeMillis = System.currentTimeMillis();
10213        String shortMsg = crashInfo.exceptionClassName;
10214        String longMsg = crashInfo.exceptionMessage;
10215        String stackTrace = crashInfo.stackTrace;
10216        if (shortMsg != null && longMsg != null) {
10217            longMsg = shortMsg + ": " + longMsg;
10218        } else if (shortMsg != null) {
10219            longMsg = shortMsg;
10220        }
10221
10222        AppErrorResult result = new AppErrorResult();
10223        synchronized (this) {
10224            if (mController != null) {
10225                try {
10226                    String name = r != null ? r.processName : null;
10227                    int pid = r != null ? r.pid : Binder.getCallingPid();
10228                    if (!mController.appCrashed(name, pid,
10229                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10230                        Slog.w(TAG, "Force-killing crashed app " + name
10231                                + " at watcher's request");
10232                        Process.killProcess(pid);
10233                        return;
10234                    }
10235                } catch (RemoteException e) {
10236                    mController = null;
10237                    Watchdog.getInstance().setActivityController(null);
10238                }
10239            }
10240
10241            final long origId = Binder.clearCallingIdentity();
10242
10243            // If this process is running instrumentation, finish it.
10244            if (r != null && r.instrumentationClass != null) {
10245                Slog.w(TAG, "Error in app " + r.processName
10246                      + " running instrumentation " + r.instrumentationClass + ":");
10247                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10248                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10249                Bundle info = new Bundle();
10250                info.putString("shortMsg", shortMsg);
10251                info.putString("longMsg", longMsg);
10252                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10253                Binder.restoreCallingIdentity(origId);
10254                return;
10255            }
10256
10257            // If we can't identify the process or it's already exceeded its crash quota,
10258            // quit right away without showing a crash dialog.
10259            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10260                Binder.restoreCallingIdentity(origId);
10261                return;
10262            }
10263
10264            Message msg = Message.obtain();
10265            msg.what = SHOW_ERROR_MSG;
10266            HashMap data = new HashMap();
10267            data.put("result", result);
10268            data.put("app", r);
10269            msg.obj = data;
10270            mHandler.sendMessage(msg);
10271
10272            Binder.restoreCallingIdentity(origId);
10273        }
10274
10275        int res = result.get();
10276
10277        Intent appErrorIntent = null;
10278        synchronized (this) {
10279            if (r != null && !r.isolated) {
10280                // XXX Can't keep track of crash time for isolated processes,
10281                // since they don't have a persistent identity.
10282                mProcessCrashTimes.put(r.info.processName, r.uid,
10283                        SystemClock.uptimeMillis());
10284            }
10285            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10286                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10287            }
10288        }
10289
10290        if (appErrorIntent != null) {
10291            try {
10292                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10293            } catch (ActivityNotFoundException e) {
10294                Slog.w(TAG, "bug report receiver dissappeared", e);
10295            }
10296        }
10297    }
10298
10299    Intent createAppErrorIntentLocked(ProcessRecord r,
10300            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10301        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10302        if (report == null) {
10303            return null;
10304        }
10305        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10306        result.setComponent(r.errorReportReceiver);
10307        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10308        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10309        return result;
10310    }
10311
10312    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10313            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10314        if (r.errorReportReceiver == null) {
10315            return null;
10316        }
10317
10318        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10319            return null;
10320        }
10321
10322        ApplicationErrorReport report = new ApplicationErrorReport();
10323        report.packageName = r.info.packageName;
10324        report.installerPackageName = r.errorReportReceiver.getPackageName();
10325        report.processName = r.processName;
10326        report.time = timeMillis;
10327        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10328
10329        if (r.crashing || r.forceCrashReport) {
10330            report.type = ApplicationErrorReport.TYPE_CRASH;
10331            report.crashInfo = crashInfo;
10332        } else if (r.notResponding) {
10333            report.type = ApplicationErrorReport.TYPE_ANR;
10334            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10335
10336            report.anrInfo.activity = r.notRespondingReport.tag;
10337            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10338            report.anrInfo.info = r.notRespondingReport.longMsg;
10339        }
10340
10341        return report;
10342    }
10343
10344    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10345        enforceNotIsolatedCaller("getProcessesInErrorState");
10346        // assume our apps are happy - lazy create the list
10347        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10348
10349        final boolean allUsers = ActivityManager.checkUidPermission(
10350                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10351                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10352        int userId = UserHandle.getUserId(Binder.getCallingUid());
10353
10354        synchronized (this) {
10355
10356            // iterate across all processes
10357            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10358                ProcessRecord app = mLruProcesses.get(i);
10359                if (!allUsers && app.userId != userId) {
10360                    continue;
10361                }
10362                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10363                    // This one's in trouble, so we'll generate a report for it
10364                    // crashes are higher priority (in case there's a crash *and* an anr)
10365                    ActivityManager.ProcessErrorStateInfo report = null;
10366                    if (app.crashing) {
10367                        report = app.crashingReport;
10368                    } else if (app.notResponding) {
10369                        report = app.notRespondingReport;
10370                    }
10371
10372                    if (report != null) {
10373                        if (errList == null) {
10374                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10375                        }
10376                        errList.add(report);
10377                    } else {
10378                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10379                                " crashing = " + app.crashing +
10380                                " notResponding = " + app.notResponding);
10381                    }
10382                }
10383            }
10384        }
10385
10386        return errList;
10387    }
10388
10389    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10390        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10391            if (currApp != null) {
10392                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10393            }
10394            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10395        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10396            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10397        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10398            if (currApp != null) {
10399                currApp.lru = 0;
10400            }
10401            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10402        } else if (adj >= ProcessList.SERVICE_ADJ) {
10403            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10404        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10405            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10406        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10407            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10408        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10409            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10410        } else {
10411            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10412        }
10413    }
10414
10415    private void fillInProcMemInfo(ProcessRecord app,
10416            ActivityManager.RunningAppProcessInfo outInfo) {
10417        outInfo.pid = app.pid;
10418        outInfo.uid = app.info.uid;
10419        if (mHeavyWeightProcess == app) {
10420            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10421        }
10422        if (app.persistent) {
10423            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10424        }
10425        if (app.activities.size() > 0) {
10426            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10427        }
10428        outInfo.lastTrimLevel = app.trimMemoryLevel;
10429        int adj = app.curAdj;
10430        outInfo.importance = oomAdjToImportance(adj, outInfo);
10431        outInfo.importanceReasonCode = app.adjTypeCode;
10432    }
10433
10434    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10435        enforceNotIsolatedCaller("getRunningAppProcesses");
10436        // Lazy instantiation of list
10437        List<ActivityManager.RunningAppProcessInfo> runList = null;
10438        final boolean allUsers = ActivityManager.checkUidPermission(
10439                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10440                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10441        int userId = UserHandle.getUserId(Binder.getCallingUid());
10442        synchronized (this) {
10443            // Iterate across all processes
10444            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10445                ProcessRecord app = mLruProcesses.get(i);
10446                if (!allUsers && app.userId != userId) {
10447                    continue;
10448                }
10449                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10450                    // Generate process state info for running application
10451                    ActivityManager.RunningAppProcessInfo currApp =
10452                        new ActivityManager.RunningAppProcessInfo(app.processName,
10453                                app.pid, app.getPackageList());
10454                    fillInProcMemInfo(app, currApp);
10455                    if (app.adjSource instanceof ProcessRecord) {
10456                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10457                        currApp.importanceReasonImportance = oomAdjToImportance(
10458                                app.adjSourceOom, null);
10459                    } else if (app.adjSource instanceof ActivityRecord) {
10460                        ActivityRecord r = (ActivityRecord)app.adjSource;
10461                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10462                    }
10463                    if (app.adjTarget instanceof ComponentName) {
10464                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10465                    }
10466                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10467                    //        + " lru=" + currApp.lru);
10468                    if (runList == null) {
10469                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10470                    }
10471                    runList.add(currApp);
10472                }
10473            }
10474        }
10475        return runList;
10476    }
10477
10478    public List<ApplicationInfo> getRunningExternalApplications() {
10479        enforceNotIsolatedCaller("getRunningExternalApplications");
10480        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10481        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10482        if (runningApps != null && runningApps.size() > 0) {
10483            Set<String> extList = new HashSet<String>();
10484            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10485                if (app.pkgList != null) {
10486                    for (String pkg : app.pkgList) {
10487                        extList.add(pkg);
10488                    }
10489                }
10490            }
10491            IPackageManager pm = AppGlobals.getPackageManager();
10492            for (String pkg : extList) {
10493                try {
10494                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10495                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10496                        retList.add(info);
10497                    }
10498                } catch (RemoteException e) {
10499                }
10500            }
10501        }
10502        return retList;
10503    }
10504
10505    @Override
10506    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10507        enforceNotIsolatedCaller("getMyMemoryState");
10508        synchronized (this) {
10509            ProcessRecord proc;
10510            synchronized (mPidsSelfLocked) {
10511                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10512            }
10513            fillInProcMemInfo(proc, outInfo);
10514        }
10515    }
10516
10517    @Override
10518    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10519        if (checkCallingPermission(android.Manifest.permission.DUMP)
10520                != PackageManager.PERMISSION_GRANTED) {
10521            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10522                    + Binder.getCallingPid()
10523                    + ", uid=" + Binder.getCallingUid()
10524                    + " without permission "
10525                    + android.Manifest.permission.DUMP);
10526            return;
10527        }
10528
10529        boolean dumpAll = false;
10530        boolean dumpClient = false;
10531        String dumpPackage = null;
10532
10533        int opti = 0;
10534        while (opti < args.length) {
10535            String opt = args[opti];
10536            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10537                break;
10538            }
10539            opti++;
10540            if ("-a".equals(opt)) {
10541                dumpAll = true;
10542            } else if ("-c".equals(opt)) {
10543                dumpClient = true;
10544            } else if ("-h".equals(opt)) {
10545                pw.println("Activity manager dump options:");
10546                pw.println("  [-a] [-c] [-h] [cmd] ...");
10547                pw.println("  cmd may be one of:");
10548                pw.println("    a[ctivities]: activity stack state");
10549                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10550                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10551                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10552                pw.println("    o[om]: out of memory management");
10553                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10554                pw.println("    provider [COMP_SPEC]: provider client-side state");
10555                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10556                pw.println("    service [COMP_SPEC]: service client-side state");
10557                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10558                pw.println("    all: dump all activities");
10559                pw.println("    top: dump the top activity");
10560                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10561                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10562                pw.println("    a partial substring in a component name, a");
10563                pw.println("    hex object identifier.");
10564                pw.println("  -a: include all available server state.");
10565                pw.println("  -c: include client state.");
10566                return;
10567            } else {
10568                pw.println("Unknown argument: " + opt + "; use -h for help");
10569            }
10570        }
10571
10572        long origId = Binder.clearCallingIdentity();
10573        boolean more = false;
10574        // Is the caller requesting to dump a particular piece of data?
10575        if (opti < args.length) {
10576            String cmd = args[opti];
10577            opti++;
10578            if ("activities".equals(cmd) || "a".equals(cmd)) {
10579                synchronized (this) {
10580                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10581                }
10582            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10583                String[] newArgs;
10584                String name;
10585                if (opti >= args.length) {
10586                    name = null;
10587                    newArgs = EMPTY_STRING_ARRAY;
10588                } else {
10589                    name = args[opti];
10590                    opti++;
10591                    newArgs = new String[args.length - opti];
10592                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10593                            args.length - opti);
10594                }
10595                synchronized (this) {
10596                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10597                }
10598            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10599                String[] newArgs;
10600                String name;
10601                if (opti >= args.length) {
10602                    name = null;
10603                    newArgs = EMPTY_STRING_ARRAY;
10604                } else {
10605                    name = args[opti];
10606                    opti++;
10607                    newArgs = new String[args.length - opti];
10608                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10609                            args.length - opti);
10610                }
10611                synchronized (this) {
10612                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10613                }
10614            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10615                String[] newArgs;
10616                String name;
10617                if (opti >= args.length) {
10618                    name = null;
10619                    newArgs = EMPTY_STRING_ARRAY;
10620                } else {
10621                    name = args[opti];
10622                    opti++;
10623                    newArgs = new String[args.length - opti];
10624                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10625                            args.length - opti);
10626                }
10627                synchronized (this) {
10628                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10629                }
10630            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10631                synchronized (this) {
10632                    dumpOomLocked(fd, pw, args, opti, true);
10633                }
10634            } else if ("provider".equals(cmd)) {
10635                String[] newArgs;
10636                String name;
10637                if (opti >= args.length) {
10638                    name = null;
10639                    newArgs = EMPTY_STRING_ARRAY;
10640                } else {
10641                    name = args[opti];
10642                    opti++;
10643                    newArgs = new String[args.length - opti];
10644                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10645                }
10646                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10647                    pw.println("No providers match: " + name);
10648                    pw.println("Use -h for help.");
10649                }
10650            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10651                synchronized (this) {
10652                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10653                }
10654            } else if ("service".equals(cmd)) {
10655                String[] newArgs;
10656                String name;
10657                if (opti >= args.length) {
10658                    name = null;
10659                    newArgs = EMPTY_STRING_ARRAY;
10660                } else {
10661                    name = args[opti];
10662                    opti++;
10663                    newArgs = new String[args.length - opti];
10664                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10665                            args.length - opti);
10666                }
10667                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10668                    pw.println("No services match: " + name);
10669                    pw.println("Use -h for help.");
10670                }
10671            } else if ("package".equals(cmd)) {
10672                String[] newArgs;
10673                if (opti >= args.length) {
10674                    pw.println("package: no package name specified");
10675                    pw.println("Use -h for help.");
10676                } else {
10677                    dumpPackage = args[opti];
10678                    opti++;
10679                    newArgs = new String[args.length - opti];
10680                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10681                            args.length - opti);
10682                    args = newArgs;
10683                    opti = 0;
10684                    more = true;
10685                }
10686            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10687                synchronized (this) {
10688                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10689                }
10690            } else {
10691                // Dumping a single activity?
10692                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10693                    pw.println("Bad activity command, or no activities match: " + cmd);
10694                    pw.println("Use -h for help.");
10695                }
10696            }
10697            if (!more) {
10698                Binder.restoreCallingIdentity(origId);
10699                return;
10700            }
10701        }
10702
10703        // No piece of data specified, dump everything.
10704        synchronized (this) {
10705            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10706            pw.println();
10707            if (dumpAll) {
10708                pw.println("-------------------------------------------------------------------------------");
10709            }
10710            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10711            pw.println();
10712            if (dumpAll) {
10713                pw.println("-------------------------------------------------------------------------------");
10714            }
10715            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10716            pw.println();
10717            if (dumpAll) {
10718                pw.println("-------------------------------------------------------------------------------");
10719            }
10720            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10721            pw.println();
10722            if (dumpAll) {
10723                pw.println("-------------------------------------------------------------------------------");
10724            }
10725            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10726            pw.println();
10727            if (dumpAll) {
10728                pw.println("-------------------------------------------------------------------------------");
10729            }
10730            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10731        }
10732        Binder.restoreCallingIdentity(origId);
10733    }
10734
10735    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10736            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10737        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10738
10739        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10740                dumpPackage);
10741        boolean needSep = printedAnything;
10742
10743        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10744                dumpPackage, needSep, "  mFocusedActivity: ");
10745        if (printed) {
10746            printedAnything = true;
10747            needSep = false;
10748        }
10749
10750        if (dumpPackage == null) {
10751            if (needSep) {
10752                pw.println();
10753            }
10754            needSep = true;
10755            printedAnything = true;
10756            mStackSupervisor.dump(pw, "  ");
10757        }
10758
10759        if (mRecentTasks.size() > 0) {
10760            boolean printedHeader = false;
10761
10762            final int N = mRecentTasks.size();
10763            for (int i=0; i<N; i++) {
10764                TaskRecord tr = mRecentTasks.get(i);
10765                if (dumpPackage != null) {
10766                    if (tr.realActivity == null ||
10767                            !dumpPackage.equals(tr.realActivity)) {
10768                        continue;
10769                    }
10770                }
10771                if (!printedHeader) {
10772                    if (needSep) {
10773                        pw.println();
10774                    }
10775                    pw.println("  Recent tasks:");
10776                    printedHeader = true;
10777                    printedAnything = true;
10778                }
10779                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10780                        pw.println(tr);
10781                if (dumpAll) {
10782                    mRecentTasks.get(i).dump(pw, "    ");
10783                }
10784            }
10785        }
10786
10787        if (!printedAnything) {
10788            pw.println("  (nothing)");
10789        }
10790    }
10791
10792    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10793            int opti, boolean dumpAll, String dumpPackage) {
10794        boolean needSep = false;
10795        boolean printedAnything = false;
10796        int numPers = 0;
10797
10798        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10799
10800        if (dumpAll) {
10801            final int NP = mProcessNames.getMap().size();
10802            for (int ip=0; ip<NP; ip++) {
10803                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10804                final int NA = procs.size();
10805                for (int ia=0; ia<NA; ia++) {
10806                    ProcessRecord r = procs.valueAt(ia);
10807                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10808                        continue;
10809                    }
10810                    if (!needSep) {
10811                        pw.println("  All known processes:");
10812                        needSep = true;
10813                        printedAnything = true;
10814                    }
10815                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10816                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10817                        pw.print(" "); pw.println(r);
10818                    r.dump(pw, "    ");
10819                    if (r.persistent) {
10820                        numPers++;
10821                    }
10822                }
10823            }
10824        }
10825
10826        if (mIsolatedProcesses.size() > 0) {
10827            boolean printed = false;
10828            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10829                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10830                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10831                    continue;
10832                }
10833                if (!printed) {
10834                    if (needSep) {
10835                        pw.println();
10836                    }
10837                    pw.println("  Isolated process list (sorted by uid):");
10838                    printedAnything = true;
10839                    printed = true;
10840                    needSep = true;
10841                }
10842                pw.println(String.format("%sIsolated #%2d: %s",
10843                        "    ", i, r.toString()));
10844            }
10845        }
10846
10847        if (mLruProcesses.size() > 0) {
10848            if (needSep) {
10849                pw.println();
10850            }
10851            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10852                    pw.print(" total, non-act at ");
10853                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10854                    pw.print(", non-svc at ");
10855                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10856                    pw.println("):");
10857            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10858            needSep = true;
10859            printedAnything = true;
10860        }
10861
10862        if (dumpAll || dumpPackage != null) {
10863            synchronized (mPidsSelfLocked) {
10864                boolean printed = false;
10865                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10866                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10867                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10868                        continue;
10869                    }
10870                    if (!printed) {
10871                        if (needSep) pw.println();
10872                        needSep = true;
10873                        pw.println("  PID mappings:");
10874                        printed = true;
10875                        printedAnything = true;
10876                    }
10877                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10878                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10879                }
10880            }
10881        }
10882
10883        if (mForegroundProcesses.size() > 0) {
10884            synchronized (mPidsSelfLocked) {
10885                boolean printed = false;
10886                for (int i=0; i<mForegroundProcesses.size(); i++) {
10887                    ProcessRecord r = mPidsSelfLocked.get(
10888                            mForegroundProcesses.valueAt(i).pid);
10889                    if (dumpPackage != null && (r == null
10890                            || !r.pkgList.containsKey(dumpPackage))) {
10891                        continue;
10892                    }
10893                    if (!printed) {
10894                        if (needSep) pw.println();
10895                        needSep = true;
10896                        pw.println("  Foreground Processes:");
10897                        printed = true;
10898                        printedAnything = true;
10899                    }
10900                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10901                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10902                }
10903            }
10904        }
10905
10906        if (mPersistentStartingProcesses.size() > 0) {
10907            if (needSep) pw.println();
10908            needSep = true;
10909            printedAnything = true;
10910            pw.println("  Persisent processes that are starting:");
10911            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10912                    "Starting Norm", "Restarting PERS", dumpPackage);
10913        }
10914
10915        if (mRemovedProcesses.size() > 0) {
10916            if (needSep) pw.println();
10917            needSep = true;
10918            printedAnything = true;
10919            pw.println("  Processes that are being removed:");
10920            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10921                    "Removed Norm", "Removed PERS", dumpPackage);
10922        }
10923
10924        if (mProcessesOnHold.size() > 0) {
10925            if (needSep) pw.println();
10926            needSep = true;
10927            printedAnything = true;
10928            pw.println("  Processes that are on old until the system is ready:");
10929            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10930                    "OnHold Norm", "OnHold PERS", dumpPackage);
10931        }
10932
10933        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10934
10935        if (mProcessCrashTimes.getMap().size() > 0) {
10936            boolean printed = false;
10937            long now = SystemClock.uptimeMillis();
10938            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10939            final int NP = pmap.size();
10940            for (int ip=0; ip<NP; ip++) {
10941                String pname = pmap.keyAt(ip);
10942                SparseArray<Long> uids = pmap.valueAt(ip);
10943                final int N = uids.size();
10944                for (int i=0; i<N; i++) {
10945                    int puid = uids.keyAt(i);
10946                    ProcessRecord r = mProcessNames.get(pname, puid);
10947                    if (dumpPackage != null && (r == null
10948                            || !r.pkgList.containsKey(dumpPackage))) {
10949                        continue;
10950                    }
10951                    if (!printed) {
10952                        if (needSep) pw.println();
10953                        needSep = true;
10954                        pw.println("  Time since processes crashed:");
10955                        printed = true;
10956                        printedAnything = true;
10957                    }
10958                    pw.print("    Process "); pw.print(pname);
10959                            pw.print(" uid "); pw.print(puid);
10960                            pw.print(": last crashed ");
10961                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10962                            pw.println(" ago");
10963                }
10964            }
10965        }
10966
10967        if (mBadProcesses.getMap().size() > 0) {
10968            boolean printed = false;
10969            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10970            final int NP = pmap.size();
10971            for (int ip=0; ip<NP; ip++) {
10972                String pname = pmap.keyAt(ip);
10973                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10974                final int N = uids.size();
10975                for (int i=0; i<N; i++) {
10976                    int puid = uids.keyAt(i);
10977                    ProcessRecord r = mProcessNames.get(pname, puid);
10978                    if (dumpPackage != null && (r == null
10979                            || !r.pkgList.containsKey(dumpPackage))) {
10980                        continue;
10981                    }
10982                    if (!printed) {
10983                        if (needSep) pw.println();
10984                        needSep = true;
10985                        pw.println("  Bad processes:");
10986                        printedAnything = true;
10987                    }
10988                    BadProcessInfo info = uids.valueAt(i);
10989                    pw.print("    Bad process "); pw.print(pname);
10990                            pw.print(" uid "); pw.print(puid);
10991                            pw.print(": crashed at time "); pw.println(info.time);
10992                    if (info.shortMsg != null) {
10993                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10994                    }
10995                    if (info.longMsg != null) {
10996                        pw.print("      Long msg: "); pw.println(info.longMsg);
10997                    }
10998                    if (info.stack != null) {
10999                        pw.println("      Stack:");
11000                        int lastPos = 0;
11001                        for (int pos=0; pos<info.stack.length(); pos++) {
11002                            if (info.stack.charAt(pos) == '\n') {
11003                                pw.print("        ");
11004                                pw.write(info.stack, lastPos, pos-lastPos);
11005                                pw.println();
11006                                lastPos = pos+1;
11007                            }
11008                        }
11009                        if (lastPos < info.stack.length()) {
11010                            pw.print("        ");
11011                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11012                            pw.println();
11013                        }
11014                    }
11015                }
11016            }
11017        }
11018
11019        if (dumpPackage == null) {
11020            pw.println();
11021            needSep = false;
11022            pw.println("  mStartedUsers:");
11023            for (int i=0; i<mStartedUsers.size(); i++) {
11024                UserStartedState uss = mStartedUsers.valueAt(i);
11025                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11026                        pw.print(": "); uss.dump("", pw);
11027            }
11028            pw.print("  mStartedUserArray: [");
11029            for (int i=0; i<mStartedUserArray.length; i++) {
11030                if (i > 0) pw.print(", ");
11031                pw.print(mStartedUserArray[i]);
11032            }
11033            pw.println("]");
11034            pw.print("  mUserLru: [");
11035            for (int i=0; i<mUserLru.size(); i++) {
11036                if (i > 0) pw.print(", ");
11037                pw.print(mUserLru.get(i));
11038            }
11039            pw.println("]");
11040            if (dumpAll) {
11041                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11042            }
11043        }
11044        if (mHomeProcess != null && (dumpPackage == null
11045                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11046            if (needSep) {
11047                pw.println();
11048                needSep = false;
11049            }
11050            pw.println("  mHomeProcess: " + mHomeProcess);
11051        }
11052        if (mPreviousProcess != null && (dumpPackage == null
11053                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11054            if (needSep) {
11055                pw.println();
11056                needSep = false;
11057            }
11058            pw.println("  mPreviousProcess: " + mPreviousProcess);
11059        }
11060        if (dumpAll) {
11061            StringBuilder sb = new StringBuilder(128);
11062            sb.append("  mPreviousProcessVisibleTime: ");
11063            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11064            pw.println(sb);
11065        }
11066        if (mHeavyWeightProcess != null && (dumpPackage == null
11067                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11068            if (needSep) {
11069                pw.println();
11070                needSep = false;
11071            }
11072            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11073        }
11074        if (dumpPackage == null) {
11075            pw.println("  mConfiguration: " + mConfiguration);
11076        }
11077        if (dumpAll) {
11078            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11079            if (mCompatModePackages.getPackages().size() > 0) {
11080                boolean printed = false;
11081                for (Map.Entry<String, Integer> entry
11082                        : mCompatModePackages.getPackages().entrySet()) {
11083                    String pkg = entry.getKey();
11084                    int mode = entry.getValue();
11085                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11086                        continue;
11087                    }
11088                    if (!printed) {
11089                        pw.println("  mScreenCompatPackages:");
11090                        printed = true;
11091                    }
11092                    pw.print("    "); pw.print(pkg); pw.print(": ");
11093                            pw.print(mode); pw.println();
11094                }
11095            }
11096        }
11097        if (dumpPackage == null) {
11098            if (mSleeping || mWentToSleep || mLockScreenShown) {
11099                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11100                        + " mLockScreenShown " + mLockScreenShown);
11101            }
11102            if (mShuttingDown) {
11103                pw.println("  mShuttingDown=" + mShuttingDown);
11104            }
11105        }
11106        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11107                || mOrigWaitForDebugger) {
11108            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11109                    || dumpPackage.equals(mOrigDebugApp)) {
11110                if (needSep) {
11111                    pw.println();
11112                    needSep = false;
11113                }
11114                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11115                        + " mDebugTransient=" + mDebugTransient
11116                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11117            }
11118        }
11119        if (mOpenGlTraceApp != null) {
11120            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11121                if (needSep) {
11122                    pw.println();
11123                    needSep = false;
11124                }
11125                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11126            }
11127        }
11128        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11129                || mProfileFd != null) {
11130            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11131                if (needSep) {
11132                    pw.println();
11133                    needSep = false;
11134                }
11135                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11136                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11137                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11138                        + mAutoStopProfiler);
11139            }
11140        }
11141        if (dumpPackage == null) {
11142            if (mAlwaysFinishActivities || mController != null) {
11143                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11144                        + " mController=" + mController);
11145            }
11146            if (dumpAll) {
11147                pw.println("  Total persistent processes: " + numPers);
11148                pw.println("  mStartRunning=" + mStartRunning
11149                        + " mProcessesReady=" + mProcessesReady
11150                        + " mSystemReady=" + mSystemReady);
11151                pw.println("  mBooting=" + mBooting
11152                        + " mBooted=" + mBooted
11153                        + " mFactoryTest=" + mFactoryTest);
11154                pw.print("  mLastPowerCheckRealtime=");
11155                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11156                        pw.println("");
11157                pw.print("  mLastPowerCheckUptime=");
11158                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11159                        pw.println("");
11160                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11161                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11162                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11163                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11164                        + " (" + mLruProcesses.size() + " total)"
11165                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11166                        + " mNumServiceProcs=" + mNumServiceProcs
11167                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11168                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11169                        + " mLastMemoryLevel" + mLastMemoryLevel
11170                        + " mLastNumProcesses" + mLastNumProcesses);
11171                long now = SystemClock.uptimeMillis();
11172                pw.print("  mLastIdleTime=");
11173                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11174                        pw.print(" mLowRamSinceLastIdle=");
11175                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11176                        pw.println();
11177            }
11178        }
11179
11180        if (!printedAnything) {
11181            pw.println("  (nothing)");
11182        }
11183    }
11184
11185    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11186            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11187        if (mProcessesToGc.size() > 0) {
11188            boolean printed = false;
11189            long now = SystemClock.uptimeMillis();
11190            for (int i=0; i<mProcessesToGc.size(); i++) {
11191                ProcessRecord proc = mProcessesToGc.get(i);
11192                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11193                    continue;
11194                }
11195                if (!printed) {
11196                    if (needSep) pw.println();
11197                    needSep = true;
11198                    pw.println("  Processes that are waiting to GC:");
11199                    printed = true;
11200                }
11201                pw.print("    Process "); pw.println(proc);
11202                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11203                        pw.print(", last gced=");
11204                        pw.print(now-proc.lastRequestedGc);
11205                        pw.print(" ms ago, last lowMem=");
11206                        pw.print(now-proc.lastLowMemory);
11207                        pw.println(" ms ago");
11208
11209            }
11210        }
11211        return needSep;
11212    }
11213
11214    void printOomLevel(PrintWriter pw, String name, int adj) {
11215        pw.print("    ");
11216        if (adj >= 0) {
11217            pw.print(' ');
11218            if (adj < 10) pw.print(' ');
11219        } else {
11220            if (adj > -10) pw.print(' ');
11221        }
11222        pw.print(adj);
11223        pw.print(": ");
11224        pw.print(name);
11225        pw.print(" (");
11226        pw.print(mProcessList.getMemLevel(adj)/1024);
11227        pw.println(" kB)");
11228    }
11229
11230    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11231            int opti, boolean dumpAll) {
11232        boolean needSep = false;
11233
11234        if (mLruProcesses.size() > 0) {
11235            if (needSep) pw.println();
11236            needSep = true;
11237            pw.println("  OOM levels:");
11238            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11239            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11240            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11241            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11242            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11243            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11244            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11245            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11246            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11247            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11248            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11249            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11250            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11251
11252            if (needSep) pw.println();
11253            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11254                    pw.print(" total, non-act at ");
11255                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11256                    pw.print(", non-svc at ");
11257                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11258                    pw.println("):");
11259            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11260            needSep = true;
11261        }
11262
11263        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11264
11265        pw.println();
11266        pw.println("  mHomeProcess: " + mHomeProcess);
11267        pw.println("  mPreviousProcess: " + mPreviousProcess);
11268        if (mHeavyWeightProcess != null) {
11269            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11270        }
11271
11272        return true;
11273    }
11274
11275    /**
11276     * There are three ways to call this:
11277     *  - no provider specified: dump all the providers
11278     *  - a flattened component name that matched an existing provider was specified as the
11279     *    first arg: dump that one provider
11280     *  - the first arg isn't the flattened component name of an existing provider:
11281     *    dump all providers whose component contains the first arg as a substring
11282     */
11283    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11284            int opti, boolean dumpAll) {
11285        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11286    }
11287
11288    static class ItemMatcher {
11289        ArrayList<ComponentName> components;
11290        ArrayList<String> strings;
11291        ArrayList<Integer> objects;
11292        boolean all;
11293
11294        ItemMatcher() {
11295            all = true;
11296        }
11297
11298        void build(String name) {
11299            ComponentName componentName = ComponentName.unflattenFromString(name);
11300            if (componentName != null) {
11301                if (components == null) {
11302                    components = new ArrayList<ComponentName>();
11303                }
11304                components.add(componentName);
11305                all = false;
11306            } else {
11307                int objectId = 0;
11308                // Not a '/' separated full component name; maybe an object ID?
11309                try {
11310                    objectId = Integer.parseInt(name, 16);
11311                    if (objects == null) {
11312                        objects = new ArrayList<Integer>();
11313                    }
11314                    objects.add(objectId);
11315                    all = false;
11316                } catch (RuntimeException e) {
11317                    // Not an integer; just do string match.
11318                    if (strings == null) {
11319                        strings = new ArrayList<String>();
11320                    }
11321                    strings.add(name);
11322                    all = false;
11323                }
11324            }
11325        }
11326
11327        int build(String[] args, int opti) {
11328            for (; opti<args.length; opti++) {
11329                String name = args[opti];
11330                if ("--".equals(name)) {
11331                    return opti+1;
11332                }
11333                build(name);
11334            }
11335            return opti;
11336        }
11337
11338        boolean match(Object object, ComponentName comp) {
11339            if (all) {
11340                return true;
11341            }
11342            if (components != null) {
11343                for (int i=0; i<components.size(); i++) {
11344                    if (components.get(i).equals(comp)) {
11345                        return true;
11346                    }
11347                }
11348            }
11349            if (objects != null) {
11350                for (int i=0; i<objects.size(); i++) {
11351                    if (System.identityHashCode(object) == objects.get(i)) {
11352                        return true;
11353                    }
11354                }
11355            }
11356            if (strings != null) {
11357                String flat = comp.flattenToString();
11358                for (int i=0; i<strings.size(); i++) {
11359                    if (flat.contains(strings.get(i))) {
11360                        return true;
11361                    }
11362                }
11363            }
11364            return false;
11365        }
11366    }
11367
11368    /**
11369     * There are three things that cmd can be:
11370     *  - a flattened component name that matches an existing activity
11371     *  - the cmd arg isn't the flattened component name of an existing activity:
11372     *    dump all activity whose component contains the cmd as a substring
11373     *  - A hex number of the ActivityRecord object instance.
11374     */
11375    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11376            int opti, boolean dumpAll) {
11377        ArrayList<ActivityRecord> activities;
11378
11379        synchronized (this) {
11380            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11381        }
11382
11383        if (activities.size() <= 0) {
11384            return false;
11385        }
11386
11387        String[] newArgs = new String[args.length - opti];
11388        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11389
11390        TaskRecord lastTask = null;
11391        boolean needSep = false;
11392        for (int i=activities.size()-1; i>=0; i--) {
11393            ActivityRecord r = activities.get(i);
11394            if (needSep) {
11395                pw.println();
11396            }
11397            needSep = true;
11398            synchronized (this) {
11399                if (lastTask != r.task) {
11400                    lastTask = r.task;
11401                    pw.print("TASK "); pw.print(lastTask.affinity);
11402                            pw.print(" id="); pw.println(lastTask.taskId);
11403                    if (dumpAll) {
11404                        lastTask.dump(pw, "  ");
11405                    }
11406                }
11407            }
11408            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11409        }
11410        return true;
11411    }
11412
11413    /**
11414     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11415     * there is a thread associated with the activity.
11416     */
11417    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11418            final ActivityRecord r, String[] args, boolean dumpAll) {
11419        String innerPrefix = prefix + "  ";
11420        synchronized (this) {
11421            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11422                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11423                    pw.print(" pid=");
11424                    if (r.app != null) pw.println(r.app.pid);
11425                    else pw.println("(not running)");
11426            if (dumpAll) {
11427                r.dump(pw, innerPrefix);
11428            }
11429        }
11430        if (r.app != null && r.app.thread != null) {
11431            // flush anything that is already in the PrintWriter since the thread is going
11432            // to write to the file descriptor directly
11433            pw.flush();
11434            try {
11435                TransferPipe tp = new TransferPipe();
11436                try {
11437                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11438                            r.appToken, innerPrefix, args);
11439                    tp.go(fd);
11440                } finally {
11441                    tp.kill();
11442                }
11443            } catch (IOException e) {
11444                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11445            } catch (RemoteException e) {
11446                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11447            }
11448        }
11449    }
11450
11451    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11452            int opti, boolean dumpAll, String dumpPackage) {
11453        boolean needSep = false;
11454        boolean onlyHistory = false;
11455        boolean printedAnything = false;
11456
11457        if ("history".equals(dumpPackage)) {
11458            if (opti < args.length && "-s".equals(args[opti])) {
11459                dumpAll = false;
11460            }
11461            onlyHistory = true;
11462            dumpPackage = null;
11463        }
11464
11465        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11466        if (!onlyHistory && dumpAll) {
11467            if (mRegisteredReceivers.size() > 0) {
11468                boolean printed = false;
11469                Iterator it = mRegisteredReceivers.values().iterator();
11470                while (it.hasNext()) {
11471                    ReceiverList r = (ReceiverList)it.next();
11472                    if (dumpPackage != null && (r.app == null ||
11473                            !dumpPackage.equals(r.app.info.packageName))) {
11474                        continue;
11475                    }
11476                    if (!printed) {
11477                        pw.println("  Registered Receivers:");
11478                        needSep = true;
11479                        printed = true;
11480                        printedAnything = true;
11481                    }
11482                    pw.print("  * "); pw.println(r);
11483                    r.dump(pw, "    ");
11484                }
11485            }
11486
11487            if (mReceiverResolver.dump(pw, needSep ?
11488                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11489                    "    ", dumpPackage, false)) {
11490                needSep = true;
11491                printedAnything = true;
11492            }
11493        }
11494
11495        for (BroadcastQueue q : mBroadcastQueues) {
11496            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11497            printedAnything |= needSep;
11498        }
11499
11500        needSep = true;
11501
11502        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11503            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11504                if (needSep) {
11505                    pw.println();
11506                }
11507                needSep = true;
11508                printedAnything = true;
11509                pw.print("  Sticky broadcasts for user ");
11510                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11511                StringBuilder sb = new StringBuilder(128);
11512                for (Map.Entry<String, ArrayList<Intent>> ent
11513                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11514                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11515                    if (dumpAll) {
11516                        pw.println(":");
11517                        ArrayList<Intent> intents = ent.getValue();
11518                        final int N = intents.size();
11519                        for (int i=0; i<N; i++) {
11520                            sb.setLength(0);
11521                            sb.append("    Intent: ");
11522                            intents.get(i).toShortString(sb, false, true, false, false);
11523                            pw.println(sb.toString());
11524                            Bundle bundle = intents.get(i).getExtras();
11525                            if (bundle != null) {
11526                                pw.print("      ");
11527                                pw.println(bundle.toString());
11528                            }
11529                        }
11530                    } else {
11531                        pw.println("");
11532                    }
11533                }
11534            }
11535        }
11536
11537        if (!onlyHistory && dumpAll) {
11538            pw.println();
11539            for (BroadcastQueue queue : mBroadcastQueues) {
11540                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11541                        + queue.mBroadcastsScheduled);
11542            }
11543            pw.println("  mHandler:");
11544            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11545            needSep = true;
11546            printedAnything = true;
11547        }
11548
11549        if (!printedAnything) {
11550            pw.println("  (nothing)");
11551        }
11552    }
11553
11554    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11555            int opti, boolean dumpAll, String dumpPackage) {
11556        boolean needSep;
11557        boolean printedAnything = false;
11558
11559        ItemMatcher matcher = new ItemMatcher();
11560        matcher.build(args, opti);
11561
11562        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11563
11564        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11565        printedAnything |= needSep;
11566
11567        if (mLaunchingProviders.size() > 0) {
11568            boolean printed = false;
11569            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11570                ContentProviderRecord r = mLaunchingProviders.get(i);
11571                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11572                    continue;
11573                }
11574                if (!printed) {
11575                    if (needSep) pw.println();
11576                    needSep = true;
11577                    pw.println("  Launching content providers:");
11578                    printed = true;
11579                    printedAnything = true;
11580                }
11581                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11582                        pw.println(r);
11583            }
11584        }
11585
11586        if (mGrantedUriPermissions.size() > 0) {
11587            boolean printed = false;
11588            int dumpUid = -2;
11589            if (dumpPackage != null) {
11590                try {
11591                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11592                } catch (NameNotFoundException e) {
11593                    dumpUid = -1;
11594                }
11595            }
11596            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11597                int uid = mGrantedUriPermissions.keyAt(i);
11598                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11599                    continue;
11600                }
11601                ArrayMap<Uri, UriPermission> perms
11602                        = mGrantedUriPermissions.valueAt(i);
11603                if (!printed) {
11604                    if (needSep) pw.println();
11605                    needSep = true;
11606                    pw.println("  Granted Uri Permissions:");
11607                    printed = true;
11608                    printedAnything = true;
11609                }
11610                pw.print("  * UID "); pw.print(uid);
11611                        pw.println(" holds:");
11612                for (UriPermission perm : perms.values()) {
11613                    pw.print("    "); pw.println(perm);
11614                    if (dumpAll) {
11615                        perm.dump(pw, "      ");
11616                    }
11617                }
11618            }
11619        }
11620
11621        if (!printedAnything) {
11622            pw.println("  (nothing)");
11623        }
11624    }
11625
11626    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11627            int opti, boolean dumpAll, String dumpPackage) {
11628        boolean printed = false;
11629
11630        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11631
11632        if (mIntentSenderRecords.size() > 0) {
11633            Iterator<WeakReference<PendingIntentRecord>> it
11634                    = mIntentSenderRecords.values().iterator();
11635            while (it.hasNext()) {
11636                WeakReference<PendingIntentRecord> ref = it.next();
11637                PendingIntentRecord rec = ref != null ? ref.get(): null;
11638                if (dumpPackage != null && (rec == null
11639                        || !dumpPackage.equals(rec.key.packageName))) {
11640                    continue;
11641                }
11642                printed = true;
11643                if (rec != null) {
11644                    pw.print("  * "); pw.println(rec);
11645                    if (dumpAll) {
11646                        rec.dump(pw, "    ");
11647                    }
11648                } else {
11649                    pw.print("  * "); pw.println(ref);
11650                }
11651            }
11652        }
11653
11654        if (!printed) {
11655            pw.println("  (nothing)");
11656        }
11657    }
11658
11659    private static final int dumpProcessList(PrintWriter pw,
11660            ActivityManagerService service, List list,
11661            String prefix, String normalLabel, String persistentLabel,
11662            String dumpPackage) {
11663        int numPers = 0;
11664        final int N = list.size()-1;
11665        for (int i=N; i>=0; i--) {
11666            ProcessRecord r = (ProcessRecord)list.get(i);
11667            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11668                continue;
11669            }
11670            pw.println(String.format("%s%s #%2d: %s",
11671                    prefix, (r.persistent ? persistentLabel : normalLabel),
11672                    i, r.toString()));
11673            if (r.persistent) {
11674                numPers++;
11675            }
11676        }
11677        return numPers;
11678    }
11679
11680    private static final boolean dumpProcessOomList(PrintWriter pw,
11681            ActivityManagerService service, List<ProcessRecord> origList,
11682            String prefix, String normalLabel, String persistentLabel,
11683            boolean inclDetails, String dumpPackage) {
11684
11685        ArrayList<Pair<ProcessRecord, Integer>> list
11686                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11687        for (int i=0; i<origList.size(); i++) {
11688            ProcessRecord r = origList.get(i);
11689            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11690                continue;
11691            }
11692            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11693        }
11694
11695        if (list.size() <= 0) {
11696            return false;
11697        }
11698
11699        Comparator<Pair<ProcessRecord, Integer>> comparator
11700                = new Comparator<Pair<ProcessRecord, Integer>>() {
11701            @Override
11702            public int compare(Pair<ProcessRecord, Integer> object1,
11703                    Pair<ProcessRecord, Integer> object2) {
11704                if (object1.first.setAdj != object2.first.setAdj) {
11705                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11706                }
11707                if (object1.second.intValue() != object2.second.intValue()) {
11708                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11709                }
11710                return 0;
11711            }
11712        };
11713
11714        Collections.sort(list, comparator);
11715
11716        final long curRealtime = SystemClock.elapsedRealtime();
11717        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11718        final long curUptime = SystemClock.uptimeMillis();
11719        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11720
11721        for (int i=list.size()-1; i>=0; i--) {
11722            ProcessRecord r = list.get(i).first;
11723            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11724            char schedGroup;
11725            switch (r.setSchedGroup) {
11726                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11727                    schedGroup = 'B';
11728                    break;
11729                case Process.THREAD_GROUP_DEFAULT:
11730                    schedGroup = 'F';
11731                    break;
11732                default:
11733                    schedGroup = '?';
11734                    break;
11735            }
11736            char foreground;
11737            if (r.foregroundActivities) {
11738                foreground = 'A';
11739            } else if (r.foregroundServices) {
11740                foreground = 'S';
11741            } else {
11742                foreground = ' ';
11743            }
11744            String procState = ProcessList.makeProcStateString(r.curProcState);
11745            pw.print(prefix);
11746            pw.print(r.persistent ? persistentLabel : normalLabel);
11747            pw.print(" #");
11748            int num = (origList.size()-1)-list.get(i).second;
11749            if (num < 10) pw.print(' ');
11750            pw.print(num);
11751            pw.print(": ");
11752            pw.print(oomAdj);
11753            pw.print(' ');
11754            pw.print(schedGroup);
11755            pw.print('/');
11756            pw.print(foreground);
11757            pw.print('/');
11758            pw.print(procState);
11759            pw.print(" trm:");
11760            if (r.trimMemoryLevel < 10) pw.print(' ');
11761            pw.print(r.trimMemoryLevel);
11762            pw.print(' ');
11763            pw.print(r.toShortString());
11764            pw.print(" (");
11765            pw.print(r.adjType);
11766            pw.println(')');
11767            if (r.adjSource != null || r.adjTarget != null) {
11768                pw.print(prefix);
11769                pw.print("    ");
11770                if (r.adjTarget instanceof ComponentName) {
11771                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11772                } else if (r.adjTarget != null) {
11773                    pw.print(r.adjTarget.toString());
11774                } else {
11775                    pw.print("{null}");
11776                }
11777                pw.print("<=");
11778                if (r.adjSource instanceof ProcessRecord) {
11779                    pw.print("Proc{");
11780                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11781                    pw.println("}");
11782                } else if (r.adjSource != null) {
11783                    pw.println(r.adjSource.toString());
11784                } else {
11785                    pw.println("{null}");
11786                }
11787            }
11788            if (inclDetails) {
11789                pw.print(prefix);
11790                pw.print("    ");
11791                pw.print("oom: max="); pw.print(r.maxAdj);
11792                pw.print(" curRaw="); pw.print(r.curRawAdj);
11793                pw.print(" setRaw="); pw.print(r.setRawAdj);
11794                pw.print(" cur="); pw.print(r.curAdj);
11795                pw.print(" set="); pw.println(r.setAdj);
11796                pw.print(prefix);
11797                pw.print("    ");
11798                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11799                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11800                pw.print(" lastPss="); pw.print(r.lastPss);
11801                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11802                pw.print(prefix);
11803                pw.print("    ");
11804                pw.print("keeping="); pw.print(r.keeping);
11805                pw.print(" cached="); pw.print(r.cached);
11806                pw.print(" empty="); pw.print(r.empty);
11807                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11808
11809                if (!r.keeping) {
11810                    if (r.lastWakeTime != 0) {
11811                        long wtime;
11812                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11813                        synchronized (stats) {
11814                            wtime = stats.getProcessWakeTime(r.info.uid,
11815                                    r.pid, curRealtime);
11816                        }
11817                        long timeUsed = wtime - r.lastWakeTime;
11818                        pw.print(prefix);
11819                        pw.print("    ");
11820                        pw.print("keep awake over ");
11821                        TimeUtils.formatDuration(realtimeSince, pw);
11822                        pw.print(" used ");
11823                        TimeUtils.formatDuration(timeUsed, pw);
11824                        pw.print(" (");
11825                        pw.print((timeUsed*100)/realtimeSince);
11826                        pw.println("%)");
11827                    }
11828                    if (r.lastCpuTime != 0) {
11829                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11830                        pw.print(prefix);
11831                        pw.print("    ");
11832                        pw.print("run cpu over ");
11833                        TimeUtils.formatDuration(uptimeSince, pw);
11834                        pw.print(" used ");
11835                        TimeUtils.formatDuration(timeUsed, pw);
11836                        pw.print(" (");
11837                        pw.print((timeUsed*100)/uptimeSince);
11838                        pw.println("%)");
11839                    }
11840                }
11841            }
11842        }
11843        return true;
11844    }
11845
11846    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11847        ArrayList<ProcessRecord> procs;
11848        synchronized (this) {
11849            if (args != null && args.length > start
11850                    && args[start].charAt(0) != '-') {
11851                procs = new ArrayList<ProcessRecord>();
11852                int pid = -1;
11853                try {
11854                    pid = Integer.parseInt(args[start]);
11855                } catch (NumberFormatException e) {
11856                }
11857                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11858                    ProcessRecord proc = mLruProcesses.get(i);
11859                    if (proc.pid == pid) {
11860                        procs.add(proc);
11861                    } else if (proc.processName.equals(args[start])) {
11862                        procs.add(proc);
11863                    }
11864                }
11865                if (procs.size() <= 0) {
11866                    return null;
11867                }
11868            } else {
11869                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11870            }
11871        }
11872        return procs;
11873    }
11874
11875    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11876            PrintWriter pw, String[] args) {
11877        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11878        if (procs == null) {
11879            pw.println("No process found for: " + args[0]);
11880            return;
11881        }
11882
11883        long uptime = SystemClock.uptimeMillis();
11884        long realtime = SystemClock.elapsedRealtime();
11885        pw.println("Applications Graphics Acceleration Info:");
11886        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11887
11888        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11889            ProcessRecord r = procs.get(i);
11890            if (r.thread != null) {
11891                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11892                pw.flush();
11893                try {
11894                    TransferPipe tp = new TransferPipe();
11895                    try {
11896                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11897                        tp.go(fd);
11898                    } finally {
11899                        tp.kill();
11900                    }
11901                } catch (IOException e) {
11902                    pw.println("Failure while dumping the app: " + r);
11903                    pw.flush();
11904                } catch (RemoteException e) {
11905                    pw.println("Got a RemoteException while dumping the app " + r);
11906                    pw.flush();
11907                }
11908            }
11909        }
11910    }
11911
11912    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11913        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11914        if (procs == null) {
11915            pw.println("No process found for: " + args[0]);
11916            return;
11917        }
11918
11919        pw.println("Applications Database Info:");
11920
11921        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11922            ProcessRecord r = procs.get(i);
11923            if (r.thread != null) {
11924                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11925                pw.flush();
11926                try {
11927                    TransferPipe tp = new TransferPipe();
11928                    try {
11929                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11930                        tp.go(fd);
11931                    } finally {
11932                        tp.kill();
11933                    }
11934                } catch (IOException e) {
11935                    pw.println("Failure while dumping the app: " + r);
11936                    pw.flush();
11937                } catch (RemoteException e) {
11938                    pw.println("Got a RemoteException while dumping the app " + r);
11939                    pw.flush();
11940                }
11941            }
11942        }
11943    }
11944
11945    final static class MemItem {
11946        final boolean isProc;
11947        final String label;
11948        final String shortLabel;
11949        final long pss;
11950        final int id;
11951        final boolean hasActivities;
11952        ArrayList<MemItem> subitems;
11953
11954        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11955                boolean _hasActivities) {
11956            isProc = true;
11957            label = _label;
11958            shortLabel = _shortLabel;
11959            pss = _pss;
11960            id = _id;
11961            hasActivities = _hasActivities;
11962        }
11963
11964        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11965            isProc = false;
11966            label = _label;
11967            shortLabel = _shortLabel;
11968            pss = _pss;
11969            id = _id;
11970            hasActivities = false;
11971        }
11972    }
11973
11974    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11975            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11976        if (sort && !isCompact) {
11977            Collections.sort(items, new Comparator<MemItem>() {
11978                @Override
11979                public int compare(MemItem lhs, MemItem rhs) {
11980                    if (lhs.pss < rhs.pss) {
11981                        return 1;
11982                    } else if (lhs.pss > rhs.pss) {
11983                        return -1;
11984                    }
11985                    return 0;
11986                }
11987            });
11988        }
11989
11990        for (int i=0; i<items.size(); i++) {
11991            MemItem mi = items.get(i);
11992            if (!isCompact) {
11993                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11994            } else if (mi.isProc) {
11995                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11996                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11997                pw.println(mi.hasActivities ? ",a" : ",e");
11998            } else {
11999                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12000                pw.println(mi.pss);
12001            }
12002            if (mi.subitems != null) {
12003                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12004                        true, isCompact);
12005            }
12006        }
12007    }
12008
12009    // These are in KB.
12010    static final long[] DUMP_MEM_BUCKETS = new long[] {
12011        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12012        120*1024, 160*1024, 200*1024,
12013        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12014        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12015    };
12016
12017    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12018            boolean stackLike) {
12019        int start = label.lastIndexOf('.');
12020        if (start >= 0) start++;
12021        else start = 0;
12022        int end = label.length();
12023        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12024            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12025                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12026                out.append(bucket);
12027                out.append(stackLike ? "MB." : "MB ");
12028                out.append(label, start, end);
12029                return;
12030            }
12031        }
12032        out.append(memKB/1024);
12033        out.append(stackLike ? "MB." : "MB ");
12034        out.append(label, start, end);
12035    }
12036
12037    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12038            ProcessList.NATIVE_ADJ,
12039            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12040            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12041            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12042            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12043            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12044    };
12045    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12046            "Native",
12047            "System", "Persistent", "Foreground",
12048            "Visible", "Perceptible",
12049            "Heavy Weight", "Backup",
12050            "A Services", "Home",
12051            "Previous", "B Services", "Cached"
12052    };
12053    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12054            "native",
12055            "sys", "pers", "fore",
12056            "vis", "percept",
12057            "heavy", "backup",
12058            "servicea", "home",
12059            "prev", "serviceb", "cached"
12060    };
12061
12062    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12063            long realtime, boolean isCheckinRequest, boolean isCompact) {
12064        if (isCheckinRequest || isCompact) {
12065            // short checkin version
12066            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12067        } else {
12068            pw.println("Applications Memory Usage (kB):");
12069            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12070        }
12071    }
12072
12073    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12074            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12075        boolean dumpDetails = false;
12076        boolean dumpFullDetails = false;
12077        boolean dumpDalvik = false;
12078        boolean oomOnly = false;
12079        boolean isCompact = false;
12080        boolean localOnly = false;
12081
12082        int opti = 0;
12083        while (opti < args.length) {
12084            String opt = args[opti];
12085            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12086                break;
12087            }
12088            opti++;
12089            if ("-a".equals(opt)) {
12090                dumpDetails = true;
12091                dumpFullDetails = true;
12092                dumpDalvik = true;
12093            } else if ("-d".equals(opt)) {
12094                dumpDalvik = true;
12095            } else if ("-c".equals(opt)) {
12096                isCompact = true;
12097            } else if ("--oom".equals(opt)) {
12098                oomOnly = true;
12099            } else if ("--local".equals(opt)) {
12100                localOnly = true;
12101            } else if ("-h".equals(opt)) {
12102                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12103                pw.println("  -a: include all available information for each process.");
12104                pw.println("  -d: include dalvik details when dumping process details.");
12105                pw.println("  -c: dump in a compact machine-parseable representation.");
12106                pw.println("  --oom: only show processes organized by oom adj.");
12107                pw.println("  --local: only collect details locally, don't call process.");
12108                pw.println("If [process] is specified it can be the name or ");
12109                pw.println("pid of a specific process to dump.");
12110                return;
12111            } else {
12112                pw.println("Unknown argument: " + opt + "; use -h for help");
12113            }
12114        }
12115
12116        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12117        long uptime = SystemClock.uptimeMillis();
12118        long realtime = SystemClock.elapsedRealtime();
12119        final long[] tmpLong = new long[1];
12120
12121        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12122        if (procs == null) {
12123            // No Java processes.  Maybe they want to print a native process.
12124            if (args != null && args.length > opti
12125                    && args[opti].charAt(0) != '-') {
12126                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12127                        = new ArrayList<ProcessCpuTracker.Stats>();
12128                updateCpuStatsNow();
12129                int findPid = -1;
12130                try {
12131                    findPid = Integer.parseInt(args[opti]);
12132                } catch (NumberFormatException e) {
12133                }
12134                synchronized (mProcessCpuThread) {
12135                    final int N = mProcessCpuTracker.countStats();
12136                    for (int i=0; i<N; i++) {
12137                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12138                        if (st.pid == findPid || (st.baseName != null
12139                                && st.baseName.equals(args[opti]))) {
12140                            nativeProcs.add(st);
12141                        }
12142                    }
12143                }
12144                if (nativeProcs.size() > 0) {
12145                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12146                            isCompact);
12147                    Debug.MemoryInfo mi = null;
12148                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12149                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12150                        final int pid = r.pid;
12151                        if (!isCheckinRequest && dumpDetails) {
12152                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12153                        }
12154                        if (mi == null) {
12155                            mi = new Debug.MemoryInfo();
12156                        }
12157                        if (dumpDetails || (!brief && !oomOnly)) {
12158                            Debug.getMemoryInfo(pid, mi);
12159                        } else {
12160                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12161                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12162                        }
12163                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12164                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12165                        if (isCheckinRequest) {
12166                            pw.println();
12167                        }
12168                    }
12169                    return;
12170                }
12171            }
12172            pw.println("No process found for: " + args[opti]);
12173            return;
12174        }
12175
12176        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12177            dumpDetails = true;
12178        }
12179
12180        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12181
12182        String[] innerArgs = new String[args.length-opti];
12183        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12184
12185        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12186        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12187        long nativePss=0, dalvikPss=0, otherPss=0;
12188        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12189
12190        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12191        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12192                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12193
12194        long totalPss = 0;
12195        long cachedPss = 0;
12196
12197        Debug.MemoryInfo mi = null;
12198        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12199            final ProcessRecord r = procs.get(i);
12200            final IApplicationThread thread;
12201            final int pid;
12202            final int oomAdj;
12203            final boolean hasActivities;
12204            synchronized (this) {
12205                thread = r.thread;
12206                pid = r.pid;
12207                oomAdj = r.getSetAdjWithServices();
12208                hasActivities = r.activities.size() > 0;
12209            }
12210            if (thread != null) {
12211                if (!isCheckinRequest && dumpDetails) {
12212                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12213                }
12214                if (mi == null) {
12215                    mi = new Debug.MemoryInfo();
12216                }
12217                if (dumpDetails || (!brief && !oomOnly)) {
12218                    Debug.getMemoryInfo(pid, mi);
12219                } else {
12220                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12221                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12222                }
12223                if (dumpDetails) {
12224                    if (localOnly) {
12225                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12226                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12227                        if (isCheckinRequest) {
12228                            pw.println();
12229                        }
12230                    } else {
12231                        try {
12232                            pw.flush();
12233                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12234                                    dumpDalvik, innerArgs);
12235                        } catch (RemoteException e) {
12236                            if (!isCheckinRequest) {
12237                                pw.println("Got RemoteException!");
12238                                pw.flush();
12239                            }
12240                        }
12241                    }
12242                }
12243
12244                final long myTotalPss = mi.getTotalPss();
12245                final long myTotalUss = mi.getTotalUss();
12246
12247                synchronized (this) {
12248                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12249                        // Record this for posterity if the process has been stable.
12250                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12251                    }
12252                }
12253
12254                if (!isCheckinRequest && mi != null) {
12255                    totalPss += myTotalPss;
12256                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12257                            (hasActivities ? " / activities)" : ")"),
12258                            r.processName, myTotalPss, pid, hasActivities);
12259                    procMems.add(pssItem);
12260                    procMemsMap.put(pid, pssItem);
12261
12262                    nativePss += mi.nativePss;
12263                    dalvikPss += mi.dalvikPss;
12264                    otherPss += mi.otherPss;
12265                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12266                        long mem = mi.getOtherPss(j);
12267                        miscPss[j] += mem;
12268                        otherPss -= mem;
12269                    }
12270
12271                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12272                        cachedPss += myTotalPss;
12273                    }
12274
12275                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12276                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12277                                || oomIndex == (oomPss.length-1)) {
12278                            oomPss[oomIndex] += myTotalPss;
12279                            if (oomProcs[oomIndex] == null) {
12280                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12281                            }
12282                            oomProcs[oomIndex].add(pssItem);
12283                            break;
12284                        }
12285                    }
12286                }
12287            }
12288        }
12289
12290        if (!isCheckinRequest && procs.size() > 1) {
12291            // If we are showing aggregations, also look for native processes to
12292            // include so that our aggregations are more accurate.
12293            updateCpuStatsNow();
12294            synchronized (mProcessCpuThread) {
12295                final int N = mProcessCpuTracker.countStats();
12296                for (int i=0; i<N; i++) {
12297                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12298                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12299                        if (mi == null) {
12300                            mi = new Debug.MemoryInfo();
12301                        }
12302                        if (!brief && !oomOnly) {
12303                            Debug.getMemoryInfo(st.pid, mi);
12304                        } else {
12305                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12306                            mi.nativePrivateDirty = (int)tmpLong[0];
12307                        }
12308
12309                        final long myTotalPss = mi.getTotalPss();
12310                        totalPss += myTotalPss;
12311
12312                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12313                                st.name, myTotalPss, st.pid, false);
12314                        procMems.add(pssItem);
12315
12316                        nativePss += mi.nativePss;
12317                        dalvikPss += mi.dalvikPss;
12318                        otherPss += mi.otherPss;
12319                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12320                            long mem = mi.getOtherPss(j);
12321                            miscPss[j] += mem;
12322                            otherPss -= mem;
12323                        }
12324                        oomPss[0] += myTotalPss;
12325                        if (oomProcs[0] == null) {
12326                            oomProcs[0] = new ArrayList<MemItem>();
12327                        }
12328                        oomProcs[0].add(pssItem);
12329                    }
12330                }
12331            }
12332
12333            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12334
12335            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12336            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12337            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12338            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12339                String label = Debug.MemoryInfo.getOtherLabel(j);
12340                catMems.add(new MemItem(label, label, miscPss[j], j));
12341            }
12342
12343            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12344            for (int j=0; j<oomPss.length; j++) {
12345                if (oomPss[j] != 0) {
12346                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12347                            : DUMP_MEM_OOM_LABEL[j];
12348                    MemItem item = new MemItem(label, label, oomPss[j],
12349                            DUMP_MEM_OOM_ADJ[j]);
12350                    item.subitems = oomProcs[j];
12351                    oomMems.add(item);
12352                }
12353            }
12354
12355            if (!brief && !oomOnly && !isCompact) {
12356                pw.println();
12357                pw.println("Total PSS by process:");
12358                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12359                pw.println();
12360            }
12361            if (!isCompact) {
12362                pw.println("Total PSS by OOM adjustment:");
12363            }
12364            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12365            if (!brief && !oomOnly) {
12366                PrintWriter out = categoryPw != null ? categoryPw : pw;
12367                if (!isCompact) {
12368                    out.println();
12369                    out.println("Total PSS by category:");
12370                }
12371                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12372            }
12373            if (!isCompact) {
12374                pw.println();
12375            }
12376            MemInfoReader memInfo = new MemInfoReader();
12377            memInfo.readMemInfo();
12378            if (!brief) {
12379                if (!isCompact) {
12380                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12381                    pw.print(" kB (status ");
12382                    switch (mLastMemoryLevel) {
12383                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12384                            pw.println("normal)");
12385                            break;
12386                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12387                            pw.println("moderate)");
12388                            break;
12389                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12390                            pw.println("low)");
12391                            break;
12392                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12393                            pw.println("critical)");
12394                            break;
12395                        default:
12396                            pw.print(mLastMemoryLevel);
12397                            pw.println(")");
12398                            break;
12399                    }
12400                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12401                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12402                            pw.print(cachedPss); pw.print(" cached pss + ");
12403                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12404                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12405                } else {
12406                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12407                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12408                            + memInfo.getFreeSizeKb()); pw.print(",");
12409                    pw.println(totalPss - cachedPss);
12410                }
12411            }
12412            if (!isCompact) {
12413                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12414                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12415                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12416                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12417                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12418                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12419                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12420                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12421                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12422                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12423                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12424            }
12425            if (!brief) {
12426                if (memInfo.getZramTotalSizeKb() != 0) {
12427                    if (!isCompact) {
12428                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12429                                pw.print(" kB physical used for ");
12430                                pw.print(memInfo.getSwapTotalSizeKb()
12431                                        - memInfo.getSwapFreeSizeKb());
12432                                pw.print(" kB in swap (");
12433                                pw.print(memInfo.getSwapTotalSizeKb());
12434                                pw.println(" kB total swap)");
12435                    } else {
12436                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12437                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12438                                pw.println(memInfo.getSwapFreeSizeKb());
12439                    }
12440                }
12441                final int[] SINGLE_LONG_FORMAT = new int[] {
12442                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12443                };
12444                long[] longOut = new long[1];
12445                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12446                        SINGLE_LONG_FORMAT, null, longOut, null);
12447                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12448                longOut[0] = 0;
12449                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12450                        SINGLE_LONG_FORMAT, null, longOut, null);
12451                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12452                longOut[0] = 0;
12453                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12454                        SINGLE_LONG_FORMAT, null, longOut, null);
12455                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12456                longOut[0] = 0;
12457                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12458                        SINGLE_LONG_FORMAT, null, longOut, null);
12459                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12460                if (!isCompact) {
12461                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12462                        pw.print("      KSM: "); pw.print(sharing);
12463                                pw.print(" kB saved from shared ");
12464                                pw.print(shared); pw.println(" kB");
12465                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12466                                pw.print(voltile); pw.println(" kB volatile");
12467                    }
12468                    pw.print("   Tuning: ");
12469                    pw.print(ActivityManager.staticGetMemoryClass());
12470                    pw.print(" (large ");
12471                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12472                    pw.print("), oom ");
12473                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12474                    pw.print(" kB");
12475                    pw.print(", restore limit ");
12476                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12477                    pw.print(" kB");
12478                    if (ActivityManager.isLowRamDeviceStatic()) {
12479                        pw.print(" (low-ram)");
12480                    }
12481                    if (ActivityManager.isHighEndGfx()) {
12482                        pw.print(" (high-end-gfx)");
12483                    }
12484                    pw.println();
12485                } else {
12486                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12487                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12488                    pw.println(voltile);
12489                    pw.print("tuning,");
12490                    pw.print(ActivityManager.staticGetMemoryClass());
12491                    pw.print(',');
12492                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12493                    pw.print(',');
12494                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12495                    if (ActivityManager.isLowRamDeviceStatic()) {
12496                        pw.print(",low-ram");
12497                    }
12498                    if (ActivityManager.isHighEndGfx()) {
12499                        pw.print(",high-end-gfx");
12500                    }
12501                    pw.println();
12502                }
12503            }
12504        }
12505    }
12506
12507    /**
12508     * Searches array of arguments for the specified string
12509     * @param args array of argument strings
12510     * @param value value to search for
12511     * @return true if the value is contained in the array
12512     */
12513    private static boolean scanArgs(String[] args, String value) {
12514        if (args != null) {
12515            for (String arg : args) {
12516                if (value.equals(arg)) {
12517                    return true;
12518                }
12519            }
12520        }
12521        return false;
12522    }
12523
12524    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12525            ContentProviderRecord cpr, boolean always) {
12526        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12527
12528        if (!inLaunching || always) {
12529            synchronized (cpr) {
12530                cpr.launchingApp = null;
12531                cpr.notifyAll();
12532            }
12533            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12534            String names[] = cpr.info.authority.split(";");
12535            for (int j = 0; j < names.length; j++) {
12536                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12537            }
12538        }
12539
12540        for (int i=0; i<cpr.connections.size(); i++) {
12541            ContentProviderConnection conn = cpr.connections.get(i);
12542            if (conn.waiting) {
12543                // If this connection is waiting for the provider, then we don't
12544                // need to mess with its process unless we are always removing
12545                // or for some reason the provider is not currently launching.
12546                if (inLaunching && !always) {
12547                    continue;
12548                }
12549            }
12550            ProcessRecord capp = conn.client;
12551            conn.dead = true;
12552            if (conn.stableCount > 0) {
12553                if (!capp.persistent && capp.thread != null
12554                        && capp.pid != 0
12555                        && capp.pid != MY_PID) {
12556                    killUnneededProcessLocked(capp, "depends on provider "
12557                            + cpr.name.flattenToShortString()
12558                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12559                }
12560            } else if (capp.thread != null && conn.provider.provider != null) {
12561                try {
12562                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12563                } catch (RemoteException e) {
12564                }
12565                // In the protocol here, we don't expect the client to correctly
12566                // clean up this connection, we'll just remove it.
12567                cpr.connections.remove(i);
12568                conn.client.conProviders.remove(conn);
12569            }
12570        }
12571
12572        if (inLaunching && always) {
12573            mLaunchingProviders.remove(cpr);
12574        }
12575        return inLaunching;
12576    }
12577
12578    /**
12579     * Main code for cleaning up a process when it has gone away.  This is
12580     * called both as a result of the process dying, or directly when stopping
12581     * a process when running in single process mode.
12582     */
12583    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12584            boolean restarting, boolean allowRestart, int index) {
12585        if (index >= 0) {
12586            removeLruProcessLocked(app);
12587            ProcessList.remove(app.pid);
12588        }
12589
12590        mProcessesToGc.remove(app);
12591        mPendingPssProcesses.remove(app);
12592
12593        // Dismiss any open dialogs.
12594        if (app.crashDialog != null && !app.forceCrashReport) {
12595            app.crashDialog.dismiss();
12596            app.crashDialog = null;
12597        }
12598        if (app.anrDialog != null) {
12599            app.anrDialog.dismiss();
12600            app.anrDialog = null;
12601        }
12602        if (app.waitDialog != null) {
12603            app.waitDialog.dismiss();
12604            app.waitDialog = null;
12605        }
12606
12607        app.crashing = false;
12608        app.notResponding = false;
12609
12610        app.resetPackageList(mProcessStats);
12611        app.unlinkDeathRecipient();
12612        app.makeInactive(mProcessStats);
12613        app.forcingToForeground = null;
12614        updateProcessForegroundLocked(app, false, false);
12615        app.foregroundActivities = false;
12616        app.hasShownUi = false;
12617        app.treatLikeActivity = false;
12618        app.hasAboveClient = false;
12619        app.hasClientActivities = false;
12620
12621        mServices.killServicesLocked(app, allowRestart);
12622
12623        boolean restart = false;
12624
12625        // Remove published content providers.
12626        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12627            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12628            final boolean always = app.bad || !allowRestart;
12629            if (removeDyingProviderLocked(app, cpr, always) || always) {
12630                // We left the provider in the launching list, need to
12631                // restart it.
12632                restart = true;
12633            }
12634
12635            cpr.provider = null;
12636            cpr.proc = null;
12637        }
12638        app.pubProviders.clear();
12639
12640        // Take care of any launching providers waiting for this process.
12641        if (checkAppInLaunchingProvidersLocked(app, false)) {
12642            restart = true;
12643        }
12644
12645        // Unregister from connected content providers.
12646        if (!app.conProviders.isEmpty()) {
12647            for (int i=0; i<app.conProviders.size(); i++) {
12648                ContentProviderConnection conn = app.conProviders.get(i);
12649                conn.provider.connections.remove(conn);
12650            }
12651            app.conProviders.clear();
12652        }
12653
12654        // At this point there may be remaining entries in mLaunchingProviders
12655        // where we were the only one waiting, so they are no longer of use.
12656        // Look for these and clean up if found.
12657        // XXX Commented out for now.  Trying to figure out a way to reproduce
12658        // the actual situation to identify what is actually going on.
12659        if (false) {
12660            for (int i=0; i<mLaunchingProviders.size(); i++) {
12661                ContentProviderRecord cpr = (ContentProviderRecord)
12662                        mLaunchingProviders.get(i);
12663                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12664                    synchronized (cpr) {
12665                        cpr.launchingApp = null;
12666                        cpr.notifyAll();
12667                    }
12668                }
12669            }
12670        }
12671
12672        skipCurrentReceiverLocked(app);
12673
12674        // Unregister any receivers.
12675        for (int i=app.receivers.size()-1; i>=0; i--) {
12676            removeReceiverLocked(app.receivers.valueAt(i));
12677        }
12678        app.receivers.clear();
12679
12680        // If the app is undergoing backup, tell the backup manager about it
12681        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12682            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12683                    + mBackupTarget.appInfo + " died during backup");
12684            try {
12685                IBackupManager bm = IBackupManager.Stub.asInterface(
12686                        ServiceManager.getService(Context.BACKUP_SERVICE));
12687                bm.agentDisconnected(app.info.packageName);
12688            } catch (RemoteException e) {
12689                // can't happen; backup manager is local
12690            }
12691        }
12692
12693        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12694            ProcessChangeItem item = mPendingProcessChanges.get(i);
12695            if (item.pid == app.pid) {
12696                mPendingProcessChanges.remove(i);
12697                mAvailProcessChanges.add(item);
12698            }
12699        }
12700        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12701
12702        // If the caller is restarting this app, then leave it in its
12703        // current lists and let the caller take care of it.
12704        if (restarting) {
12705            return;
12706        }
12707
12708        if (!app.persistent || app.isolated) {
12709            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12710                    "Removing non-persistent process during cleanup: " + app);
12711            mProcessNames.remove(app.processName, app.uid);
12712            mIsolatedProcesses.remove(app.uid);
12713            if (mHeavyWeightProcess == app) {
12714                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12715                        mHeavyWeightProcess.userId, 0));
12716                mHeavyWeightProcess = null;
12717            }
12718        } else if (!app.removed) {
12719            // This app is persistent, so we need to keep its record around.
12720            // If it is not already on the pending app list, add it there
12721            // and start a new process for it.
12722            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12723                mPersistentStartingProcesses.add(app);
12724                restart = true;
12725            }
12726        }
12727        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12728                "Clean-up removing on hold: " + app);
12729        mProcessesOnHold.remove(app);
12730
12731        if (app == mHomeProcess) {
12732            mHomeProcess = null;
12733        }
12734        if (app == mPreviousProcess) {
12735            mPreviousProcess = null;
12736        }
12737
12738        if (restart && !app.isolated) {
12739            // We have components that still need to be running in the
12740            // process, so re-launch it.
12741            mProcessNames.put(app.processName, app.uid, app);
12742            startProcessLocked(app, "restart", app.processName);
12743        } else if (app.pid > 0 && app.pid != MY_PID) {
12744            // Goodbye!
12745            boolean removed;
12746            synchronized (mPidsSelfLocked) {
12747                mPidsSelfLocked.remove(app.pid);
12748                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12749            }
12750            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12751                    app.processName, app.info.uid);
12752            if (app.isolated) {
12753                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12754            }
12755            app.setPid(0);
12756        }
12757    }
12758
12759    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12760        // Look through the content providers we are waiting to have launched,
12761        // and if any run in this process then either schedule a restart of
12762        // the process or kill the client waiting for it if this process has
12763        // gone bad.
12764        int NL = mLaunchingProviders.size();
12765        boolean restart = false;
12766        for (int i=0; i<NL; i++) {
12767            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12768            if (cpr.launchingApp == app) {
12769                if (!alwaysBad && !app.bad) {
12770                    restart = true;
12771                } else {
12772                    removeDyingProviderLocked(app, cpr, true);
12773                    // cpr should have been removed from mLaunchingProviders
12774                    NL = mLaunchingProviders.size();
12775                    i--;
12776                }
12777            }
12778        }
12779        return restart;
12780    }
12781
12782    // =========================================================
12783    // SERVICES
12784    // =========================================================
12785
12786    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12787            int flags) {
12788        enforceNotIsolatedCaller("getServices");
12789        synchronized (this) {
12790            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12791        }
12792    }
12793
12794    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12795        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12796        synchronized (this) {
12797            return mServices.getRunningServiceControlPanelLocked(name);
12798        }
12799    }
12800
12801    public ComponentName startService(IApplicationThread caller, Intent service,
12802            String resolvedType, int userId) {
12803        enforceNotIsolatedCaller("startService");
12804        // Refuse possible leaked file descriptors
12805        if (service != null && service.hasFileDescriptors() == true) {
12806            throw new IllegalArgumentException("File descriptors passed in Intent");
12807        }
12808
12809        if (DEBUG_SERVICE)
12810            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12811        synchronized(this) {
12812            final int callingPid = Binder.getCallingPid();
12813            final int callingUid = Binder.getCallingUid();
12814            final long origId = Binder.clearCallingIdentity();
12815            ComponentName res = mServices.startServiceLocked(caller, service,
12816                    resolvedType, callingPid, callingUid, userId);
12817            Binder.restoreCallingIdentity(origId);
12818            return res;
12819        }
12820    }
12821
12822    ComponentName startServiceInPackage(int uid,
12823            Intent service, String resolvedType, int userId) {
12824        synchronized(this) {
12825            if (DEBUG_SERVICE)
12826                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12827            final long origId = Binder.clearCallingIdentity();
12828            ComponentName res = mServices.startServiceLocked(null, service,
12829                    resolvedType, -1, uid, userId);
12830            Binder.restoreCallingIdentity(origId);
12831            return res;
12832        }
12833    }
12834
12835    public int stopService(IApplicationThread caller, Intent service,
12836            String resolvedType, int userId) {
12837        enforceNotIsolatedCaller("stopService");
12838        // Refuse possible leaked file descriptors
12839        if (service != null && service.hasFileDescriptors() == true) {
12840            throw new IllegalArgumentException("File descriptors passed in Intent");
12841        }
12842
12843        synchronized(this) {
12844            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12845        }
12846    }
12847
12848    public IBinder peekService(Intent service, String resolvedType) {
12849        enforceNotIsolatedCaller("peekService");
12850        // Refuse possible leaked file descriptors
12851        if (service != null && service.hasFileDescriptors() == true) {
12852            throw new IllegalArgumentException("File descriptors passed in Intent");
12853        }
12854        synchronized(this) {
12855            return mServices.peekServiceLocked(service, resolvedType);
12856        }
12857    }
12858
12859    public boolean stopServiceToken(ComponentName className, IBinder token,
12860            int startId) {
12861        synchronized(this) {
12862            return mServices.stopServiceTokenLocked(className, token, startId);
12863        }
12864    }
12865
12866    public void setServiceForeground(ComponentName className, IBinder token,
12867            int id, Notification notification, boolean removeNotification) {
12868        synchronized(this) {
12869            mServices.setServiceForegroundLocked(className, token, id, notification,
12870                    removeNotification);
12871        }
12872    }
12873
12874    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12875            boolean requireFull, String name, String callerPackage) {
12876        final int callingUserId = UserHandle.getUserId(callingUid);
12877        if (callingUserId != userId) {
12878            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12879                if ((requireFull || checkComponentPermission(
12880                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12881                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12882                        && checkComponentPermission(
12883                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12884                                callingPid, callingUid, -1, true)
12885                                != PackageManager.PERMISSION_GRANTED) {
12886                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12887                        // In this case, they would like to just execute as their
12888                        // owner user instead of failing.
12889                        userId = callingUserId;
12890                    } else {
12891                        StringBuilder builder = new StringBuilder(128);
12892                        builder.append("Permission Denial: ");
12893                        builder.append(name);
12894                        if (callerPackage != null) {
12895                            builder.append(" from ");
12896                            builder.append(callerPackage);
12897                        }
12898                        builder.append(" asks to run as user ");
12899                        builder.append(userId);
12900                        builder.append(" but is calling from user ");
12901                        builder.append(UserHandle.getUserId(callingUid));
12902                        builder.append("; this requires ");
12903                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12904                        if (!requireFull) {
12905                            builder.append(" or ");
12906                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12907                        }
12908                        String msg = builder.toString();
12909                        Slog.w(TAG, msg);
12910                        throw new SecurityException(msg);
12911                    }
12912                }
12913            }
12914            if (userId == UserHandle.USER_CURRENT
12915                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12916                // Note that we may be accessing this outside of a lock...
12917                // shouldn't be a big deal, if this is being called outside
12918                // of a locked context there is intrinsically a race with
12919                // the value the caller will receive and someone else changing it.
12920                userId = mCurrentUserId;
12921            }
12922            if (!allowAll && userId < 0) {
12923                throw new IllegalArgumentException(
12924                        "Call does not support special user #" + userId);
12925            }
12926        }
12927        return userId;
12928    }
12929
12930    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12931            String className, int flags) {
12932        boolean result = false;
12933        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12934            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12935                if (ActivityManager.checkUidPermission(
12936                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12937                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12938                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12939                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12940                            + " requests FLAG_SINGLE_USER, but app does not hold "
12941                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12942                    Slog.w(TAG, msg);
12943                    throw new SecurityException(msg);
12944                }
12945                result = true;
12946            }
12947        } else if (componentProcessName == aInfo.packageName) {
12948            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12949        } else if ("system".equals(componentProcessName)) {
12950            result = true;
12951        }
12952        if (DEBUG_MU) {
12953            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12954                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12955        }
12956        return result;
12957    }
12958
12959    public int bindService(IApplicationThread caller, IBinder token,
12960            Intent service, String resolvedType,
12961            IServiceConnection connection, int flags, int userId) {
12962        enforceNotIsolatedCaller("bindService");
12963        // Refuse possible leaked file descriptors
12964        if (service != null && service.hasFileDescriptors() == true) {
12965            throw new IllegalArgumentException("File descriptors passed in Intent");
12966        }
12967
12968        synchronized(this) {
12969            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12970                    connection, flags, userId);
12971        }
12972    }
12973
12974    public boolean unbindService(IServiceConnection connection) {
12975        synchronized (this) {
12976            return mServices.unbindServiceLocked(connection);
12977        }
12978    }
12979
12980    public void publishService(IBinder token, Intent intent, IBinder service) {
12981        // Refuse possible leaked file descriptors
12982        if (intent != null && intent.hasFileDescriptors() == true) {
12983            throw new IllegalArgumentException("File descriptors passed in Intent");
12984        }
12985
12986        synchronized(this) {
12987            if (!(token instanceof ServiceRecord)) {
12988                throw new IllegalArgumentException("Invalid service token");
12989            }
12990            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12991        }
12992    }
12993
12994    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12995        // Refuse possible leaked file descriptors
12996        if (intent != null && intent.hasFileDescriptors() == true) {
12997            throw new IllegalArgumentException("File descriptors passed in Intent");
12998        }
12999
13000        synchronized(this) {
13001            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13002        }
13003    }
13004
13005    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13006        synchronized(this) {
13007            if (!(token instanceof ServiceRecord)) {
13008                throw new IllegalArgumentException("Invalid service token");
13009            }
13010            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13011        }
13012    }
13013
13014    // =========================================================
13015    // BACKUP AND RESTORE
13016    // =========================================================
13017
13018    // Cause the target app to be launched if necessary and its backup agent
13019    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13020    // activity manager to announce its creation.
13021    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13022        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13023        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13024
13025        synchronized(this) {
13026            // !!! TODO: currently no check here that we're already bound
13027            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13028            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13029            synchronized (stats) {
13030                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13031            }
13032
13033            // Backup agent is now in use, its package can't be stopped.
13034            try {
13035                AppGlobals.getPackageManager().setPackageStoppedState(
13036                        app.packageName, false, UserHandle.getUserId(app.uid));
13037            } catch (RemoteException e) {
13038            } catch (IllegalArgumentException e) {
13039                Slog.w(TAG, "Failed trying to unstop package "
13040                        + app.packageName + ": " + e);
13041            }
13042
13043            BackupRecord r = new BackupRecord(ss, app, backupMode);
13044            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13045                    ? new ComponentName(app.packageName, app.backupAgentName)
13046                    : new ComponentName("android", "FullBackupAgent");
13047            // startProcessLocked() returns existing proc's record if it's already running
13048            ProcessRecord proc = startProcessLocked(app.processName, app,
13049                    false, 0, "backup", hostingName, false, false, false);
13050            if (proc == null) {
13051                Slog.e(TAG, "Unable to start backup agent process " + r);
13052                return false;
13053            }
13054
13055            r.app = proc;
13056            mBackupTarget = r;
13057            mBackupAppName = app.packageName;
13058
13059            // Try not to kill the process during backup
13060            updateOomAdjLocked(proc);
13061
13062            // If the process is already attached, schedule the creation of the backup agent now.
13063            // If it is not yet live, this will be done when it attaches to the framework.
13064            if (proc.thread != null) {
13065                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13066                try {
13067                    proc.thread.scheduleCreateBackupAgent(app,
13068                            compatibilityInfoForPackageLocked(app), backupMode);
13069                } catch (RemoteException e) {
13070                    // Will time out on the backup manager side
13071                }
13072            } else {
13073                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13074            }
13075            // Invariants: at this point, the target app process exists and the application
13076            // is either already running or in the process of coming up.  mBackupTarget and
13077            // mBackupAppName describe the app, so that when it binds back to the AM we
13078            // know that it's scheduled for a backup-agent operation.
13079        }
13080
13081        return true;
13082    }
13083
13084    @Override
13085    public void clearPendingBackup() {
13086        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13087        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13088
13089        synchronized (this) {
13090            mBackupTarget = null;
13091            mBackupAppName = null;
13092        }
13093    }
13094
13095    // A backup agent has just come up
13096    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13097        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13098                + " = " + agent);
13099
13100        synchronized(this) {
13101            if (!agentPackageName.equals(mBackupAppName)) {
13102                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13103                return;
13104            }
13105        }
13106
13107        long oldIdent = Binder.clearCallingIdentity();
13108        try {
13109            IBackupManager bm = IBackupManager.Stub.asInterface(
13110                    ServiceManager.getService(Context.BACKUP_SERVICE));
13111            bm.agentConnected(agentPackageName, agent);
13112        } catch (RemoteException e) {
13113            // can't happen; the backup manager service is local
13114        } catch (Exception e) {
13115            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13116            e.printStackTrace();
13117        } finally {
13118            Binder.restoreCallingIdentity(oldIdent);
13119        }
13120    }
13121
13122    // done with this agent
13123    public void unbindBackupAgent(ApplicationInfo appInfo) {
13124        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13125        if (appInfo == null) {
13126            Slog.w(TAG, "unbind backup agent for null app");
13127            return;
13128        }
13129
13130        synchronized(this) {
13131            try {
13132                if (mBackupAppName == null) {
13133                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13134                    return;
13135                }
13136
13137                if (!mBackupAppName.equals(appInfo.packageName)) {
13138                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13139                    return;
13140                }
13141
13142                // Not backing this app up any more; reset its OOM adjustment
13143                final ProcessRecord proc = mBackupTarget.app;
13144                updateOomAdjLocked(proc);
13145
13146                // If the app crashed during backup, 'thread' will be null here
13147                if (proc.thread != null) {
13148                    try {
13149                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13150                                compatibilityInfoForPackageLocked(appInfo));
13151                    } catch (Exception e) {
13152                        Slog.e(TAG, "Exception when unbinding backup agent:");
13153                        e.printStackTrace();
13154                    }
13155                }
13156            } finally {
13157                mBackupTarget = null;
13158                mBackupAppName = null;
13159            }
13160        }
13161    }
13162    // =========================================================
13163    // BROADCASTS
13164    // =========================================================
13165
13166    private final List getStickiesLocked(String action, IntentFilter filter,
13167            List cur, int userId) {
13168        final ContentResolver resolver = mContext.getContentResolver();
13169        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13170        if (stickies == null) {
13171            return cur;
13172        }
13173        final ArrayList<Intent> list = stickies.get(action);
13174        if (list == null) {
13175            return cur;
13176        }
13177        int N = list.size();
13178        for (int i=0; i<N; i++) {
13179            Intent intent = list.get(i);
13180            if (filter.match(resolver, intent, true, TAG) >= 0) {
13181                if (cur == null) {
13182                    cur = new ArrayList<Intent>();
13183                }
13184                cur.add(intent);
13185            }
13186        }
13187        return cur;
13188    }
13189
13190    boolean isPendingBroadcastProcessLocked(int pid) {
13191        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13192                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13193    }
13194
13195    void skipPendingBroadcastLocked(int pid) {
13196            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13197            for (BroadcastQueue queue : mBroadcastQueues) {
13198                queue.skipPendingBroadcastLocked(pid);
13199            }
13200    }
13201
13202    // The app just attached; send any pending broadcasts that it should receive
13203    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13204        boolean didSomething = false;
13205        for (BroadcastQueue queue : mBroadcastQueues) {
13206            didSomething |= queue.sendPendingBroadcastsLocked(app);
13207        }
13208        return didSomething;
13209    }
13210
13211    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13212            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13213        enforceNotIsolatedCaller("registerReceiver");
13214        int callingUid;
13215        int callingPid;
13216        synchronized(this) {
13217            ProcessRecord callerApp = null;
13218            if (caller != null) {
13219                callerApp = getRecordForAppLocked(caller);
13220                if (callerApp == null) {
13221                    throw new SecurityException(
13222                            "Unable to find app for caller " + caller
13223                            + " (pid=" + Binder.getCallingPid()
13224                            + ") when registering receiver " + receiver);
13225                }
13226                if (callerApp.info.uid != Process.SYSTEM_UID &&
13227                        !callerApp.pkgList.containsKey(callerPackage) &&
13228                        !"android".equals(callerPackage)) {
13229                    throw new SecurityException("Given caller package " + callerPackage
13230                            + " is not running in process " + callerApp);
13231                }
13232                callingUid = callerApp.info.uid;
13233                callingPid = callerApp.pid;
13234            } else {
13235                callerPackage = null;
13236                callingUid = Binder.getCallingUid();
13237                callingPid = Binder.getCallingPid();
13238            }
13239
13240            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13241                    true, true, "registerReceiver", callerPackage);
13242
13243            List allSticky = null;
13244
13245            // Look for any matching sticky broadcasts...
13246            Iterator actions = filter.actionsIterator();
13247            if (actions != null) {
13248                while (actions.hasNext()) {
13249                    String action = (String)actions.next();
13250                    allSticky = getStickiesLocked(action, filter, allSticky,
13251                            UserHandle.USER_ALL);
13252                    allSticky = getStickiesLocked(action, filter, allSticky,
13253                            UserHandle.getUserId(callingUid));
13254                }
13255            } else {
13256                allSticky = getStickiesLocked(null, filter, allSticky,
13257                        UserHandle.USER_ALL);
13258                allSticky = getStickiesLocked(null, filter, allSticky,
13259                        UserHandle.getUserId(callingUid));
13260            }
13261
13262            // The first sticky in the list is returned directly back to
13263            // the client.
13264            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13265
13266            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13267                    + ": " + sticky);
13268
13269            if (receiver == null) {
13270                return sticky;
13271            }
13272
13273            ReceiverList rl
13274                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13275            if (rl == null) {
13276                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13277                        userId, receiver);
13278                if (rl.app != null) {
13279                    rl.app.receivers.add(rl);
13280                } else {
13281                    try {
13282                        receiver.asBinder().linkToDeath(rl, 0);
13283                    } catch (RemoteException e) {
13284                        return sticky;
13285                    }
13286                    rl.linkedToDeath = true;
13287                }
13288                mRegisteredReceivers.put(receiver.asBinder(), rl);
13289            } else if (rl.uid != callingUid) {
13290                throw new IllegalArgumentException(
13291                        "Receiver requested to register for uid " + callingUid
13292                        + " was previously registered for uid " + rl.uid);
13293            } else if (rl.pid != callingPid) {
13294                throw new IllegalArgumentException(
13295                        "Receiver requested to register for pid " + callingPid
13296                        + " was previously registered for pid " + rl.pid);
13297            } else if (rl.userId != userId) {
13298                throw new IllegalArgumentException(
13299                        "Receiver requested to register for user " + userId
13300                        + " was previously registered for user " + rl.userId);
13301            }
13302            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13303                    permission, callingUid, userId);
13304            rl.add(bf);
13305            if (!bf.debugCheck()) {
13306                Slog.w(TAG, "==> For Dynamic broadast");
13307            }
13308            mReceiverResolver.addFilter(bf);
13309
13310            // Enqueue broadcasts for all existing stickies that match
13311            // this filter.
13312            if (allSticky != null) {
13313                ArrayList receivers = new ArrayList();
13314                receivers.add(bf);
13315
13316                int N = allSticky.size();
13317                for (int i=0; i<N; i++) {
13318                    Intent intent = (Intent)allSticky.get(i);
13319                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13320                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13321                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13322                            null, null, false, true, true, -1);
13323                    queue.enqueueParallelBroadcastLocked(r);
13324                    queue.scheduleBroadcastsLocked();
13325                }
13326            }
13327
13328            return sticky;
13329        }
13330    }
13331
13332    public void unregisterReceiver(IIntentReceiver receiver) {
13333        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13334
13335        final long origId = Binder.clearCallingIdentity();
13336        try {
13337            boolean doTrim = false;
13338
13339            synchronized(this) {
13340                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13341                if (rl != null) {
13342                    if (rl.curBroadcast != null) {
13343                        BroadcastRecord r = rl.curBroadcast;
13344                        final boolean doNext = finishReceiverLocked(
13345                                receiver.asBinder(), r.resultCode, r.resultData,
13346                                r.resultExtras, r.resultAbort);
13347                        if (doNext) {
13348                            doTrim = true;
13349                            r.queue.processNextBroadcast(false);
13350                        }
13351                    }
13352
13353                    if (rl.app != null) {
13354                        rl.app.receivers.remove(rl);
13355                    }
13356                    removeReceiverLocked(rl);
13357                    if (rl.linkedToDeath) {
13358                        rl.linkedToDeath = false;
13359                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13360                    }
13361                }
13362            }
13363
13364            // If we actually concluded any broadcasts, we might now be able
13365            // to trim the recipients' apps from our working set
13366            if (doTrim) {
13367                trimApplications();
13368                return;
13369            }
13370
13371        } finally {
13372            Binder.restoreCallingIdentity(origId);
13373        }
13374    }
13375
13376    void removeReceiverLocked(ReceiverList rl) {
13377        mRegisteredReceivers.remove(rl.receiver.asBinder());
13378        int N = rl.size();
13379        for (int i=0; i<N; i++) {
13380            mReceiverResolver.removeFilter(rl.get(i));
13381        }
13382    }
13383
13384    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13385        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13386            ProcessRecord r = mLruProcesses.get(i);
13387            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13388                try {
13389                    r.thread.dispatchPackageBroadcast(cmd, packages);
13390                } catch (RemoteException ex) {
13391                }
13392            }
13393        }
13394    }
13395
13396    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13397            int[] users) {
13398        List<ResolveInfo> receivers = null;
13399        try {
13400            HashSet<ComponentName> singleUserReceivers = null;
13401            boolean scannedFirstReceivers = false;
13402            for (int user : users) {
13403                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13404                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13405                if (user != 0 && newReceivers != null) {
13406                    // If this is not the primary user, we need to check for
13407                    // any receivers that should be filtered out.
13408                    for (int i=0; i<newReceivers.size(); i++) {
13409                        ResolveInfo ri = newReceivers.get(i);
13410                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13411                            newReceivers.remove(i);
13412                            i--;
13413                        }
13414                    }
13415                }
13416                if (newReceivers != null && newReceivers.size() == 0) {
13417                    newReceivers = null;
13418                }
13419                if (receivers == null) {
13420                    receivers = newReceivers;
13421                } else if (newReceivers != null) {
13422                    // We need to concatenate the additional receivers
13423                    // found with what we have do far.  This would be easy,
13424                    // but we also need to de-dup any receivers that are
13425                    // singleUser.
13426                    if (!scannedFirstReceivers) {
13427                        // Collect any single user receivers we had already retrieved.
13428                        scannedFirstReceivers = true;
13429                        for (int i=0; i<receivers.size(); i++) {
13430                            ResolveInfo ri = receivers.get(i);
13431                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13432                                ComponentName cn = new ComponentName(
13433                                        ri.activityInfo.packageName, ri.activityInfo.name);
13434                                if (singleUserReceivers == null) {
13435                                    singleUserReceivers = new HashSet<ComponentName>();
13436                                }
13437                                singleUserReceivers.add(cn);
13438                            }
13439                        }
13440                    }
13441                    // Add the new results to the existing results, tracking
13442                    // and de-dupping single user receivers.
13443                    for (int i=0; i<newReceivers.size(); i++) {
13444                        ResolveInfo ri = newReceivers.get(i);
13445                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13446                            ComponentName cn = new ComponentName(
13447                                    ri.activityInfo.packageName, ri.activityInfo.name);
13448                            if (singleUserReceivers == null) {
13449                                singleUserReceivers = new HashSet<ComponentName>();
13450                            }
13451                            if (!singleUserReceivers.contains(cn)) {
13452                                singleUserReceivers.add(cn);
13453                                receivers.add(ri);
13454                            }
13455                        } else {
13456                            receivers.add(ri);
13457                        }
13458                    }
13459                }
13460            }
13461        } catch (RemoteException ex) {
13462            // pm is in same process, this will never happen.
13463        }
13464        return receivers;
13465    }
13466
13467    private final int broadcastIntentLocked(ProcessRecord callerApp,
13468            String callerPackage, Intent intent, String resolvedType,
13469            IIntentReceiver resultTo, int resultCode, String resultData,
13470            Bundle map, String requiredPermission, int appOp,
13471            boolean ordered, boolean sticky, int callingPid, int callingUid,
13472            int userId) {
13473        intent = new Intent(intent);
13474
13475        // By default broadcasts do not go to stopped apps.
13476        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13477
13478        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13479            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13480            + " ordered=" + ordered + " userid=" + userId);
13481        if ((resultTo != null) && !ordered) {
13482            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13483        }
13484
13485        userId = handleIncomingUser(callingPid, callingUid, userId,
13486                true, false, "broadcast", callerPackage);
13487
13488        // Make sure that the user who is receiving this broadcast is started.
13489        // If not, we will just skip it.
13490        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13491            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13492                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13493                Slog.w(TAG, "Skipping broadcast of " + intent
13494                        + ": user " + userId + " is stopped");
13495                return ActivityManager.BROADCAST_SUCCESS;
13496            }
13497        }
13498
13499        /*
13500         * Prevent non-system code (defined here to be non-persistent
13501         * processes) from sending protected broadcasts.
13502         */
13503        int callingAppId = UserHandle.getAppId(callingUid);
13504        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13505            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13506            callingUid == 0) {
13507            // Always okay.
13508        } else if (callerApp == null || !callerApp.persistent) {
13509            try {
13510                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13511                        intent.getAction())) {
13512                    String msg = "Permission Denial: not allowed to send broadcast "
13513                            + intent.getAction() + " from pid="
13514                            + callingPid + ", uid=" + callingUid;
13515                    Slog.w(TAG, msg);
13516                    throw new SecurityException(msg);
13517                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13518                    // Special case for compatibility: we don't want apps to send this,
13519                    // but historically it has not been protected and apps may be using it
13520                    // to poke their own app widget.  So, instead of making it protected,
13521                    // just limit it to the caller.
13522                    if (callerApp == null) {
13523                        String msg = "Permission Denial: not allowed to send broadcast "
13524                                + intent.getAction() + " from unknown caller.";
13525                        Slog.w(TAG, msg);
13526                        throw new SecurityException(msg);
13527                    } else if (intent.getComponent() != null) {
13528                        // They are good enough to send to an explicit component...  verify
13529                        // it is being sent to the calling app.
13530                        if (!intent.getComponent().getPackageName().equals(
13531                                callerApp.info.packageName)) {
13532                            String msg = "Permission Denial: not allowed to send broadcast "
13533                                    + intent.getAction() + " to "
13534                                    + intent.getComponent().getPackageName() + " from "
13535                                    + callerApp.info.packageName;
13536                            Slog.w(TAG, msg);
13537                            throw new SecurityException(msg);
13538                        }
13539                    } else {
13540                        // Limit broadcast to their own package.
13541                        intent.setPackage(callerApp.info.packageName);
13542                    }
13543                }
13544            } catch (RemoteException e) {
13545                Slog.w(TAG, "Remote exception", e);
13546                return ActivityManager.BROADCAST_SUCCESS;
13547            }
13548        }
13549
13550        // Handle special intents: if this broadcast is from the package
13551        // manager about a package being removed, we need to remove all of
13552        // its activities from the history stack.
13553        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13554                intent.getAction());
13555        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13556                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13557                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13558                || uidRemoved) {
13559            if (checkComponentPermission(
13560                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13561                    callingPid, callingUid, -1, true)
13562                    == PackageManager.PERMISSION_GRANTED) {
13563                if (uidRemoved) {
13564                    final Bundle intentExtras = intent.getExtras();
13565                    final int uid = intentExtras != null
13566                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13567                    if (uid >= 0) {
13568                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13569                        synchronized (bs) {
13570                            bs.removeUidStatsLocked(uid);
13571                        }
13572                        mAppOpsService.uidRemoved(uid);
13573                    }
13574                } else {
13575                    // If resources are unavailable just force stop all
13576                    // those packages and flush the attribute cache as well.
13577                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13578                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13579                        if (list != null && (list.length > 0)) {
13580                            for (String pkg : list) {
13581                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13582                                        "storage unmount");
13583                            }
13584                            sendPackageBroadcastLocked(
13585                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13586                        }
13587                    } else {
13588                        Uri data = intent.getData();
13589                        String ssp;
13590                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13591                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13592                                    intent.getAction());
13593                            boolean fullUninstall = removed &&
13594                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13595                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13596                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13597                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13598                                        false, fullUninstall, userId,
13599                                        removed ? "pkg removed" : "pkg changed");
13600                            }
13601                            if (removed) {
13602                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13603                                        new String[] {ssp}, userId);
13604                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13605                                    mAppOpsService.packageRemoved(
13606                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13607
13608                                    // Remove all permissions granted from/to this package
13609                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13610                                }
13611                            }
13612                        }
13613                    }
13614                }
13615            } else {
13616                String msg = "Permission Denial: " + intent.getAction()
13617                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13618                        + ", uid=" + callingUid + ")"
13619                        + " requires "
13620                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13621                Slog.w(TAG, msg);
13622                throw new SecurityException(msg);
13623            }
13624
13625        // Special case for adding a package: by default turn on compatibility
13626        // mode.
13627        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13628            Uri data = intent.getData();
13629            String ssp;
13630            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13631                mCompatModePackages.handlePackageAddedLocked(ssp,
13632                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13633            }
13634        }
13635
13636        /*
13637         * If this is the time zone changed action, queue up a message that will reset the timezone
13638         * of all currently running processes. This message will get queued up before the broadcast
13639         * happens.
13640         */
13641        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13642            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13643        }
13644
13645        /*
13646         * If the user set the time, let all running processes know.
13647         */
13648        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13649            final int is24Hour = intent.getBooleanExtra(
13650                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13651            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13652        }
13653
13654        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13655            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13656        }
13657
13658        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13659            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13660            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13661        }
13662
13663        // Add to the sticky list if requested.
13664        if (sticky) {
13665            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13666                    callingPid, callingUid)
13667                    != PackageManager.PERMISSION_GRANTED) {
13668                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13669                        + callingPid + ", uid=" + callingUid
13670                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13671                Slog.w(TAG, msg);
13672                throw new SecurityException(msg);
13673            }
13674            if (requiredPermission != null) {
13675                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13676                        + " and enforce permission " + requiredPermission);
13677                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13678            }
13679            if (intent.getComponent() != null) {
13680                throw new SecurityException(
13681                        "Sticky broadcasts can't target a specific component");
13682            }
13683            // We use userId directly here, since the "all" target is maintained
13684            // as a separate set of sticky broadcasts.
13685            if (userId != UserHandle.USER_ALL) {
13686                // But first, if this is not a broadcast to all users, then
13687                // make sure it doesn't conflict with an existing broadcast to
13688                // all users.
13689                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13690                        UserHandle.USER_ALL);
13691                if (stickies != null) {
13692                    ArrayList<Intent> list = stickies.get(intent.getAction());
13693                    if (list != null) {
13694                        int N = list.size();
13695                        int i;
13696                        for (i=0; i<N; i++) {
13697                            if (intent.filterEquals(list.get(i))) {
13698                                throw new IllegalArgumentException(
13699                                        "Sticky broadcast " + intent + " for user "
13700                                        + userId + " conflicts with existing global broadcast");
13701                            }
13702                        }
13703                    }
13704                }
13705            }
13706            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13707            if (stickies == null) {
13708                stickies = new ArrayMap<String, ArrayList<Intent>>();
13709                mStickyBroadcasts.put(userId, stickies);
13710            }
13711            ArrayList<Intent> list = stickies.get(intent.getAction());
13712            if (list == null) {
13713                list = new ArrayList<Intent>();
13714                stickies.put(intent.getAction(), list);
13715            }
13716            int N = list.size();
13717            int i;
13718            for (i=0; i<N; i++) {
13719                if (intent.filterEquals(list.get(i))) {
13720                    // This sticky already exists, replace it.
13721                    list.set(i, new Intent(intent));
13722                    break;
13723                }
13724            }
13725            if (i >= N) {
13726                list.add(new Intent(intent));
13727            }
13728        }
13729
13730        int[] users;
13731        if (userId == UserHandle.USER_ALL) {
13732            // Caller wants broadcast to go to all started users.
13733            users = mStartedUserArray;
13734        } else {
13735            // Caller wants broadcast to go to one specific user.
13736            users = new int[] {userId};
13737        }
13738
13739        // Figure out who all will receive this broadcast.
13740        List receivers = null;
13741        List<BroadcastFilter> registeredReceivers = null;
13742        // Need to resolve the intent to interested receivers...
13743        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13744                 == 0) {
13745            receivers = collectReceiverComponents(intent, resolvedType, users);
13746        }
13747        if (intent.getComponent() == null) {
13748            registeredReceivers = mReceiverResolver.queryIntent(intent,
13749                    resolvedType, false, userId);
13750        }
13751
13752        final boolean replacePending =
13753                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13754
13755        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13756                + " replacePending=" + replacePending);
13757
13758        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13759        if (!ordered && NR > 0) {
13760            // If we are not serializing this broadcast, then send the
13761            // registered receivers separately so they don't wait for the
13762            // components to be launched.
13763            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13764            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13765                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13766                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13767                    ordered, sticky, false, userId);
13768            if (DEBUG_BROADCAST) Slog.v(
13769                    TAG, "Enqueueing parallel broadcast " + r);
13770            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13771            if (!replaced) {
13772                queue.enqueueParallelBroadcastLocked(r);
13773                queue.scheduleBroadcastsLocked();
13774            }
13775            registeredReceivers = null;
13776            NR = 0;
13777        }
13778
13779        // Merge into one list.
13780        int ir = 0;
13781        if (receivers != null) {
13782            // A special case for PACKAGE_ADDED: do not allow the package
13783            // being added to see this broadcast.  This prevents them from
13784            // using this as a back door to get run as soon as they are
13785            // installed.  Maybe in the future we want to have a special install
13786            // broadcast or such for apps, but we'd like to deliberately make
13787            // this decision.
13788            String skipPackages[] = null;
13789            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13790                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13791                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13792                Uri data = intent.getData();
13793                if (data != null) {
13794                    String pkgName = data.getSchemeSpecificPart();
13795                    if (pkgName != null) {
13796                        skipPackages = new String[] { pkgName };
13797                    }
13798                }
13799            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13800                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13801            }
13802            if (skipPackages != null && (skipPackages.length > 0)) {
13803                for (String skipPackage : skipPackages) {
13804                    if (skipPackage != null) {
13805                        int NT = receivers.size();
13806                        for (int it=0; it<NT; it++) {
13807                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13808                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13809                                receivers.remove(it);
13810                                it--;
13811                                NT--;
13812                            }
13813                        }
13814                    }
13815                }
13816            }
13817
13818            int NT = receivers != null ? receivers.size() : 0;
13819            int it = 0;
13820            ResolveInfo curt = null;
13821            BroadcastFilter curr = null;
13822            while (it < NT && ir < NR) {
13823                if (curt == null) {
13824                    curt = (ResolveInfo)receivers.get(it);
13825                }
13826                if (curr == null) {
13827                    curr = registeredReceivers.get(ir);
13828                }
13829                if (curr.getPriority() >= curt.priority) {
13830                    // Insert this broadcast record into the final list.
13831                    receivers.add(it, curr);
13832                    ir++;
13833                    curr = null;
13834                    it++;
13835                    NT++;
13836                } else {
13837                    // Skip to the next ResolveInfo in the final list.
13838                    it++;
13839                    curt = null;
13840                }
13841            }
13842        }
13843        while (ir < NR) {
13844            if (receivers == null) {
13845                receivers = new ArrayList();
13846            }
13847            receivers.add(registeredReceivers.get(ir));
13848            ir++;
13849        }
13850
13851        if ((receivers != null && receivers.size() > 0)
13852                || resultTo != null) {
13853            BroadcastQueue queue = broadcastQueueForIntent(intent);
13854            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13855                    callerPackage, callingPid, callingUid, resolvedType,
13856                    requiredPermission, appOp, receivers, resultTo, resultCode,
13857                    resultData, map, ordered, sticky, false, userId);
13858            if (DEBUG_BROADCAST) Slog.v(
13859                    TAG, "Enqueueing ordered broadcast " + r
13860                    + ": prev had " + queue.mOrderedBroadcasts.size());
13861            if (DEBUG_BROADCAST) {
13862                int seq = r.intent.getIntExtra("seq", -1);
13863                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13864            }
13865            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13866            if (!replaced) {
13867                queue.enqueueOrderedBroadcastLocked(r);
13868                queue.scheduleBroadcastsLocked();
13869            }
13870        }
13871
13872        return ActivityManager.BROADCAST_SUCCESS;
13873    }
13874
13875    final Intent verifyBroadcastLocked(Intent intent) {
13876        // Refuse possible leaked file descriptors
13877        if (intent != null && intent.hasFileDescriptors() == true) {
13878            throw new IllegalArgumentException("File descriptors passed in Intent");
13879        }
13880
13881        int flags = intent.getFlags();
13882
13883        if (!mProcessesReady) {
13884            // if the caller really truly claims to know what they're doing, go
13885            // ahead and allow the broadcast without launching any receivers
13886            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13887                intent = new Intent(intent);
13888                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13889            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13890                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13891                        + " before boot completion");
13892                throw new IllegalStateException("Cannot broadcast before boot completed");
13893            }
13894        }
13895
13896        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13897            throw new IllegalArgumentException(
13898                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13899        }
13900
13901        return intent;
13902    }
13903
13904    public final int broadcastIntent(IApplicationThread caller,
13905            Intent intent, String resolvedType, IIntentReceiver resultTo,
13906            int resultCode, String resultData, Bundle map,
13907            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13908        enforceNotIsolatedCaller("broadcastIntent");
13909        synchronized(this) {
13910            intent = verifyBroadcastLocked(intent);
13911
13912            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13913            final int callingPid = Binder.getCallingPid();
13914            final int callingUid = Binder.getCallingUid();
13915            final long origId = Binder.clearCallingIdentity();
13916            int res = broadcastIntentLocked(callerApp,
13917                    callerApp != null ? callerApp.info.packageName : null,
13918                    intent, resolvedType, resultTo,
13919                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13920                    callingPid, callingUid, userId);
13921            Binder.restoreCallingIdentity(origId);
13922            return res;
13923        }
13924    }
13925
13926    int broadcastIntentInPackage(String packageName, int uid,
13927            Intent intent, String resolvedType, IIntentReceiver resultTo,
13928            int resultCode, String resultData, Bundle map,
13929            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13930        synchronized(this) {
13931            intent = verifyBroadcastLocked(intent);
13932
13933            final long origId = Binder.clearCallingIdentity();
13934            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13935                    resultTo, resultCode, resultData, map, requiredPermission,
13936                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13937            Binder.restoreCallingIdentity(origId);
13938            return res;
13939        }
13940    }
13941
13942    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13943        // Refuse possible leaked file descriptors
13944        if (intent != null && intent.hasFileDescriptors() == true) {
13945            throw new IllegalArgumentException("File descriptors passed in Intent");
13946        }
13947
13948        userId = handleIncomingUser(Binder.getCallingPid(),
13949                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13950
13951        synchronized(this) {
13952            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13953                    != PackageManager.PERMISSION_GRANTED) {
13954                String msg = "Permission Denial: unbroadcastIntent() from pid="
13955                        + Binder.getCallingPid()
13956                        + ", uid=" + Binder.getCallingUid()
13957                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13958                Slog.w(TAG, msg);
13959                throw new SecurityException(msg);
13960            }
13961            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13962            if (stickies != null) {
13963                ArrayList<Intent> list = stickies.get(intent.getAction());
13964                if (list != null) {
13965                    int N = list.size();
13966                    int i;
13967                    for (i=0; i<N; i++) {
13968                        if (intent.filterEquals(list.get(i))) {
13969                            list.remove(i);
13970                            break;
13971                        }
13972                    }
13973                    if (list.size() <= 0) {
13974                        stickies.remove(intent.getAction());
13975                    }
13976                }
13977                if (stickies.size() <= 0) {
13978                    mStickyBroadcasts.remove(userId);
13979                }
13980            }
13981        }
13982    }
13983
13984    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13985            String resultData, Bundle resultExtras, boolean resultAbort) {
13986        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13987        if (r == null) {
13988            Slog.w(TAG, "finishReceiver called but not found on queue");
13989            return false;
13990        }
13991
13992        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13993    }
13994
13995    void backgroundServicesFinishedLocked(int userId) {
13996        for (BroadcastQueue queue : mBroadcastQueues) {
13997            queue.backgroundServicesFinishedLocked(userId);
13998        }
13999    }
14000
14001    public void finishReceiver(IBinder who, int resultCode, String resultData,
14002            Bundle resultExtras, boolean resultAbort) {
14003        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14004
14005        // Refuse possible leaked file descriptors
14006        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14007            throw new IllegalArgumentException("File descriptors passed in Bundle");
14008        }
14009
14010        final long origId = Binder.clearCallingIdentity();
14011        try {
14012            boolean doNext = false;
14013            BroadcastRecord r;
14014
14015            synchronized(this) {
14016                r = broadcastRecordForReceiverLocked(who);
14017                if (r != null) {
14018                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14019                        resultData, resultExtras, resultAbort, true);
14020                }
14021            }
14022
14023            if (doNext) {
14024                r.queue.processNextBroadcast(false);
14025            }
14026            trimApplications();
14027        } finally {
14028            Binder.restoreCallingIdentity(origId);
14029        }
14030    }
14031
14032    // =========================================================
14033    // INSTRUMENTATION
14034    // =========================================================
14035
14036    public boolean startInstrumentation(ComponentName className,
14037            String profileFile, int flags, Bundle arguments,
14038            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14039            int userId) {
14040        enforceNotIsolatedCaller("startInstrumentation");
14041        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14042                userId, false, true, "startInstrumentation", null);
14043        // Refuse possible leaked file descriptors
14044        if (arguments != null && arguments.hasFileDescriptors()) {
14045            throw new IllegalArgumentException("File descriptors passed in Bundle");
14046        }
14047
14048        synchronized(this) {
14049            InstrumentationInfo ii = null;
14050            ApplicationInfo ai = null;
14051            try {
14052                ii = mContext.getPackageManager().getInstrumentationInfo(
14053                    className, STOCK_PM_FLAGS);
14054                ai = AppGlobals.getPackageManager().getApplicationInfo(
14055                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14056            } catch (PackageManager.NameNotFoundException e) {
14057            } catch (RemoteException e) {
14058            }
14059            if (ii == null) {
14060                reportStartInstrumentationFailure(watcher, className,
14061                        "Unable to find instrumentation info for: " + className);
14062                return false;
14063            }
14064            if (ai == null) {
14065                reportStartInstrumentationFailure(watcher, className,
14066                        "Unable to find instrumentation target package: " + ii.targetPackage);
14067                return false;
14068            }
14069
14070            int match = mContext.getPackageManager().checkSignatures(
14071                    ii.targetPackage, ii.packageName);
14072            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14073                String msg = "Permission Denial: starting instrumentation "
14074                        + className + " from pid="
14075                        + Binder.getCallingPid()
14076                        + ", uid=" + Binder.getCallingPid()
14077                        + " not allowed because package " + ii.packageName
14078                        + " does not have a signature matching the target "
14079                        + ii.targetPackage;
14080                reportStartInstrumentationFailure(watcher, className, msg);
14081                throw new SecurityException(msg);
14082            }
14083
14084            final long origId = Binder.clearCallingIdentity();
14085            // Instrumentation can kill and relaunch even persistent processes
14086            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14087                    "start instr");
14088            ProcessRecord app = addAppLocked(ai, false);
14089            app.instrumentationClass = className;
14090            app.instrumentationInfo = ai;
14091            app.instrumentationProfileFile = profileFile;
14092            app.instrumentationArguments = arguments;
14093            app.instrumentationWatcher = watcher;
14094            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14095            app.instrumentationResultClass = className;
14096            Binder.restoreCallingIdentity(origId);
14097        }
14098
14099        return true;
14100    }
14101
14102    /**
14103     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14104     * error to the logs, but if somebody is watching, send the report there too.  This enables
14105     * the "am" command to report errors with more information.
14106     *
14107     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14108     * @param cn The component name of the instrumentation.
14109     * @param report The error report.
14110     */
14111    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14112            ComponentName cn, String report) {
14113        Slog.w(TAG, report);
14114        try {
14115            if (watcher != null) {
14116                Bundle results = new Bundle();
14117                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14118                results.putString("Error", report);
14119                watcher.instrumentationStatus(cn, -1, results);
14120            }
14121        } catch (RemoteException e) {
14122            Slog.w(TAG, e);
14123        }
14124    }
14125
14126    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14127        if (app.instrumentationWatcher != null) {
14128            try {
14129                // NOTE:  IInstrumentationWatcher *must* be oneway here
14130                app.instrumentationWatcher.instrumentationFinished(
14131                    app.instrumentationClass,
14132                    resultCode,
14133                    results);
14134            } catch (RemoteException e) {
14135            }
14136        }
14137        if (app.instrumentationUiAutomationConnection != null) {
14138            try {
14139                app.instrumentationUiAutomationConnection.shutdown();
14140            } catch (RemoteException re) {
14141                /* ignore */
14142            }
14143            // Only a UiAutomation can set this flag and now that
14144            // it is finished we make sure it is reset to its default.
14145            mUserIsMonkey = false;
14146        }
14147        app.instrumentationWatcher = null;
14148        app.instrumentationUiAutomationConnection = null;
14149        app.instrumentationClass = null;
14150        app.instrumentationInfo = null;
14151        app.instrumentationProfileFile = null;
14152        app.instrumentationArguments = null;
14153
14154        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14155                "finished inst");
14156    }
14157
14158    public void finishInstrumentation(IApplicationThread target,
14159            int resultCode, Bundle results) {
14160        int userId = UserHandle.getCallingUserId();
14161        // Refuse possible leaked file descriptors
14162        if (results != null && results.hasFileDescriptors()) {
14163            throw new IllegalArgumentException("File descriptors passed in Intent");
14164        }
14165
14166        synchronized(this) {
14167            ProcessRecord app = getRecordForAppLocked(target);
14168            if (app == null) {
14169                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14170                return;
14171            }
14172            final long origId = Binder.clearCallingIdentity();
14173            finishInstrumentationLocked(app, resultCode, results);
14174            Binder.restoreCallingIdentity(origId);
14175        }
14176    }
14177
14178    // =========================================================
14179    // CONFIGURATION
14180    // =========================================================
14181
14182    public ConfigurationInfo getDeviceConfigurationInfo() {
14183        ConfigurationInfo config = new ConfigurationInfo();
14184        synchronized (this) {
14185            config.reqTouchScreen = mConfiguration.touchscreen;
14186            config.reqKeyboardType = mConfiguration.keyboard;
14187            config.reqNavigation = mConfiguration.navigation;
14188            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14189                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14190                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14191            }
14192            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14193                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14194                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14195            }
14196            config.reqGlEsVersion = GL_ES_VERSION;
14197        }
14198        return config;
14199    }
14200
14201    ActivityStack getFocusedStack() {
14202        return mStackSupervisor.getFocusedStack();
14203    }
14204
14205    public Configuration getConfiguration() {
14206        Configuration ci;
14207        synchronized(this) {
14208            ci = new Configuration(mConfiguration);
14209        }
14210        return ci;
14211    }
14212
14213    public void updatePersistentConfiguration(Configuration values) {
14214        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14215                "updateConfiguration()");
14216        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14217                "updateConfiguration()");
14218        if (values == null) {
14219            throw new NullPointerException("Configuration must not be null");
14220        }
14221
14222        synchronized(this) {
14223            final long origId = Binder.clearCallingIdentity();
14224            updateConfigurationLocked(values, null, true, false);
14225            Binder.restoreCallingIdentity(origId);
14226        }
14227    }
14228
14229    public void updateConfiguration(Configuration values) {
14230        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14231                "updateConfiguration()");
14232
14233        synchronized(this) {
14234            if (values == null && mWindowManager != null) {
14235                // sentinel: fetch the current configuration from the window manager
14236                values = mWindowManager.computeNewConfiguration();
14237            }
14238
14239            if (mWindowManager != null) {
14240                mProcessList.applyDisplaySize(mWindowManager);
14241            }
14242
14243            final long origId = Binder.clearCallingIdentity();
14244            if (values != null) {
14245                Settings.System.clearConfiguration(values);
14246            }
14247            updateConfigurationLocked(values, null, false, false);
14248            Binder.restoreCallingIdentity(origId);
14249        }
14250    }
14251
14252    /**
14253     * Do either or both things: (1) change the current configuration, and (2)
14254     * make sure the given activity is running with the (now) current
14255     * configuration.  Returns true if the activity has been left running, or
14256     * false if <var>starting</var> is being destroyed to match the new
14257     * configuration.
14258     * @param persistent TODO
14259     */
14260    boolean updateConfigurationLocked(Configuration values,
14261            ActivityRecord starting, boolean persistent, boolean initLocale) {
14262        int changes = 0;
14263
14264        if (values != null) {
14265            Configuration newConfig = new Configuration(mConfiguration);
14266            changes = newConfig.updateFrom(values);
14267            if (changes != 0) {
14268                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14269                    Slog.i(TAG, "Updating configuration to: " + values);
14270                }
14271
14272                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14273
14274                if (values.locale != null && !initLocale) {
14275                    saveLocaleLocked(values.locale,
14276                                     !values.locale.equals(mConfiguration.locale),
14277                                     values.userSetLocale);
14278                }
14279
14280                mConfigurationSeq++;
14281                if (mConfigurationSeq <= 0) {
14282                    mConfigurationSeq = 1;
14283                }
14284                newConfig.seq = mConfigurationSeq;
14285                mConfiguration = newConfig;
14286                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14287
14288                final Configuration configCopy = new Configuration(mConfiguration);
14289
14290                // TODO: If our config changes, should we auto dismiss any currently
14291                // showing dialogs?
14292                mShowDialogs = shouldShowDialogs(newConfig);
14293
14294                AttributeCache ac = AttributeCache.instance();
14295                if (ac != null) {
14296                    ac.updateConfiguration(configCopy);
14297                }
14298
14299                // Make sure all resources in our process are updated
14300                // right now, so that anyone who is going to retrieve
14301                // resource values after we return will be sure to get
14302                // the new ones.  This is especially important during
14303                // boot, where the first config change needs to guarantee
14304                // all resources have that config before following boot
14305                // code is executed.
14306                mSystemThread.applyConfigurationToResources(configCopy);
14307
14308                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14309                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14310                    msg.obj = new Configuration(configCopy);
14311                    mHandler.sendMessage(msg);
14312                }
14313
14314                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14315                    ProcessRecord app = mLruProcesses.get(i);
14316                    try {
14317                        if (app.thread != null) {
14318                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14319                                    + app.processName + " new config " + mConfiguration);
14320                            app.thread.scheduleConfigurationChanged(configCopy);
14321                        }
14322                    } catch (Exception e) {
14323                    }
14324                }
14325                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14326                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14327                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14328                        | Intent.FLAG_RECEIVER_FOREGROUND);
14329                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14330                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14331                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14332                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14333                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14334                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14335                    broadcastIntentLocked(null, null, intent,
14336                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14337                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14338                }
14339            }
14340        }
14341
14342        boolean kept = true;
14343        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14344        // mainStack is null during startup.
14345        if (mainStack != null) {
14346            if (changes != 0 && starting == null) {
14347                // If the configuration changed, and the caller is not already
14348                // in the process of starting an activity, then find the top
14349                // activity to check if its configuration needs to change.
14350                starting = mainStack.topRunningActivityLocked(null);
14351            }
14352
14353            if (starting != null) {
14354                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14355                // And we need to make sure at this point that all other activities
14356                // are made visible with the correct configuration.
14357                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14358            }
14359        }
14360
14361        if (values != null && mWindowManager != null) {
14362            mWindowManager.setNewConfiguration(mConfiguration);
14363        }
14364
14365        return kept;
14366    }
14367
14368    /**
14369     * Decide based on the configuration whether we should shouw the ANR,
14370     * crash, etc dialogs.  The idea is that if there is no affordnace to
14371     * press the on-screen buttons, we shouldn't show the dialog.
14372     *
14373     * A thought: SystemUI might also want to get told about this, the Power
14374     * dialog / global actions also might want different behaviors.
14375     */
14376    private static final boolean shouldShowDialogs(Configuration config) {
14377        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14378                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14379    }
14380
14381    /**
14382     * Save the locale.  You must be inside a synchronized (this) block.
14383     */
14384    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14385        if(isDiff) {
14386            SystemProperties.set("user.language", l.getLanguage());
14387            SystemProperties.set("user.region", l.getCountry());
14388        }
14389
14390        if(isPersist) {
14391            SystemProperties.set("persist.sys.language", l.getLanguage());
14392            SystemProperties.set("persist.sys.country", l.getCountry());
14393            SystemProperties.set("persist.sys.localevar", l.getVariant());
14394        }
14395    }
14396
14397    @Override
14398    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14399        ActivityRecord srec = ActivityRecord.forToken(token);
14400        return srec != null && srec.task.affinity != null &&
14401                srec.task.affinity.equals(destAffinity);
14402    }
14403
14404    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14405            Intent resultData) {
14406
14407        synchronized (this) {
14408            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14409            if (stack != null) {
14410                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14411            }
14412            return false;
14413        }
14414    }
14415
14416    public int getLaunchedFromUid(IBinder activityToken) {
14417        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14418        if (srec == null) {
14419            return -1;
14420        }
14421        return srec.launchedFromUid;
14422    }
14423
14424    public String getLaunchedFromPackage(IBinder activityToken) {
14425        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14426        if (srec == null) {
14427            return null;
14428        }
14429        return srec.launchedFromPackage;
14430    }
14431
14432    // =========================================================
14433    // LIFETIME MANAGEMENT
14434    // =========================================================
14435
14436    // Returns which broadcast queue the app is the current [or imminent] receiver
14437    // on, or 'null' if the app is not an active broadcast recipient.
14438    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14439        BroadcastRecord r = app.curReceiver;
14440        if (r != null) {
14441            return r.queue;
14442        }
14443
14444        // It's not the current receiver, but it might be starting up to become one
14445        synchronized (this) {
14446            for (BroadcastQueue queue : mBroadcastQueues) {
14447                r = queue.mPendingBroadcast;
14448                if (r != null && r.curApp == app) {
14449                    // found it; report which queue it's in
14450                    return queue;
14451                }
14452            }
14453        }
14454
14455        return null;
14456    }
14457
14458    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14459            boolean doingAll, long now) {
14460        if (mAdjSeq == app.adjSeq) {
14461            // This adjustment has already been computed.
14462            return app.curRawAdj;
14463        }
14464
14465        if (app.thread == null) {
14466            app.adjSeq = mAdjSeq;
14467            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14468            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14469            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14470        }
14471
14472        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14473        app.adjSource = null;
14474        app.adjTarget = null;
14475        app.empty = false;
14476        app.cached = false;
14477
14478        final int activitiesSize = app.activities.size();
14479
14480        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14481            // The max adjustment doesn't allow this app to be anything
14482            // below foreground, so it is not worth doing work for it.
14483            app.adjType = "fixed";
14484            app.adjSeq = mAdjSeq;
14485            app.curRawAdj = app.maxAdj;
14486            app.foregroundActivities = false;
14487            app.keeping = true;
14488            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14489            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14490            // System process can do UI, and when they do we want to have
14491            // them trim their memory after the user leaves the UI.  To
14492            // facilitate this, here we need to determine whether or not it
14493            // is currently showing UI.
14494            app.systemNoUi = true;
14495            if (app == TOP_APP) {
14496                app.systemNoUi = false;
14497            } else if (activitiesSize > 0) {
14498                for (int j = 0; j < activitiesSize; j++) {
14499                    final ActivityRecord r = app.activities.get(j);
14500                    if (r.visible) {
14501                        app.systemNoUi = false;
14502                    }
14503                }
14504            }
14505            if (!app.systemNoUi) {
14506                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14507            }
14508            return (app.curAdj=app.maxAdj);
14509        }
14510
14511        app.keeping = false;
14512        app.systemNoUi = false;
14513
14514        // Determine the importance of the process, starting with most
14515        // important to least, and assign an appropriate OOM adjustment.
14516        int adj;
14517        int schedGroup;
14518        int procState;
14519        boolean foregroundActivities = false;
14520        boolean interesting = false;
14521        BroadcastQueue queue;
14522        if (app == TOP_APP) {
14523            // The last app on the list is the foreground app.
14524            adj = ProcessList.FOREGROUND_APP_ADJ;
14525            schedGroup = Process.THREAD_GROUP_DEFAULT;
14526            app.adjType = "top-activity";
14527            foregroundActivities = true;
14528            interesting = true;
14529            procState = ActivityManager.PROCESS_STATE_TOP;
14530        } else if (app.instrumentationClass != null) {
14531            // Don't want to kill running instrumentation.
14532            adj = ProcessList.FOREGROUND_APP_ADJ;
14533            schedGroup = Process.THREAD_GROUP_DEFAULT;
14534            app.adjType = "instrumentation";
14535            interesting = true;
14536            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14537        } else if ((queue = isReceivingBroadcast(app)) != null) {
14538            // An app that is currently receiving a broadcast also
14539            // counts as being in the foreground for OOM killer purposes.
14540            // It's placed in a sched group based on the nature of the
14541            // broadcast as reflected by which queue it's active in.
14542            adj = ProcessList.FOREGROUND_APP_ADJ;
14543            schedGroup = (queue == mFgBroadcastQueue)
14544                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14545            app.adjType = "broadcast";
14546            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14547        } else if (app.executingServices.size() > 0) {
14548            // An app that is currently executing a service callback also
14549            // counts as being in the foreground.
14550            adj = ProcessList.FOREGROUND_APP_ADJ;
14551            schedGroup = app.execServicesFg ?
14552                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14553            app.adjType = "exec-service";
14554            procState = ActivityManager.PROCESS_STATE_SERVICE;
14555            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14556        } else {
14557            // As far as we know the process is empty.  We may change our mind later.
14558            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14559            // At this point we don't actually know the adjustment.  Use the cached adj
14560            // value that the caller wants us to.
14561            adj = cachedAdj;
14562            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14563            app.cached = true;
14564            app.empty = true;
14565            app.adjType = "cch-empty";
14566        }
14567
14568        // Examine all activities if not already foreground.
14569        if (!foregroundActivities && activitiesSize > 0) {
14570            for (int j = 0; j < activitiesSize; j++) {
14571                final ActivityRecord r = app.activities.get(j);
14572                if (r.app != app) {
14573                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14574                            + app + "?!?");
14575                    continue;
14576                }
14577                if (r.visible) {
14578                    // App has a visible activity; only upgrade adjustment.
14579                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14580                        adj = ProcessList.VISIBLE_APP_ADJ;
14581                        app.adjType = "visible";
14582                    }
14583                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14584                        procState = ActivityManager.PROCESS_STATE_TOP;
14585                    }
14586                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14587                    app.cached = false;
14588                    app.empty = false;
14589                    foregroundActivities = true;
14590                    break;
14591                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14592                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14593                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14594                        app.adjType = "pausing";
14595                    }
14596                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14597                        procState = ActivityManager.PROCESS_STATE_TOP;
14598                    }
14599                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14600                    app.cached = false;
14601                    app.empty = false;
14602                    foregroundActivities = true;
14603                } else if (r.state == ActivityState.STOPPING) {
14604                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14605                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14606                        app.adjType = "stopping";
14607                    }
14608                    // For the process state, we will at this point consider the
14609                    // process to be cached.  It will be cached either as an activity
14610                    // or empty depending on whether the activity is finishing.  We do
14611                    // this so that we can treat the process as cached for purposes of
14612                    // memory trimming (determing current memory level, trim command to
14613                    // send to process) since there can be an arbitrary number of stopping
14614                    // processes and they should soon all go into the cached state.
14615                    if (!r.finishing) {
14616                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14617                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14618                        }
14619                    }
14620                    app.cached = false;
14621                    app.empty = false;
14622                    foregroundActivities = true;
14623                } else {
14624                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14625                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14626                        app.adjType = "cch-act";
14627                    }
14628                }
14629            }
14630        }
14631
14632        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14633            if (app.foregroundServices) {
14634                // The user is aware of this app, so make it visible.
14635                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14636                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14637                app.cached = false;
14638                app.adjType = "fg-service";
14639                schedGroup = Process.THREAD_GROUP_DEFAULT;
14640            } else if (app.forcingToForeground != null) {
14641                // The user is aware of this app, so make it visible.
14642                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14643                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14644                app.cached = false;
14645                app.adjType = "force-fg";
14646                app.adjSource = app.forcingToForeground;
14647                schedGroup = Process.THREAD_GROUP_DEFAULT;
14648            }
14649        }
14650
14651        if (app.foregroundServices) {
14652            interesting = true;
14653        }
14654
14655        if (app == mHeavyWeightProcess) {
14656            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14657                // We don't want to kill the current heavy-weight process.
14658                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14659                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14660                app.cached = false;
14661                app.adjType = "heavy";
14662            }
14663            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14664                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14665            }
14666        }
14667
14668        if (app == mHomeProcess) {
14669            if (adj > ProcessList.HOME_APP_ADJ) {
14670                // This process is hosting what we currently consider to be the
14671                // home app, so we don't want to let it go into the background.
14672                adj = ProcessList.HOME_APP_ADJ;
14673                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14674                app.cached = false;
14675                app.adjType = "home";
14676            }
14677            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14678                procState = ActivityManager.PROCESS_STATE_HOME;
14679            }
14680        }
14681
14682        if (app == mPreviousProcess && app.activities.size() > 0) {
14683            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14684                // This was the previous process that showed UI to the user.
14685                // We want to try to keep it around more aggressively, to give
14686                // a good experience around switching between two apps.
14687                adj = ProcessList.PREVIOUS_APP_ADJ;
14688                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14689                app.cached = false;
14690                app.adjType = "previous";
14691            }
14692            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14693                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14694            }
14695        }
14696
14697        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14698                + " reason=" + app.adjType);
14699
14700        // By default, we use the computed adjustment.  It may be changed if
14701        // there are applications dependent on our services or providers, but
14702        // this gives us a baseline and makes sure we don't get into an
14703        // infinite recursion.
14704        app.adjSeq = mAdjSeq;
14705        app.curRawAdj = adj;
14706        app.hasStartedServices = false;
14707
14708        if (mBackupTarget != null && app == mBackupTarget.app) {
14709            // If possible we want to avoid killing apps while they're being backed up
14710            if (adj > ProcessList.BACKUP_APP_ADJ) {
14711                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14712                adj = ProcessList.BACKUP_APP_ADJ;
14713                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14714                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14715                }
14716                app.adjType = "backup";
14717                app.cached = false;
14718            }
14719            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14720                procState = ActivityManager.PROCESS_STATE_BACKUP;
14721            }
14722        }
14723
14724        boolean mayBeTop = false;
14725
14726        for (int is = app.services.size()-1;
14727                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14728                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14729                        || procState > ActivityManager.PROCESS_STATE_TOP);
14730                is--) {
14731            ServiceRecord s = app.services.valueAt(is);
14732            if (s.startRequested) {
14733                app.hasStartedServices = true;
14734                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14735                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14736                }
14737                if (app.hasShownUi && app != mHomeProcess) {
14738                    // If this process has shown some UI, let it immediately
14739                    // go to the LRU list because it may be pretty heavy with
14740                    // UI stuff.  We'll tag it with a label just to help
14741                    // debug and understand what is going on.
14742                    if (adj > ProcessList.SERVICE_ADJ) {
14743                        app.adjType = "cch-started-ui-services";
14744                    }
14745                } else {
14746                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14747                        // This service has seen some activity within
14748                        // recent memory, so we will keep its process ahead
14749                        // of the background processes.
14750                        if (adj > ProcessList.SERVICE_ADJ) {
14751                            adj = ProcessList.SERVICE_ADJ;
14752                            app.adjType = "started-services";
14753                            app.cached = false;
14754                        }
14755                    }
14756                    // If we have let the service slide into the background
14757                    // state, still have some text describing what it is doing
14758                    // even though the service no longer has an impact.
14759                    if (adj > ProcessList.SERVICE_ADJ) {
14760                        app.adjType = "cch-started-services";
14761                    }
14762                }
14763                // Don't kill this process because it is doing work; it
14764                // has said it is doing work.
14765                app.keeping = true;
14766            }
14767            for (int conni = s.connections.size()-1;
14768                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14769                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14770                            || procState > ActivityManager.PROCESS_STATE_TOP);
14771                    conni--) {
14772                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14773                for (int i = 0;
14774                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14775                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14776                                || procState > ActivityManager.PROCESS_STATE_TOP);
14777                        i++) {
14778                    // XXX should compute this based on the max of
14779                    // all connected clients.
14780                    ConnectionRecord cr = clist.get(i);
14781                    if (cr.binding.client == app) {
14782                        // Binding to ourself is not interesting.
14783                        continue;
14784                    }
14785                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14786                        ProcessRecord client = cr.binding.client;
14787                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14788                                TOP_APP, doingAll, now);
14789                        int clientProcState = client.curProcState;
14790                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14791                            // If the other app is cached for any reason, for purposes here
14792                            // we are going to consider it empty.  The specific cached state
14793                            // doesn't propagate except under certain conditions.
14794                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14795                        }
14796                        String adjType = null;
14797                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14798                            // Not doing bind OOM management, so treat
14799                            // this guy more like a started service.
14800                            if (app.hasShownUi && app != mHomeProcess) {
14801                                // If this process has shown some UI, let it immediately
14802                                // go to the LRU list because it may be pretty heavy with
14803                                // UI stuff.  We'll tag it with a label just to help
14804                                // debug and understand what is going on.
14805                                if (adj > clientAdj) {
14806                                    adjType = "cch-bound-ui-services";
14807                                }
14808                                app.cached = false;
14809                                clientAdj = adj;
14810                                clientProcState = procState;
14811                            } else {
14812                                if (now >= (s.lastActivity
14813                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14814                                    // This service has not seen activity within
14815                                    // recent memory, so allow it to drop to the
14816                                    // LRU list if there is no other reason to keep
14817                                    // it around.  We'll also tag it with a label just
14818                                    // to help debug and undertand what is going on.
14819                                    if (adj > clientAdj) {
14820                                        adjType = "cch-bound-services";
14821                                    }
14822                                    clientAdj = adj;
14823                                }
14824                            }
14825                        }
14826                        if (adj > clientAdj) {
14827                            // If this process has recently shown UI, and
14828                            // the process that is binding to it is less
14829                            // important than being visible, then we don't
14830                            // care about the binding as much as we care
14831                            // about letting this process get into the LRU
14832                            // list to be killed and restarted if needed for
14833                            // memory.
14834                            if (app.hasShownUi && app != mHomeProcess
14835                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14836                                adjType = "cch-bound-ui-services";
14837                            } else {
14838                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14839                                        |Context.BIND_IMPORTANT)) != 0) {
14840                                    adj = clientAdj;
14841                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14842                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14843                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14844                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14845                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14846                                    adj = clientAdj;
14847                                } else {
14848                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14849                                        adj = ProcessList.VISIBLE_APP_ADJ;
14850                                    }
14851                                }
14852                                if (!client.cached) {
14853                                    app.cached = false;
14854                                }
14855                                if (client.keeping) {
14856                                    app.keeping = true;
14857                                }
14858                                adjType = "service";
14859                            }
14860                        }
14861                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14862                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14863                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14864                            }
14865                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14866                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14867                                    // Special handling of clients who are in the top state.
14868                                    // We *may* want to consider this process to be in the
14869                                    // top state as well, but only if there is not another
14870                                    // reason for it to be running.  Being on the top is a
14871                                    // special state, meaning you are specifically running
14872                                    // for the current top app.  If the process is already
14873                                    // running in the background for some other reason, it
14874                                    // is more important to continue considering it to be
14875                                    // in the background state.
14876                                    mayBeTop = true;
14877                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14878                                } else {
14879                                    // Special handling for above-top states (persistent
14880                                    // processes).  These should not bring the current process
14881                                    // into the top state, since they are not on top.  Instead
14882                                    // give them the best state after that.
14883                                    clientProcState =
14884                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14885                                }
14886                            }
14887                        } else {
14888                            if (clientProcState <
14889                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14890                                clientProcState =
14891                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14892                            }
14893                        }
14894                        if (procState > clientProcState) {
14895                            procState = clientProcState;
14896                        }
14897                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14898                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14899                            app.pendingUiClean = true;
14900                        }
14901                        if (adjType != null) {
14902                            app.adjType = adjType;
14903                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14904                                    .REASON_SERVICE_IN_USE;
14905                            app.adjSource = cr.binding.client;
14906                            app.adjSourceOom = clientAdj;
14907                            app.adjTarget = s.name;
14908                        }
14909                    }
14910                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
14911                        app.treatLikeActivity = true;
14912                    }
14913                    final ActivityRecord a = cr.activity;
14914                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14915                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14916                                (a.visible || a.state == ActivityState.RESUMED
14917                                 || a.state == ActivityState.PAUSING)) {
14918                            adj = ProcessList.FOREGROUND_APP_ADJ;
14919                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14920                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14921                            }
14922                            app.cached = false;
14923                            app.adjType = "service";
14924                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14925                                    .REASON_SERVICE_IN_USE;
14926                            app.adjSource = a;
14927                            app.adjSourceOom = adj;
14928                            app.adjTarget = s.name;
14929                        }
14930                    }
14931                }
14932            }
14933        }
14934
14935        for (int provi = app.pubProviders.size()-1;
14936                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14937                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14938                        || procState > ActivityManager.PROCESS_STATE_TOP);
14939                provi--) {
14940            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14941            for (int i = cpr.connections.size()-1;
14942                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14943                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14944                            || procState > ActivityManager.PROCESS_STATE_TOP);
14945                    i--) {
14946                ContentProviderConnection conn = cpr.connections.get(i);
14947                ProcessRecord client = conn.client;
14948                if (client == app) {
14949                    // Being our own client is not interesting.
14950                    continue;
14951                }
14952                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14953                int clientProcState = client.curProcState;
14954                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14955                    // If the other app is cached for any reason, for purposes here
14956                    // we are going to consider it empty.
14957                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14958                }
14959                if (adj > clientAdj) {
14960                    if (app.hasShownUi && app != mHomeProcess
14961                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14962                        app.adjType = "cch-ui-provider";
14963                    } else {
14964                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14965                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14966                        app.adjType = "provider";
14967                    }
14968                    app.cached &= client.cached;
14969                    app.keeping |= client.keeping;
14970                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14971                            .REASON_PROVIDER_IN_USE;
14972                    app.adjSource = client;
14973                    app.adjSourceOom = clientAdj;
14974                    app.adjTarget = cpr.name;
14975                }
14976                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14977                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14978                        // Special handling of clients who are in the top state.
14979                        // We *may* want to consider this process to be in the
14980                        // top state as well, but only if there is not another
14981                        // reason for it to be running.  Being on the top is a
14982                        // special state, meaning you are specifically running
14983                        // for the current top app.  If the process is already
14984                        // running in the background for some other reason, it
14985                        // is more important to continue considering it to be
14986                        // in the background state.
14987                        mayBeTop = true;
14988                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14989                    } else {
14990                        // Special handling for above-top states (persistent
14991                        // processes).  These should not bring the current process
14992                        // into the top state, since they are not on top.  Instead
14993                        // give them the best state after that.
14994                        clientProcState =
14995                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14996                    }
14997                }
14998                if (procState > clientProcState) {
14999                    procState = clientProcState;
15000                }
15001                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15002                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15003                }
15004            }
15005            // If the provider has external (non-framework) process
15006            // dependencies, ensure that its adjustment is at least
15007            // FOREGROUND_APP_ADJ.
15008            if (cpr.hasExternalProcessHandles()) {
15009                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15010                    adj = ProcessList.FOREGROUND_APP_ADJ;
15011                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15012                    app.cached = false;
15013                    app.keeping = true;
15014                    app.adjType = "provider";
15015                    app.adjTarget = cpr.name;
15016                }
15017                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15018                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15019                }
15020            }
15021        }
15022
15023        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15024            // A client of one of our services or providers is in the top state.  We
15025            // *may* want to be in the top state, but not if we are already running in
15026            // the background for some other reason.  For the decision here, we are going
15027            // to pick out a few specific states that we want to remain in when a client
15028            // is top (states that tend to be longer-term) and otherwise allow it to go
15029            // to the top state.
15030            switch (procState) {
15031                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15032                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15033                case ActivityManager.PROCESS_STATE_SERVICE:
15034                    // These all are longer-term states, so pull them up to the top
15035                    // of the background states, but not all the way to the top state.
15036                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15037                    break;
15038                default:
15039                    // Otherwise, top is a better choice, so take it.
15040                    procState = ActivityManager.PROCESS_STATE_TOP;
15041                    break;
15042            }
15043        }
15044
15045        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15046            if (app.hasClientActivities) {
15047                // This is a cached process, but with client activities.  Mark it so.
15048                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15049                app.adjType = "cch-client-act";
15050            } else if (app.treatLikeActivity) {
15051                // This is a cached process, but somebody wants us to treat it like it has
15052                // an activity, okay!
15053                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15054                app.adjType = "cch-as-act";
15055            }
15056        }
15057
15058        if (adj == ProcessList.SERVICE_ADJ) {
15059            if (doingAll) {
15060                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15061                mNewNumServiceProcs++;
15062                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15063                if (!app.serviceb) {
15064                    // This service isn't far enough down on the LRU list to
15065                    // normally be a B service, but if we are low on RAM and it
15066                    // is large we want to force it down since we would prefer to
15067                    // keep launcher over it.
15068                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15069                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15070                        app.serviceHighRam = true;
15071                        app.serviceb = true;
15072                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15073                    } else {
15074                        mNewNumAServiceProcs++;
15075                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15076                    }
15077                } else {
15078                    app.serviceHighRam = false;
15079                }
15080            }
15081            if (app.serviceb) {
15082                adj = ProcessList.SERVICE_B_ADJ;
15083            }
15084        }
15085
15086        app.curRawAdj = adj;
15087
15088        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15089        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15090        if (adj > app.maxAdj) {
15091            adj = app.maxAdj;
15092            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15093                schedGroup = Process.THREAD_GROUP_DEFAULT;
15094            }
15095        }
15096        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15097            app.keeping = true;
15098        }
15099
15100        // Do final modification to adj.  Everything we do between here and applying
15101        // the final setAdj must be done in this function, because we will also use
15102        // it when computing the final cached adj later.  Note that we don't need to
15103        // worry about this for max adj above, since max adj will always be used to
15104        // keep it out of the cached vaues.
15105        adj = app.modifyRawOomAdj(adj);
15106
15107        app.curProcState = procState;
15108
15109        int importance = app.memImportance;
15110        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15111            app.curAdj = adj;
15112            app.curSchedGroup = schedGroup;
15113            if (!interesting) {
15114                // For this reporting, if there is not something explicitly
15115                // interesting in this process then we will push it to the
15116                // background importance.
15117                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15118            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15119                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15120            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15121                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15122            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15123                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15124            } else if (adj >= ProcessList.SERVICE_ADJ) {
15125                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15126            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15127                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15128            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15129                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15130            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15131                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15132            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15133                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15134            } else {
15135                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15136            }
15137        }
15138
15139        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15140        if (foregroundActivities != app.foregroundActivities) {
15141            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15142        }
15143        if (changes != 0) {
15144            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15145            app.memImportance = importance;
15146            app.foregroundActivities = foregroundActivities;
15147            int i = mPendingProcessChanges.size()-1;
15148            ProcessChangeItem item = null;
15149            while (i >= 0) {
15150                item = mPendingProcessChanges.get(i);
15151                if (item.pid == app.pid) {
15152                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15153                    break;
15154                }
15155                i--;
15156            }
15157            if (i < 0) {
15158                // No existing item in pending changes; need a new one.
15159                final int NA = mAvailProcessChanges.size();
15160                if (NA > 0) {
15161                    item = mAvailProcessChanges.remove(NA-1);
15162                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15163                } else {
15164                    item = new ProcessChangeItem();
15165                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15166                }
15167                item.changes = 0;
15168                item.pid = app.pid;
15169                item.uid = app.info.uid;
15170                if (mPendingProcessChanges.size() == 0) {
15171                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15172                            "*** Enqueueing dispatch processes changed!");
15173                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15174                }
15175                mPendingProcessChanges.add(item);
15176            }
15177            item.changes |= changes;
15178            item.importance = importance;
15179            item.foregroundActivities = foregroundActivities;
15180            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15181                    + Integer.toHexString(System.identityHashCode(item))
15182                    + " " + app.toShortString() + ": changes=" + item.changes
15183                    + " importance=" + item.importance
15184                    + " foreground=" + item.foregroundActivities
15185                    + " type=" + app.adjType + " source=" + app.adjSource
15186                    + " target=" + app.adjTarget);
15187        }
15188
15189        return app.curRawAdj;
15190    }
15191
15192    /**
15193     * Schedule PSS collection of a process.
15194     */
15195    void requestPssLocked(ProcessRecord proc, int procState) {
15196        if (mPendingPssProcesses.contains(proc)) {
15197            return;
15198        }
15199        if (mPendingPssProcesses.size() == 0) {
15200            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15201        }
15202        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15203        proc.pssProcState = procState;
15204        mPendingPssProcesses.add(proc);
15205    }
15206
15207    /**
15208     * Schedule PSS collection of all processes.
15209     */
15210    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15211        if (!always) {
15212            if (now < (mLastFullPssTime +
15213                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15214                return;
15215            }
15216        }
15217        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15218        mLastFullPssTime = now;
15219        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15220        mPendingPssProcesses.clear();
15221        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15222            ProcessRecord app = mLruProcesses.get(i);
15223            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15224                app.pssProcState = app.setProcState;
15225                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15226                        mSleeping, now);
15227                mPendingPssProcesses.add(app);
15228            }
15229        }
15230        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15231    }
15232
15233    /**
15234     * Ask a given process to GC right now.
15235     */
15236    final void performAppGcLocked(ProcessRecord app) {
15237        try {
15238            app.lastRequestedGc = SystemClock.uptimeMillis();
15239            if (app.thread != null) {
15240                if (app.reportLowMemory) {
15241                    app.reportLowMemory = false;
15242                    app.thread.scheduleLowMemory();
15243                } else {
15244                    app.thread.processInBackground();
15245                }
15246            }
15247        } catch (Exception e) {
15248            // whatever.
15249        }
15250    }
15251
15252    /**
15253     * Returns true if things are idle enough to perform GCs.
15254     */
15255    private final boolean canGcNowLocked() {
15256        boolean processingBroadcasts = false;
15257        for (BroadcastQueue q : mBroadcastQueues) {
15258            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15259                processingBroadcasts = true;
15260            }
15261        }
15262        return !processingBroadcasts
15263                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15264    }
15265
15266    /**
15267     * Perform GCs on all processes that are waiting for it, but only
15268     * if things are idle.
15269     */
15270    final void performAppGcsLocked() {
15271        final int N = mProcessesToGc.size();
15272        if (N <= 0) {
15273            return;
15274        }
15275        if (canGcNowLocked()) {
15276            while (mProcessesToGc.size() > 0) {
15277                ProcessRecord proc = mProcessesToGc.remove(0);
15278                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15279                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15280                            <= SystemClock.uptimeMillis()) {
15281                        // To avoid spamming the system, we will GC processes one
15282                        // at a time, waiting a few seconds between each.
15283                        performAppGcLocked(proc);
15284                        scheduleAppGcsLocked();
15285                        return;
15286                    } else {
15287                        // It hasn't been long enough since we last GCed this
15288                        // process...  put it in the list to wait for its time.
15289                        addProcessToGcListLocked(proc);
15290                        break;
15291                    }
15292                }
15293            }
15294
15295            scheduleAppGcsLocked();
15296        }
15297    }
15298
15299    /**
15300     * If all looks good, perform GCs on all processes waiting for them.
15301     */
15302    final void performAppGcsIfAppropriateLocked() {
15303        if (canGcNowLocked()) {
15304            performAppGcsLocked();
15305            return;
15306        }
15307        // Still not idle, wait some more.
15308        scheduleAppGcsLocked();
15309    }
15310
15311    /**
15312     * Schedule the execution of all pending app GCs.
15313     */
15314    final void scheduleAppGcsLocked() {
15315        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15316
15317        if (mProcessesToGc.size() > 0) {
15318            // Schedule a GC for the time to the next process.
15319            ProcessRecord proc = mProcessesToGc.get(0);
15320            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15321
15322            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15323            long now = SystemClock.uptimeMillis();
15324            if (when < (now+GC_TIMEOUT)) {
15325                when = now + GC_TIMEOUT;
15326            }
15327            mHandler.sendMessageAtTime(msg, when);
15328        }
15329    }
15330
15331    /**
15332     * Add a process to the array of processes waiting to be GCed.  Keeps the
15333     * list in sorted order by the last GC time.  The process can't already be
15334     * on the list.
15335     */
15336    final void addProcessToGcListLocked(ProcessRecord proc) {
15337        boolean added = false;
15338        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15339            if (mProcessesToGc.get(i).lastRequestedGc <
15340                    proc.lastRequestedGc) {
15341                added = true;
15342                mProcessesToGc.add(i+1, proc);
15343                break;
15344            }
15345        }
15346        if (!added) {
15347            mProcessesToGc.add(0, proc);
15348        }
15349    }
15350
15351    /**
15352     * Set up to ask a process to GC itself.  This will either do it
15353     * immediately, or put it on the list of processes to gc the next
15354     * time things are idle.
15355     */
15356    final void scheduleAppGcLocked(ProcessRecord app) {
15357        long now = SystemClock.uptimeMillis();
15358        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15359            return;
15360        }
15361        if (!mProcessesToGc.contains(app)) {
15362            addProcessToGcListLocked(app);
15363            scheduleAppGcsLocked();
15364        }
15365    }
15366
15367    final void checkExcessivePowerUsageLocked(boolean doKills) {
15368        updateCpuStatsNow();
15369
15370        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15371        boolean doWakeKills = doKills;
15372        boolean doCpuKills = doKills;
15373        if (mLastPowerCheckRealtime == 0) {
15374            doWakeKills = false;
15375        }
15376        if (mLastPowerCheckUptime == 0) {
15377            doCpuKills = false;
15378        }
15379        if (stats.isScreenOn()) {
15380            doWakeKills = false;
15381        }
15382        final long curRealtime = SystemClock.elapsedRealtime();
15383        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15384        final long curUptime = SystemClock.uptimeMillis();
15385        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15386        mLastPowerCheckRealtime = curRealtime;
15387        mLastPowerCheckUptime = curUptime;
15388        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15389            doWakeKills = false;
15390        }
15391        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15392            doCpuKills = false;
15393        }
15394        int i = mLruProcesses.size();
15395        while (i > 0) {
15396            i--;
15397            ProcessRecord app = mLruProcesses.get(i);
15398            if (!app.keeping) {
15399                long wtime;
15400                synchronized (stats) {
15401                    wtime = stats.getProcessWakeTime(app.info.uid,
15402                            app.pid, curRealtime);
15403                }
15404                long wtimeUsed = wtime - app.lastWakeTime;
15405                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15406                if (DEBUG_POWER) {
15407                    StringBuilder sb = new StringBuilder(128);
15408                    sb.append("Wake for ");
15409                    app.toShortString(sb);
15410                    sb.append(": over ");
15411                    TimeUtils.formatDuration(realtimeSince, sb);
15412                    sb.append(" used ");
15413                    TimeUtils.formatDuration(wtimeUsed, sb);
15414                    sb.append(" (");
15415                    sb.append((wtimeUsed*100)/realtimeSince);
15416                    sb.append("%)");
15417                    Slog.i(TAG, sb.toString());
15418                    sb.setLength(0);
15419                    sb.append("CPU for ");
15420                    app.toShortString(sb);
15421                    sb.append(": over ");
15422                    TimeUtils.formatDuration(uptimeSince, sb);
15423                    sb.append(" used ");
15424                    TimeUtils.formatDuration(cputimeUsed, sb);
15425                    sb.append(" (");
15426                    sb.append((cputimeUsed*100)/uptimeSince);
15427                    sb.append("%)");
15428                    Slog.i(TAG, sb.toString());
15429                }
15430                // If a process has held a wake lock for more
15431                // than 50% of the time during this period,
15432                // that sounds bad.  Kill!
15433                if (doWakeKills && realtimeSince > 0
15434                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15435                    synchronized (stats) {
15436                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15437                                realtimeSince, wtimeUsed);
15438                    }
15439                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15440                            + " during " + realtimeSince);
15441                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15442                } else if (doCpuKills && uptimeSince > 0
15443                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15444                    synchronized (stats) {
15445                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15446                                uptimeSince, cputimeUsed);
15447                    }
15448                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15449                            + " during " + uptimeSince);
15450                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15451                } else {
15452                    app.lastWakeTime = wtime;
15453                    app.lastCpuTime = app.curCpuTime;
15454                }
15455            }
15456        }
15457    }
15458
15459    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15460            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15461        boolean success = true;
15462
15463        if (app.curRawAdj != app.setRawAdj) {
15464            if (wasKeeping && !app.keeping) {
15465                // This app is no longer something we want to keep.  Note
15466                // its current wake lock time to later know to kill it if
15467                // it is not behaving well.
15468                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15469                synchronized (stats) {
15470                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15471                            app.pid, SystemClock.elapsedRealtime());
15472                }
15473                app.lastCpuTime = app.curCpuTime;
15474            }
15475
15476            app.setRawAdj = app.curRawAdj;
15477        }
15478
15479        if (app.curAdj != app.setAdj) {
15480            ProcessList.setOomAdj(app.pid, app.curAdj);
15481            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15482                TAG, "Set " + app.pid + " " + app.processName +
15483                " adj " + app.curAdj + ": " + app.adjType);
15484            app.setAdj = app.curAdj;
15485        }
15486
15487        if (app.setSchedGroup != app.curSchedGroup) {
15488            app.setSchedGroup = app.curSchedGroup;
15489            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15490                    "Setting process group of " + app.processName
15491                    + " to " + app.curSchedGroup);
15492            if (app.waitingToKill != null &&
15493                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15494                killUnneededProcessLocked(app, app.waitingToKill);
15495                success = false;
15496            } else {
15497                if (true) {
15498                    long oldId = Binder.clearCallingIdentity();
15499                    try {
15500                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15501                    } catch (Exception e) {
15502                        Slog.w(TAG, "Failed setting process group of " + app.pid
15503                                + " to " + app.curSchedGroup);
15504                        e.printStackTrace();
15505                    } finally {
15506                        Binder.restoreCallingIdentity(oldId);
15507                    }
15508                } else {
15509                    if (app.thread != null) {
15510                        try {
15511                            app.thread.setSchedulingGroup(app.curSchedGroup);
15512                        } catch (RemoteException e) {
15513                        }
15514                    }
15515                }
15516                Process.setSwappiness(app.pid,
15517                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15518            }
15519        }
15520        if (app.repProcState != app.curProcState) {
15521            app.repProcState = app.curProcState;
15522            if (!reportingProcessState && app.thread != null) {
15523                try {
15524                    if (false) {
15525                        //RuntimeException h = new RuntimeException("here");
15526                        Slog.i(TAG, "Sending new process state " + app.repProcState
15527                                + " to " + app /*, h*/);
15528                    }
15529                    app.thread.setProcessState(app.repProcState);
15530                } catch (RemoteException e) {
15531                }
15532            }
15533        }
15534        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15535                app.setProcState)) {
15536            app.lastStateTime = now;
15537            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15538                    mSleeping, now);
15539            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15540                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15541                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15542                    + (app.nextPssTime-now) + ": " + app);
15543        } else {
15544            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15545                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15546                requestPssLocked(app, app.setProcState);
15547                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15548                        mSleeping, now);
15549            } else if (false && DEBUG_PSS) {
15550                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15551            }
15552        }
15553        if (app.setProcState != app.curProcState) {
15554            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15555                    "Proc state change of " + app.processName
15556                    + " to " + app.curProcState);
15557            app.setProcState = app.curProcState;
15558            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15559                app.notCachedSinceIdle = false;
15560            }
15561            if (!doingAll) {
15562                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15563            } else {
15564                app.procStateChanged = true;
15565            }
15566        }
15567        return success;
15568    }
15569
15570    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15571        if (proc.thread != null && proc.baseProcessTracker != null) {
15572            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15573        }
15574    }
15575
15576    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15577            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15578        if (app.thread == null) {
15579            return false;
15580        }
15581
15582        final boolean wasKeeping = app.keeping;
15583
15584        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15585
15586        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15587                reportingProcessState, now);
15588    }
15589
15590    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15591            boolean oomAdj) {
15592        if (isForeground != proc.foregroundServices) {
15593            proc.foregroundServices = isForeground;
15594            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15595                    proc.info.uid);
15596            if (isForeground) {
15597                if (curProcs == null) {
15598                    curProcs = new ArrayList<ProcessRecord>();
15599                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15600                }
15601                if (!curProcs.contains(proc)) {
15602                    curProcs.add(proc);
15603                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15604                            proc.info.packageName, proc.info.uid);
15605                }
15606            } else {
15607                if (curProcs != null) {
15608                    if (curProcs.remove(proc)) {
15609                        mBatteryStatsService.noteEvent(
15610                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15611                                proc.info.packageName, proc.info.uid);
15612                        if (curProcs.size() <= 0) {
15613                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15614                        }
15615                    }
15616                }
15617            }
15618            if (oomAdj) {
15619                updateOomAdjLocked();
15620            }
15621        }
15622    }
15623
15624    private final ActivityRecord resumedAppLocked() {
15625        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15626        String pkg;
15627        int uid;
15628        if (act != null && !act.sleeping) {
15629            pkg = act.packageName;
15630            uid = act.info.applicationInfo.uid;
15631        } else {
15632            pkg = null;
15633            uid = -1;
15634        }
15635        // Has the UID or resumed package name changed?
15636        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15637                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15638            if (mCurResumedPackage != null) {
15639                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15640                        mCurResumedPackage, mCurResumedUid);
15641            }
15642            mCurResumedPackage = pkg;
15643            mCurResumedUid = uid;
15644            if (mCurResumedPackage != null) {
15645                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15646                        mCurResumedPackage, mCurResumedUid);
15647            }
15648        }
15649        return act;
15650    }
15651
15652    final boolean updateOomAdjLocked(ProcessRecord app) {
15653        return updateOomAdjLocked(app, false);
15654    }
15655
15656    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15657        final ActivityRecord TOP_ACT = resumedAppLocked();
15658        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15659        final boolean wasCached = app.cached;
15660
15661        mAdjSeq++;
15662
15663        // This is the desired cached adjusment we want to tell it to use.
15664        // If our app is currently cached, we know it, and that is it.  Otherwise,
15665        // we don't know it yet, and it needs to now be cached we will then
15666        // need to do a complete oom adj.
15667        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15668                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15669        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15670                SystemClock.uptimeMillis());
15671        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15672            // Changed to/from cached state, so apps after it in the LRU
15673            // list may also be changed.
15674            updateOomAdjLocked();
15675        }
15676        return success;
15677    }
15678
15679    final void updateOomAdjLocked() {
15680        final ActivityRecord TOP_ACT = resumedAppLocked();
15681        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15682        final long now = SystemClock.uptimeMillis();
15683        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15684        final int N = mLruProcesses.size();
15685
15686        if (false) {
15687            RuntimeException e = new RuntimeException();
15688            e.fillInStackTrace();
15689            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15690        }
15691
15692        mAdjSeq++;
15693        mNewNumServiceProcs = 0;
15694        mNewNumAServiceProcs = 0;
15695
15696        final int emptyProcessLimit;
15697        final int cachedProcessLimit;
15698        if (mProcessLimit <= 0) {
15699            emptyProcessLimit = cachedProcessLimit = 0;
15700        } else if (mProcessLimit == 1) {
15701            emptyProcessLimit = 1;
15702            cachedProcessLimit = 0;
15703        } else {
15704            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15705            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15706        }
15707
15708        // Let's determine how many processes we have running vs.
15709        // how many slots we have for background processes; we may want
15710        // to put multiple processes in a slot of there are enough of
15711        // them.
15712        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15713                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15714        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15715        if (numEmptyProcs > cachedProcessLimit) {
15716            // If there are more empty processes than our limit on cached
15717            // processes, then use the cached process limit for the factor.
15718            // This ensures that the really old empty processes get pushed
15719            // down to the bottom, so if we are running low on memory we will
15720            // have a better chance at keeping around more cached processes
15721            // instead of a gazillion empty processes.
15722            numEmptyProcs = cachedProcessLimit;
15723        }
15724        int emptyFactor = numEmptyProcs/numSlots;
15725        if (emptyFactor < 1) emptyFactor = 1;
15726        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15727        if (cachedFactor < 1) cachedFactor = 1;
15728        int stepCached = 0;
15729        int stepEmpty = 0;
15730        int numCached = 0;
15731        int numEmpty = 0;
15732        int numTrimming = 0;
15733
15734        mNumNonCachedProcs = 0;
15735        mNumCachedHiddenProcs = 0;
15736
15737        // First update the OOM adjustment for each of the
15738        // application processes based on their current state.
15739        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15740        int nextCachedAdj = curCachedAdj+1;
15741        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15742        int nextEmptyAdj = curEmptyAdj+2;
15743        for (int i=N-1; i>=0; i--) {
15744            ProcessRecord app = mLruProcesses.get(i);
15745            if (!app.killedByAm && app.thread != null) {
15746                app.procStateChanged = false;
15747                final boolean wasKeeping = app.keeping;
15748                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15749
15750                // If we haven't yet assigned the final cached adj
15751                // to the process, do that now.
15752                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15753                    switch (app.curProcState) {
15754                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15755                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15756                            // This process is a cached process holding activities...
15757                            // assign it the next cached value for that type, and then
15758                            // step that cached level.
15759                            app.curRawAdj = curCachedAdj;
15760                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15761                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15762                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15763                                    + ")");
15764                            if (curCachedAdj != nextCachedAdj) {
15765                                stepCached++;
15766                                if (stepCached >= cachedFactor) {
15767                                    stepCached = 0;
15768                                    curCachedAdj = nextCachedAdj;
15769                                    nextCachedAdj += 2;
15770                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15771                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15772                                    }
15773                                }
15774                            }
15775                            break;
15776                        default:
15777                            // For everything else, assign next empty cached process
15778                            // level and bump that up.  Note that this means that
15779                            // long-running services that have dropped down to the
15780                            // cached level will be treated as empty (since their process
15781                            // state is still as a service), which is what we want.
15782                            app.curRawAdj = curEmptyAdj;
15783                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15784                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15785                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15786                                    + ")");
15787                            if (curEmptyAdj != nextEmptyAdj) {
15788                                stepEmpty++;
15789                                if (stepEmpty >= emptyFactor) {
15790                                    stepEmpty = 0;
15791                                    curEmptyAdj = nextEmptyAdj;
15792                                    nextEmptyAdj += 2;
15793                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15794                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15795                                    }
15796                                }
15797                            }
15798                            break;
15799                    }
15800                }
15801
15802                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15803
15804                // Count the number of process types.
15805                switch (app.curProcState) {
15806                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15807                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15808                        mNumCachedHiddenProcs++;
15809                        numCached++;
15810                        if (numCached > cachedProcessLimit) {
15811                            killUnneededProcessLocked(app, "cached #" + numCached);
15812                        }
15813                        break;
15814                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15815                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15816                                && app.lastActivityTime < oldTime) {
15817                            killUnneededProcessLocked(app, "empty for "
15818                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15819                                    / 1000) + "s");
15820                        } else {
15821                            numEmpty++;
15822                            if (numEmpty > emptyProcessLimit) {
15823                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15824                            }
15825                        }
15826                        break;
15827                    default:
15828                        mNumNonCachedProcs++;
15829                        break;
15830                }
15831
15832                if (app.isolated && app.services.size() <= 0) {
15833                    // If this is an isolated process, and there are no
15834                    // services running in it, then the process is no longer
15835                    // needed.  We agressively kill these because we can by
15836                    // definition not re-use the same process again, and it is
15837                    // good to avoid having whatever code was running in them
15838                    // left sitting around after no longer needed.
15839                    killUnneededProcessLocked(app, "isolated not needed");
15840                }
15841
15842                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15843                        && !app.killedByAm) {
15844                    numTrimming++;
15845                }
15846            }
15847        }
15848
15849        mNumServiceProcs = mNewNumServiceProcs;
15850
15851        // Now determine the memory trimming level of background processes.
15852        // Unfortunately we need to start at the back of the list to do this
15853        // properly.  We only do this if the number of background apps we
15854        // are managing to keep around is less than half the maximum we desire;
15855        // if we are keeping a good number around, we'll let them use whatever
15856        // memory they want.
15857        final int numCachedAndEmpty = numCached + numEmpty;
15858        int memFactor;
15859        if (numCached <= ProcessList.TRIM_CACHED_APPS
15860                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15861            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15862                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15863            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15864                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15865            } else {
15866                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15867            }
15868        } else {
15869            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15870        }
15871        // We always allow the memory level to go up (better).  We only allow it to go
15872        // down if we are in a state where that is allowed, *and* the total number of processes
15873        // has gone down since last time.
15874        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15875                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15876                + " last=" + mLastNumProcesses);
15877        if (memFactor > mLastMemoryLevel) {
15878            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15879                memFactor = mLastMemoryLevel;
15880                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15881            }
15882        }
15883        mLastMemoryLevel = memFactor;
15884        mLastNumProcesses = mLruProcesses.size();
15885        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15886        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15887        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15888            if (mLowRamStartTime == 0) {
15889                mLowRamStartTime = now;
15890            }
15891            int step = 0;
15892            int fgTrimLevel;
15893            switch (memFactor) {
15894                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15895                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15896                    break;
15897                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15898                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15899                    break;
15900                default:
15901                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15902                    break;
15903            }
15904            int factor = numTrimming/3;
15905            int minFactor = 2;
15906            if (mHomeProcess != null) minFactor++;
15907            if (mPreviousProcess != null) minFactor++;
15908            if (factor < minFactor) factor = minFactor;
15909            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15910            for (int i=N-1; i>=0; i--) {
15911                ProcessRecord app = mLruProcesses.get(i);
15912                if (allChanged || app.procStateChanged) {
15913                    setProcessTrackerState(app, trackerMemFactor, now);
15914                    app.procStateChanged = false;
15915                }
15916                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15917                        && !app.killedByAm) {
15918                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15919                        try {
15920                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15921                                    "Trimming memory of " + app.processName
15922                                    + " to " + curLevel);
15923                            app.thread.scheduleTrimMemory(curLevel);
15924                        } catch (RemoteException e) {
15925                        }
15926                        if (false) {
15927                            // For now we won't do this; our memory trimming seems
15928                            // to be good enough at this point that destroying
15929                            // activities causes more harm than good.
15930                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15931                                    && app != mHomeProcess && app != mPreviousProcess) {
15932                                // Need to do this on its own message because the stack may not
15933                                // be in a consistent state at this point.
15934                                // For these apps we will also finish their activities
15935                                // to help them free memory.
15936                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15937                            }
15938                        }
15939                    }
15940                    app.trimMemoryLevel = curLevel;
15941                    step++;
15942                    if (step >= factor) {
15943                        step = 0;
15944                        switch (curLevel) {
15945                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15946                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15947                                break;
15948                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15949                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15950                                break;
15951                        }
15952                    }
15953                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15954                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15955                            && app.thread != null) {
15956                        try {
15957                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15958                                    "Trimming memory of heavy-weight " + app.processName
15959                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15960                            app.thread.scheduleTrimMemory(
15961                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15962                        } catch (RemoteException e) {
15963                        }
15964                    }
15965                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15966                } else {
15967                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15968                            || app.systemNoUi) && app.pendingUiClean) {
15969                        // If this application is now in the background and it
15970                        // had done UI, then give it the special trim level to
15971                        // have it free UI resources.
15972                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15973                        if (app.trimMemoryLevel < level && app.thread != null) {
15974                            try {
15975                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15976                                        "Trimming memory of bg-ui " + app.processName
15977                                        + " to " + level);
15978                                app.thread.scheduleTrimMemory(level);
15979                            } catch (RemoteException e) {
15980                            }
15981                        }
15982                        app.pendingUiClean = false;
15983                    }
15984                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15985                        try {
15986                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15987                                    "Trimming memory of fg " + app.processName
15988                                    + " to " + fgTrimLevel);
15989                            app.thread.scheduleTrimMemory(fgTrimLevel);
15990                        } catch (RemoteException e) {
15991                        }
15992                    }
15993                    app.trimMemoryLevel = fgTrimLevel;
15994                }
15995            }
15996        } else {
15997            if (mLowRamStartTime != 0) {
15998                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15999                mLowRamStartTime = 0;
16000            }
16001            for (int i=N-1; i>=0; i--) {
16002                ProcessRecord app = mLruProcesses.get(i);
16003                if (allChanged || app.procStateChanged) {
16004                    setProcessTrackerState(app, trackerMemFactor, now);
16005                    app.procStateChanged = false;
16006                }
16007                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16008                        || app.systemNoUi) && app.pendingUiClean) {
16009                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16010                            && app.thread != null) {
16011                        try {
16012                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16013                                    "Trimming memory of ui hidden " + app.processName
16014                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16015                            app.thread.scheduleTrimMemory(
16016                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16017                        } catch (RemoteException e) {
16018                        }
16019                    }
16020                    app.pendingUiClean = false;
16021                }
16022                app.trimMemoryLevel = 0;
16023            }
16024        }
16025
16026        if (mAlwaysFinishActivities) {
16027            // Need to do this on its own message because the stack may not
16028            // be in a consistent state at this point.
16029            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16030        }
16031
16032        if (allChanged) {
16033            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16034        }
16035
16036        if (mProcessStats.shouldWriteNowLocked(now)) {
16037            mHandler.post(new Runnable() {
16038                @Override public void run() {
16039                    synchronized (ActivityManagerService.this) {
16040                        mProcessStats.writeStateAsyncLocked();
16041                    }
16042                }
16043            });
16044        }
16045
16046        if (DEBUG_OOM_ADJ) {
16047            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16048        }
16049    }
16050
16051    final void trimApplications() {
16052        synchronized (this) {
16053            int i;
16054
16055            // First remove any unused application processes whose package
16056            // has been removed.
16057            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16058                final ProcessRecord app = mRemovedProcesses.get(i);
16059                if (app.activities.size() == 0
16060                        && app.curReceiver == null && app.services.size() == 0) {
16061                    Slog.i(
16062                        TAG, "Exiting empty application process "
16063                        + app.processName + " ("
16064                        + (app.thread != null ? app.thread.asBinder() : null)
16065                        + ")\n");
16066                    if (app.pid > 0 && app.pid != MY_PID) {
16067                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16068                                app.processName, app.setAdj, "empty");
16069                        app.killedByAm = true;
16070                        Process.killProcessQuiet(app.pid);
16071                    } else {
16072                        try {
16073                            app.thread.scheduleExit();
16074                        } catch (Exception e) {
16075                            // Ignore exceptions.
16076                        }
16077                    }
16078                    cleanUpApplicationRecordLocked(app, false, true, -1);
16079                    mRemovedProcesses.remove(i);
16080
16081                    if (app.persistent) {
16082                        if (app.persistent) {
16083                            addAppLocked(app.info, false);
16084                        }
16085                    }
16086                }
16087            }
16088
16089            // Now update the oom adj for all processes.
16090            updateOomAdjLocked();
16091        }
16092    }
16093
16094    /** This method sends the specified signal to each of the persistent apps */
16095    public void signalPersistentProcesses(int sig) throws RemoteException {
16096        if (sig != Process.SIGNAL_USR1) {
16097            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16098        }
16099
16100        synchronized (this) {
16101            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16102                    != PackageManager.PERMISSION_GRANTED) {
16103                throw new SecurityException("Requires permission "
16104                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16105            }
16106
16107            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16108                ProcessRecord r = mLruProcesses.get(i);
16109                if (r.thread != null && r.persistent) {
16110                    Process.sendSignal(r.pid, sig);
16111                }
16112            }
16113        }
16114    }
16115
16116    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16117        if (proc == null || proc == mProfileProc) {
16118            proc = mProfileProc;
16119            path = mProfileFile;
16120            profileType = mProfileType;
16121            clearProfilerLocked();
16122        }
16123        if (proc == null) {
16124            return;
16125        }
16126        try {
16127            proc.thread.profilerControl(false, path, null, profileType);
16128        } catch (RemoteException e) {
16129            throw new IllegalStateException("Process disappeared");
16130        }
16131    }
16132
16133    private void clearProfilerLocked() {
16134        if (mProfileFd != null) {
16135            try {
16136                mProfileFd.close();
16137            } catch (IOException e) {
16138            }
16139        }
16140        mProfileApp = null;
16141        mProfileProc = null;
16142        mProfileFile = null;
16143        mProfileType = 0;
16144        mAutoStopProfiler = false;
16145    }
16146
16147    public boolean profileControl(String process, int userId, boolean start,
16148            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16149
16150        try {
16151            synchronized (this) {
16152                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16153                // its own permission.
16154                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16155                        != PackageManager.PERMISSION_GRANTED) {
16156                    throw new SecurityException("Requires permission "
16157                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16158                }
16159
16160                if (start && fd == null) {
16161                    throw new IllegalArgumentException("null fd");
16162                }
16163
16164                ProcessRecord proc = null;
16165                if (process != null) {
16166                    proc = findProcessLocked(process, userId, "profileControl");
16167                }
16168
16169                if (start && (proc == null || proc.thread == null)) {
16170                    throw new IllegalArgumentException("Unknown process: " + process);
16171                }
16172
16173                if (start) {
16174                    stopProfilerLocked(null, null, 0);
16175                    setProfileApp(proc.info, proc.processName, path, fd, false);
16176                    mProfileProc = proc;
16177                    mProfileType = profileType;
16178                    try {
16179                        fd = fd.dup();
16180                    } catch (IOException e) {
16181                        fd = null;
16182                    }
16183                    proc.thread.profilerControl(start, path, fd, profileType);
16184                    fd = null;
16185                    mProfileFd = null;
16186                } else {
16187                    stopProfilerLocked(proc, path, profileType);
16188                    if (fd != null) {
16189                        try {
16190                            fd.close();
16191                        } catch (IOException e) {
16192                        }
16193                    }
16194                }
16195
16196                return true;
16197            }
16198        } catch (RemoteException e) {
16199            throw new IllegalStateException("Process disappeared");
16200        } finally {
16201            if (fd != null) {
16202                try {
16203                    fd.close();
16204                } catch (IOException e) {
16205                }
16206            }
16207        }
16208    }
16209
16210    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16211        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16212                userId, true, true, callName, null);
16213        ProcessRecord proc = null;
16214        try {
16215            int pid = Integer.parseInt(process);
16216            synchronized (mPidsSelfLocked) {
16217                proc = mPidsSelfLocked.get(pid);
16218            }
16219        } catch (NumberFormatException e) {
16220        }
16221
16222        if (proc == null) {
16223            ArrayMap<String, SparseArray<ProcessRecord>> all
16224                    = mProcessNames.getMap();
16225            SparseArray<ProcessRecord> procs = all.get(process);
16226            if (procs != null && procs.size() > 0) {
16227                proc = procs.valueAt(0);
16228                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16229                    for (int i=1; i<procs.size(); i++) {
16230                        ProcessRecord thisProc = procs.valueAt(i);
16231                        if (thisProc.userId == userId) {
16232                            proc = thisProc;
16233                            break;
16234                        }
16235                    }
16236                }
16237            }
16238        }
16239
16240        return proc;
16241    }
16242
16243    public boolean dumpHeap(String process, int userId, boolean managed,
16244            String path, ParcelFileDescriptor fd) throws RemoteException {
16245
16246        try {
16247            synchronized (this) {
16248                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16249                // its own permission (same as profileControl).
16250                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16251                        != PackageManager.PERMISSION_GRANTED) {
16252                    throw new SecurityException("Requires permission "
16253                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16254                }
16255
16256                if (fd == null) {
16257                    throw new IllegalArgumentException("null fd");
16258                }
16259
16260                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16261                if (proc == null || proc.thread == null) {
16262                    throw new IllegalArgumentException("Unknown process: " + process);
16263                }
16264
16265                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16266                if (!isDebuggable) {
16267                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16268                        throw new SecurityException("Process not debuggable: " + proc);
16269                    }
16270                }
16271
16272                proc.thread.dumpHeap(managed, path, fd);
16273                fd = null;
16274                return true;
16275            }
16276        } catch (RemoteException e) {
16277            throw new IllegalStateException("Process disappeared");
16278        } finally {
16279            if (fd != null) {
16280                try {
16281                    fd.close();
16282                } catch (IOException e) {
16283                }
16284            }
16285        }
16286    }
16287
16288    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16289    public void monitor() {
16290        synchronized (this) { }
16291    }
16292
16293    void onCoreSettingsChange(Bundle settings) {
16294        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16295            ProcessRecord processRecord = mLruProcesses.get(i);
16296            try {
16297                if (processRecord.thread != null) {
16298                    processRecord.thread.setCoreSettings(settings);
16299                }
16300            } catch (RemoteException re) {
16301                /* ignore */
16302            }
16303        }
16304    }
16305
16306    // Multi-user methods
16307
16308    /**
16309     * Start user, if its not already running, but don't bring it to foreground.
16310     */
16311    @Override
16312    public boolean startUserInBackground(final int userId) {
16313        return startUser(userId, /* foreground */ false);
16314    }
16315
16316    /**
16317     * Refreshes the list of users related to the current user when either a
16318     * user switch happens or when a new related user is started in the
16319     * background.
16320     */
16321    private void updateCurrentProfileIdsLocked() {
16322        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
16323        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16324        for (int i = 0; i < currentProfileIds.length; i++) {
16325            currentProfileIds[i] = profiles.get(i).id;
16326        }
16327        mCurrentProfileIds = currentProfileIds;
16328    }
16329
16330    private Set getProfileIdsLocked(int userId) {
16331        Set userIds = new HashSet<Integer>();
16332        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(userId);
16333        for (UserInfo user : profiles) {
16334            userIds.add(Integer.valueOf(user.id));
16335        }
16336        return userIds;
16337    }
16338
16339    @Override
16340    public boolean switchUser(final int userId) {
16341        return startUser(userId, /* foregound */ true);
16342    }
16343
16344    private boolean startUser(final int userId, boolean foreground) {
16345        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16346                != PackageManager.PERMISSION_GRANTED) {
16347            String msg = "Permission Denial: switchUser() from pid="
16348                    + Binder.getCallingPid()
16349                    + ", uid=" + Binder.getCallingUid()
16350                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16351            Slog.w(TAG, msg);
16352            throw new SecurityException(msg);
16353        }
16354
16355        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16356
16357        final long ident = Binder.clearCallingIdentity();
16358        try {
16359            synchronized (this) {
16360                final int oldUserId = mCurrentUserId;
16361                if (oldUserId == userId) {
16362                    return true;
16363                }
16364
16365                mStackSupervisor.setLockTaskModeLocked(null);
16366
16367                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16368                if (userInfo == null) {
16369                    Slog.w(TAG, "No user info for user #" + userId);
16370                    return false;
16371                }
16372
16373                if (foreground) {
16374                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16375                            R.anim.screen_user_enter);
16376                }
16377
16378                boolean needStart = false;
16379
16380                // If the user we are switching to is not currently started, then
16381                // we need to start it now.
16382                if (mStartedUsers.get(userId) == null) {
16383                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16384                    updateStartedUserArrayLocked();
16385                    needStart = true;
16386                }
16387
16388                final Integer userIdInt = Integer.valueOf(userId);
16389                mUserLru.remove(userIdInt);
16390                mUserLru.add(userIdInt);
16391
16392                if (foreground) {
16393                    mCurrentUserId = userId;
16394                    updateCurrentProfileIdsLocked();
16395                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16396                    // Once the internal notion of the active user has switched, we lock the device
16397                    // with the option to show the user switcher on the keyguard.
16398                    mWindowManager.lockNow(null);
16399                } else {
16400                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16401                    updateCurrentProfileIdsLocked();
16402                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16403                    mUserLru.remove(currentUserIdInt);
16404                    mUserLru.add(currentUserIdInt);
16405                }
16406
16407                final UserStartedState uss = mStartedUsers.get(userId);
16408
16409                // Make sure user is in the started state.  If it is currently
16410                // stopping, we need to knock that off.
16411                if (uss.mState == UserStartedState.STATE_STOPPING) {
16412                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16413                    // so we can just fairly silently bring the user back from
16414                    // the almost-dead.
16415                    uss.mState = UserStartedState.STATE_RUNNING;
16416                    updateStartedUserArrayLocked();
16417                    needStart = true;
16418                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16419                    // This means ACTION_SHUTDOWN has been sent, so we will
16420                    // need to treat this as a new boot of the user.
16421                    uss.mState = UserStartedState.STATE_BOOTING;
16422                    updateStartedUserArrayLocked();
16423                    needStart = true;
16424                }
16425
16426                if (foreground) {
16427                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16428                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16429                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16430                            oldUserId, userId, uss));
16431                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16432                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16433                }
16434
16435                if (needStart) {
16436                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16437                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16438                            | Intent.FLAG_RECEIVER_FOREGROUND);
16439                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16440                    broadcastIntentLocked(null, null, intent,
16441                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16442                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16443                }
16444
16445                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16446                    if (userId != 0) {
16447                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16448                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16449                        broadcastIntentLocked(null, null, intent, null,
16450                                new IIntentReceiver.Stub() {
16451                                    public void performReceive(Intent intent, int resultCode,
16452                                            String data, Bundle extras, boolean ordered,
16453                                            boolean sticky, int sendingUser) {
16454                                        userInitialized(uss, userId);
16455                                    }
16456                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16457                                true, false, MY_PID, Process.SYSTEM_UID,
16458                                userId);
16459                        uss.initializing = true;
16460                    } else {
16461                        getUserManagerLocked().makeInitialized(userInfo.id);
16462                    }
16463                }
16464
16465                if (foreground) {
16466                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16467                    if (homeInFront) {
16468                        startHomeActivityLocked(userId);
16469                    } else {
16470                        mStackSupervisor.resumeTopActivitiesLocked();
16471                    }
16472                    EventLogTags.writeAmSwitchUser(userId);
16473                    getUserManagerLocked().userForeground(userId);
16474                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16475                }
16476
16477                if (needStart) {
16478                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16479                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16480                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16481                    broadcastIntentLocked(null, null, intent,
16482                            null, new IIntentReceiver.Stub() {
16483                                @Override
16484                                public void performReceive(Intent intent, int resultCode, String data,
16485                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16486                                        throws RemoteException {
16487                                }
16488                            }, 0, null, null,
16489                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16490                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16491                }
16492            }
16493        } finally {
16494            Binder.restoreCallingIdentity(ident);
16495        }
16496
16497        return true;
16498    }
16499
16500    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16501        long ident = Binder.clearCallingIdentity();
16502        try {
16503            Intent intent;
16504            if (oldUserId >= 0) {
16505                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16506                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16507                        | Intent.FLAG_RECEIVER_FOREGROUND);
16508                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16509                broadcastIntentLocked(null, null, intent,
16510                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16511                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16512            }
16513            if (newUserId >= 0) {
16514                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16515                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16516                        | Intent.FLAG_RECEIVER_FOREGROUND);
16517                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16518                broadcastIntentLocked(null, null, intent,
16519                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16520                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16521                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16522                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16523                        | Intent.FLAG_RECEIVER_FOREGROUND);
16524                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16525                broadcastIntentLocked(null, null, intent,
16526                        null, null, 0, null, null,
16527                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16528                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16529            }
16530        } finally {
16531            Binder.restoreCallingIdentity(ident);
16532        }
16533    }
16534
16535    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16536            final int newUserId) {
16537        final int N = mUserSwitchObservers.beginBroadcast();
16538        if (N > 0) {
16539            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16540                int mCount = 0;
16541                @Override
16542                public void sendResult(Bundle data) throws RemoteException {
16543                    synchronized (ActivityManagerService.this) {
16544                        if (mCurUserSwitchCallback == this) {
16545                            mCount++;
16546                            if (mCount == N) {
16547                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16548                            }
16549                        }
16550                    }
16551                }
16552            };
16553            synchronized (this) {
16554                uss.switching = true;
16555                mCurUserSwitchCallback = callback;
16556            }
16557            for (int i=0; i<N; i++) {
16558                try {
16559                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16560                            newUserId, callback);
16561                } catch (RemoteException e) {
16562                }
16563            }
16564        } else {
16565            synchronized (this) {
16566                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16567            }
16568        }
16569        mUserSwitchObservers.finishBroadcast();
16570    }
16571
16572    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16573        synchronized (this) {
16574            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16575            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16576        }
16577    }
16578
16579    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16580        mCurUserSwitchCallback = null;
16581        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16582        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16583                oldUserId, newUserId, uss));
16584    }
16585
16586    void userInitialized(UserStartedState uss, int newUserId) {
16587        completeSwitchAndInitalize(uss, newUserId, true, false);
16588    }
16589
16590    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16591        completeSwitchAndInitalize(uss, newUserId, false, true);
16592    }
16593
16594    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16595            boolean clearInitializing, boolean clearSwitching) {
16596        boolean unfrozen = false;
16597        synchronized (this) {
16598            if (clearInitializing) {
16599                uss.initializing = false;
16600                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16601            }
16602            if (clearSwitching) {
16603                uss.switching = false;
16604            }
16605            if (!uss.switching && !uss.initializing) {
16606                mWindowManager.stopFreezingScreen();
16607                unfrozen = true;
16608            }
16609        }
16610        if (unfrozen) {
16611            final int N = mUserSwitchObservers.beginBroadcast();
16612            for (int i=0; i<N; i++) {
16613                try {
16614                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16615                } catch (RemoteException e) {
16616                }
16617            }
16618            mUserSwitchObservers.finishBroadcast();
16619        }
16620    }
16621
16622    void scheduleStartProfilesLocked() {
16623        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16624            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16625                    DateUtils.SECOND_IN_MILLIS);
16626        }
16627    }
16628
16629    void startProfilesLocked() {
16630        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16631        List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
16632        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16633        for (UserInfo user : profiles) {
16634            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16635                    && user.id != mCurrentUserId) {
16636                toStart.add(user);
16637            }
16638        }
16639        final int n = toStart.size();
16640        int i = 0;
16641        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16642            startUserInBackground(toStart.get(i).id);
16643        }
16644        if (i < n) {
16645            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16646        }
16647    }
16648
16649    void finishUserSwitch(UserStartedState uss) {
16650        synchronized (this) {
16651            if (uss.mState == UserStartedState.STATE_BOOTING
16652                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16653                uss.mState = UserStartedState.STATE_RUNNING;
16654                final int userId = uss.mHandle.getIdentifier();
16655                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16656                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16657                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16658                broadcastIntentLocked(null, null, intent,
16659                        null, null, 0, null, null,
16660                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16661                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16662            }
16663
16664            startProfilesLocked();
16665
16666            int num = mUserLru.size();
16667            int i = 0;
16668            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16669                Integer oldUserId = mUserLru.get(i);
16670                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16671                if (oldUss == null) {
16672                    // Shouldn't happen, but be sane if it does.
16673                    mUserLru.remove(i);
16674                    num--;
16675                    continue;
16676                }
16677                if (oldUss.mState == UserStartedState.STATE_STOPPING
16678                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16679                    // This user is already stopping, doesn't count.
16680                    num--;
16681                    i++;
16682                    continue;
16683                }
16684                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16685                    // Owner and current can't be stopped, but count as running.
16686                    i++;
16687                    continue;
16688                }
16689                // This is a user to be stopped.
16690                stopUserLocked(oldUserId, null);
16691                num--;
16692                i++;
16693            }
16694        }
16695    }
16696
16697    @Override
16698    public int stopUser(final int userId, final IStopUserCallback callback) {
16699        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16700                != PackageManager.PERMISSION_GRANTED) {
16701            String msg = "Permission Denial: switchUser() from pid="
16702                    + Binder.getCallingPid()
16703                    + ", uid=" + Binder.getCallingUid()
16704                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16705            Slog.w(TAG, msg);
16706            throw new SecurityException(msg);
16707        }
16708        if (userId <= 0) {
16709            throw new IllegalArgumentException("Can't stop primary user " + userId);
16710        }
16711        synchronized (this) {
16712            return stopUserLocked(userId, callback);
16713        }
16714    }
16715
16716    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16717        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16718        if (mCurrentUserId == userId) {
16719            return ActivityManager.USER_OP_IS_CURRENT;
16720        }
16721
16722        final UserStartedState uss = mStartedUsers.get(userId);
16723        if (uss == null) {
16724            // User is not started, nothing to do...  but we do need to
16725            // callback if requested.
16726            if (callback != null) {
16727                mHandler.post(new Runnable() {
16728                    @Override
16729                    public void run() {
16730                        try {
16731                            callback.userStopped(userId);
16732                        } catch (RemoteException e) {
16733                        }
16734                    }
16735                });
16736            }
16737            return ActivityManager.USER_OP_SUCCESS;
16738        }
16739
16740        if (callback != null) {
16741            uss.mStopCallbacks.add(callback);
16742        }
16743
16744        if (uss.mState != UserStartedState.STATE_STOPPING
16745                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16746            uss.mState = UserStartedState.STATE_STOPPING;
16747            updateStartedUserArrayLocked();
16748
16749            long ident = Binder.clearCallingIdentity();
16750            try {
16751                // We are going to broadcast ACTION_USER_STOPPING and then
16752                // once that is done send a final ACTION_SHUTDOWN and then
16753                // stop the user.
16754                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16755                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16756                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16757                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16758                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16759                // This is the result receiver for the final shutdown broadcast.
16760                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16761                    @Override
16762                    public void performReceive(Intent intent, int resultCode, String data,
16763                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16764                        finishUserStop(uss);
16765                    }
16766                };
16767                // This is the result receiver for the initial stopping broadcast.
16768                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16769                    @Override
16770                    public void performReceive(Intent intent, int resultCode, String data,
16771                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16772                        // On to the next.
16773                        synchronized (ActivityManagerService.this) {
16774                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16775                                // Whoops, we are being started back up.  Abort, abort!
16776                                return;
16777                            }
16778                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16779                        }
16780                        broadcastIntentLocked(null, null, shutdownIntent,
16781                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16782                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16783                    }
16784                };
16785                // Kick things off.
16786                broadcastIntentLocked(null, null, stoppingIntent,
16787                        null, stoppingReceiver, 0, null, null,
16788                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16789                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16790            } finally {
16791                Binder.restoreCallingIdentity(ident);
16792            }
16793        }
16794
16795        return ActivityManager.USER_OP_SUCCESS;
16796    }
16797
16798    void finishUserStop(UserStartedState uss) {
16799        final int userId = uss.mHandle.getIdentifier();
16800        boolean stopped;
16801        ArrayList<IStopUserCallback> callbacks;
16802        synchronized (this) {
16803            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16804            if (mStartedUsers.get(userId) != uss) {
16805                stopped = false;
16806            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16807                stopped = false;
16808            } else {
16809                stopped = true;
16810                // User can no longer run.
16811                mStartedUsers.remove(userId);
16812                mUserLru.remove(Integer.valueOf(userId));
16813                updateStartedUserArrayLocked();
16814
16815                // Clean up all state and processes associated with the user.
16816                // Kill all the processes for the user.
16817                forceStopUserLocked(userId, "finish user");
16818            }
16819        }
16820
16821        for (int i=0; i<callbacks.size(); i++) {
16822            try {
16823                if (stopped) callbacks.get(i).userStopped(userId);
16824                else callbacks.get(i).userStopAborted(userId);
16825            } catch (RemoteException e) {
16826            }
16827        }
16828
16829        mStackSupervisor.removeUserLocked(userId);
16830    }
16831
16832    @Override
16833    public UserInfo getCurrentUser() {
16834        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16835                != PackageManager.PERMISSION_GRANTED) && (
16836                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16837                != PackageManager.PERMISSION_GRANTED)) {
16838            String msg = "Permission Denial: getCurrentUser() from pid="
16839                    + Binder.getCallingPid()
16840                    + ", uid=" + Binder.getCallingUid()
16841                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16842            Slog.w(TAG, msg);
16843            throw new SecurityException(msg);
16844        }
16845        synchronized (this) {
16846            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16847        }
16848    }
16849
16850    int getCurrentUserIdLocked() {
16851        return mCurrentUserId;
16852    }
16853
16854    @Override
16855    public boolean isUserRunning(int userId, boolean orStopped) {
16856        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16857                != PackageManager.PERMISSION_GRANTED) {
16858            String msg = "Permission Denial: isUserRunning() from pid="
16859                    + Binder.getCallingPid()
16860                    + ", uid=" + Binder.getCallingUid()
16861                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16862            Slog.w(TAG, msg);
16863            throw new SecurityException(msg);
16864        }
16865        synchronized (this) {
16866            return isUserRunningLocked(userId, orStopped);
16867        }
16868    }
16869
16870    boolean isUserRunningLocked(int userId, boolean orStopped) {
16871        UserStartedState state = mStartedUsers.get(userId);
16872        if (state == null) {
16873            return false;
16874        }
16875        if (orStopped) {
16876            return true;
16877        }
16878        return state.mState != UserStartedState.STATE_STOPPING
16879                && state.mState != UserStartedState.STATE_SHUTDOWN;
16880    }
16881
16882    @Override
16883    public int[] getRunningUserIds() {
16884        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16885                != PackageManager.PERMISSION_GRANTED) {
16886            String msg = "Permission Denial: isUserRunning() from pid="
16887                    + Binder.getCallingPid()
16888                    + ", uid=" + Binder.getCallingUid()
16889                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16890            Slog.w(TAG, msg);
16891            throw new SecurityException(msg);
16892        }
16893        synchronized (this) {
16894            return mStartedUserArray;
16895        }
16896    }
16897
16898    private void updateStartedUserArrayLocked() {
16899        int num = 0;
16900        for (int i=0; i<mStartedUsers.size();  i++) {
16901            UserStartedState uss = mStartedUsers.valueAt(i);
16902            // This list does not include stopping users.
16903            if (uss.mState != UserStartedState.STATE_STOPPING
16904                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16905                num++;
16906            }
16907        }
16908        mStartedUserArray = new int[num];
16909        num = 0;
16910        for (int i=0; i<mStartedUsers.size();  i++) {
16911            UserStartedState uss = mStartedUsers.valueAt(i);
16912            if (uss.mState != UserStartedState.STATE_STOPPING
16913                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16914                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16915                num++;
16916            }
16917        }
16918    }
16919
16920    @Override
16921    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16922        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16923                != PackageManager.PERMISSION_GRANTED) {
16924            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16925                    + Binder.getCallingPid()
16926                    + ", uid=" + Binder.getCallingUid()
16927                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16928            Slog.w(TAG, msg);
16929            throw new SecurityException(msg);
16930        }
16931
16932        mUserSwitchObservers.register(observer);
16933    }
16934
16935    @Override
16936    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16937        mUserSwitchObservers.unregister(observer);
16938    }
16939
16940    private boolean userExists(int userId) {
16941        if (userId == 0) {
16942            return true;
16943        }
16944        UserManagerService ums = getUserManagerLocked();
16945        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16946    }
16947
16948    int[] getUsersLocked() {
16949        UserManagerService ums = getUserManagerLocked();
16950        return ums != null ? ums.getUserIds() : new int[] { 0 };
16951    }
16952
16953    UserManagerService getUserManagerLocked() {
16954        if (mUserManager == null) {
16955            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16956            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16957        }
16958        return mUserManager;
16959    }
16960
16961    private int applyUserId(int uid, int userId) {
16962        return UserHandle.getUid(userId, uid);
16963    }
16964
16965    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16966        if (info == null) return null;
16967        ApplicationInfo newInfo = new ApplicationInfo(info);
16968        newInfo.uid = applyUserId(info.uid, userId);
16969        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16970                + info.packageName;
16971        return newInfo;
16972    }
16973
16974    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16975        if (aInfo == null
16976                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16977            return aInfo;
16978        }
16979
16980        ActivityInfo info = new ActivityInfo(aInfo);
16981        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16982        return info;
16983    }
16984}
16985