ActivityManagerService.java revision 08488bf3fe6f4b1fadf59821feaf07b4c2ae52ae
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    String mDebugApp = null;
949    boolean mWaitForDebugger = false;
950    boolean mDebugTransient = false;
951    String mOrigDebugApp = null;
952    boolean mOrigWaitForDebugger = false;
953    boolean mAlwaysFinishActivities = false;
954    IActivityController mController = null;
955    String mProfileApp = null;
956    ProcessRecord mProfileProc = null;
957    String mProfileFile;
958    ParcelFileDescriptor mProfileFd;
959    int mProfileType = 0;
960    boolean mAutoStopProfiler = false;
961    String mOpenGlTraceApp = null;
962
963    static class ProcessChangeItem {
964        static final int CHANGE_ACTIVITIES = 1<<0;
965        static final int CHANGE_IMPORTANCE= 1<<1;
966        int changes;
967        int uid;
968        int pid;
969        int importance;
970        boolean foregroundActivities;
971    }
972
973    final RemoteCallbackList<IProcessObserver> mProcessObservers
974            = new RemoteCallbackList<IProcessObserver>();
975    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
976
977    final ArrayList<ProcessChangeItem> mPendingProcessChanges
978            = new ArrayList<ProcessChangeItem>();
979    final ArrayList<ProcessChangeItem> mAvailProcessChanges
980            = new ArrayList<ProcessChangeItem>();
981
982    /**
983     * Runtime CPU use collection thread.  This object's lock is used to
984     * protect all related state.
985     */
986    final Thread mProcessCpuThread;
987
988    /**
989     * Used to collect process stats when showing not responding dialog.
990     * Protected by mProcessCpuThread.
991     */
992    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
993            MONITOR_THREAD_CPU_USAGE);
994    final AtomicLong mLastCpuTime = new AtomicLong(0);
995    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
996
997    long mLastWriteTime = 0;
998
999    /**
1000     * Used to retain an update lock when the foreground activity is in
1001     * immersive mode.
1002     */
1003    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1004
1005    /**
1006     * Set to true after the system has finished booting.
1007     */
1008    boolean mBooted = false;
1009
1010    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1011    int mProcessLimitOverride = -1;
1012
1013    WindowManagerService mWindowManager;
1014
1015    final ActivityThread mSystemThread;
1016
1017    int mCurrentUserId = 0;
1018    private UserManagerService mUserManager;
1019
1020    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1021        final ProcessRecord mApp;
1022        final int mPid;
1023        final IApplicationThread mAppThread;
1024
1025        AppDeathRecipient(ProcessRecord app, int pid,
1026                IApplicationThread thread) {
1027            if (localLOGV) Slog.v(
1028                TAG, "New death recipient " + this
1029                + " for thread " + thread.asBinder());
1030            mApp = app;
1031            mPid = pid;
1032            mAppThread = thread;
1033        }
1034
1035        @Override
1036        public void binderDied() {
1037            if (localLOGV) Slog.v(
1038                TAG, "Death received in " + this
1039                + " for thread " + mAppThread.asBinder());
1040            synchronized(ActivityManagerService.this) {
1041                appDiedLocked(mApp, mPid, mAppThread);
1042            }
1043        }
1044    }
1045
1046    static final int SHOW_ERROR_MSG = 1;
1047    static final int SHOW_NOT_RESPONDING_MSG = 2;
1048    static final int SHOW_FACTORY_ERROR_MSG = 3;
1049    static final int UPDATE_CONFIGURATION_MSG = 4;
1050    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1051    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1052    static final int SERVICE_TIMEOUT_MSG = 12;
1053    static final int UPDATE_TIME_ZONE = 13;
1054    static final int SHOW_UID_ERROR_MSG = 14;
1055    static final int IM_FEELING_LUCKY_MSG = 15;
1056    static final int PROC_START_TIMEOUT_MSG = 20;
1057    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1058    static final int KILL_APPLICATION_MSG = 22;
1059    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1060    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1061    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1062    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1063    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1064    static final int CLEAR_DNS_CACHE_MSG = 28;
1065    static final int UPDATE_HTTP_PROXY_MSG = 29;
1066    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1067    static final int DISPATCH_PROCESSES_CHANGED = 31;
1068    static final int DISPATCH_PROCESS_DIED = 32;
1069    static final int REPORT_MEM_USAGE_MSG = 33;
1070    static final int REPORT_USER_SWITCH_MSG = 34;
1071    static final int CONTINUE_USER_SWITCH_MSG = 35;
1072    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1073    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1074    static final int PERSIST_URI_GRANTS_MSG = 38;
1075    static final int REQUEST_ALL_PSS_MSG = 39;
1076
1077    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1078    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1079    static final int FIRST_COMPAT_MODE_MSG = 300;
1080    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1081
1082    AlertDialog mUidAlert;
1083    CompatModeDialog mCompatModeDialog;
1084    long mLastMemUsageReportTime = 0;
1085
1086    /**
1087     * Flag whether the current user is a "monkey", i.e. whether
1088     * the UI is driven by a UI automation tool.
1089     */
1090    private boolean mUserIsMonkey;
1091
1092    final ServiceThread mHandlerThread;
1093    final MainHandler mHandler;
1094
1095    final class MainHandler extends Handler {
1096        public MainHandler(Looper looper) {
1097            super(looper, null, true);
1098        }
1099
1100        @Override
1101        public void handleMessage(Message msg) {
1102            switch (msg.what) {
1103            case SHOW_ERROR_MSG: {
1104                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1105                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1106                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1107                synchronized (ActivityManagerService.this) {
1108                    ProcessRecord proc = (ProcessRecord)data.get("app");
1109                    AppErrorResult res = (AppErrorResult) data.get("result");
1110                    if (proc != null && proc.crashDialog != null) {
1111                        Slog.e(TAG, "App already has crash dialog: " + proc);
1112                        if (res != null) {
1113                            res.set(0);
1114                        }
1115                        return;
1116                    }
1117                    if (!showBackground && UserHandle.getAppId(proc.uid)
1118                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1119                            && proc.pid != MY_PID) {
1120                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1121                        if (res != null) {
1122                            res.set(0);
1123                        }
1124                        return;
1125                    }
1126                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1127                        Dialog d = new AppErrorDialog(mContext,
1128                                ActivityManagerService.this, res, proc);
1129                        d.show();
1130                        proc.crashDialog = d;
1131                    } else {
1132                        // The device is asleep, so just pretend that the user
1133                        // saw a crash dialog and hit "force quit".
1134                        if (res != null) {
1135                            res.set(0);
1136                        }
1137                    }
1138                }
1139
1140                ensureBootCompleted();
1141            } break;
1142            case SHOW_NOT_RESPONDING_MSG: {
1143                synchronized (ActivityManagerService.this) {
1144                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1145                    ProcessRecord proc = (ProcessRecord)data.get("app");
1146                    if (proc != null && proc.anrDialog != null) {
1147                        Slog.e(TAG, "App already has anr dialog: " + proc);
1148                        return;
1149                    }
1150
1151                    Intent intent = new Intent("android.intent.action.ANR");
1152                    if (!mProcessesReady) {
1153                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1154                                | Intent.FLAG_RECEIVER_FOREGROUND);
1155                    }
1156                    broadcastIntentLocked(null, null, intent,
1157                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1158                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1159
1160                    if (mShowDialogs) {
1161                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1162                                mContext, proc, (ActivityRecord)data.get("activity"),
1163                                msg.arg1 != 0);
1164                        d.show();
1165                        proc.anrDialog = d;
1166                    } else {
1167                        // Just kill the app if there is no dialog to be shown.
1168                        killAppAtUsersRequest(proc, null);
1169                    }
1170                }
1171
1172                ensureBootCompleted();
1173            } break;
1174            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1175                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1176                synchronized (ActivityManagerService.this) {
1177                    ProcessRecord proc = (ProcessRecord) data.get("app");
1178                    if (proc == null) {
1179                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1180                        break;
1181                    }
1182                    if (proc.crashDialog != null) {
1183                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1184                        return;
1185                    }
1186                    AppErrorResult res = (AppErrorResult) data.get("result");
1187                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1188                        Dialog d = new StrictModeViolationDialog(mContext,
1189                                ActivityManagerService.this, res, proc);
1190                        d.show();
1191                        proc.crashDialog = d;
1192                    } else {
1193                        // The device is asleep, so just pretend that the user
1194                        // saw a crash dialog and hit "force quit".
1195                        res.set(0);
1196                    }
1197                }
1198                ensureBootCompleted();
1199            } break;
1200            case SHOW_FACTORY_ERROR_MSG: {
1201                Dialog d = new FactoryErrorDialog(
1202                    mContext, msg.getData().getCharSequence("msg"));
1203                d.show();
1204                ensureBootCompleted();
1205            } break;
1206            case UPDATE_CONFIGURATION_MSG: {
1207                final ContentResolver resolver = mContext.getContentResolver();
1208                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1209            } break;
1210            case GC_BACKGROUND_PROCESSES_MSG: {
1211                synchronized (ActivityManagerService.this) {
1212                    performAppGcsIfAppropriateLocked();
1213                }
1214            } break;
1215            case WAIT_FOR_DEBUGGER_MSG: {
1216                synchronized (ActivityManagerService.this) {
1217                    ProcessRecord app = (ProcessRecord)msg.obj;
1218                    if (msg.arg1 != 0) {
1219                        if (!app.waitedForDebugger) {
1220                            Dialog d = new AppWaitingForDebuggerDialog(
1221                                    ActivityManagerService.this,
1222                                    mContext, app);
1223                            app.waitDialog = d;
1224                            app.waitedForDebugger = true;
1225                            d.show();
1226                        }
1227                    } else {
1228                        if (app.waitDialog != null) {
1229                            app.waitDialog.dismiss();
1230                            app.waitDialog = null;
1231                        }
1232                    }
1233                }
1234            } break;
1235            case SERVICE_TIMEOUT_MSG: {
1236                if (mDidDexOpt) {
1237                    mDidDexOpt = false;
1238                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1239                    nmsg.obj = msg.obj;
1240                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1241                    return;
1242                }
1243                mServices.serviceTimeout((ProcessRecord)msg.obj);
1244            } break;
1245            case UPDATE_TIME_ZONE: {
1246                synchronized (ActivityManagerService.this) {
1247                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1248                        ProcessRecord r = mLruProcesses.get(i);
1249                        if (r.thread != null) {
1250                            try {
1251                                r.thread.updateTimeZone();
1252                            } catch (RemoteException ex) {
1253                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1254                            }
1255                        }
1256                    }
1257                }
1258            } break;
1259            case CLEAR_DNS_CACHE_MSG: {
1260                synchronized (ActivityManagerService.this) {
1261                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1262                        ProcessRecord r = mLruProcesses.get(i);
1263                        if (r.thread != null) {
1264                            try {
1265                                r.thread.clearDnsCache();
1266                            } catch (RemoteException ex) {
1267                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1268                            }
1269                        }
1270                    }
1271                }
1272            } break;
1273            case UPDATE_HTTP_PROXY_MSG: {
1274                ProxyProperties proxy = (ProxyProperties)msg.obj;
1275                String host = "";
1276                String port = "";
1277                String exclList = "";
1278                String pacFileUrl = null;
1279                if (proxy != null) {
1280                    host = proxy.getHost();
1281                    port = Integer.toString(proxy.getPort());
1282                    exclList = proxy.getExclusionList();
1283                    pacFileUrl = proxy.getPacFileUrl();
1284                }
1285                synchronized (ActivityManagerService.this) {
1286                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1287                        ProcessRecord r = mLruProcesses.get(i);
1288                        if (r.thread != null) {
1289                            try {
1290                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1291                            } catch (RemoteException ex) {
1292                                Slog.w(TAG, "Failed to update http proxy for: " +
1293                                        r.info.processName);
1294                            }
1295                        }
1296                    }
1297                }
1298            } break;
1299            case SHOW_UID_ERROR_MSG: {
1300                String title = "System UIDs Inconsistent";
1301                String text = "UIDs on the system are inconsistent, you need to wipe your"
1302                        + " data partition or your device will be unstable.";
1303                Log.e(TAG, title + ": " + text);
1304                if (mShowDialogs) {
1305                    // XXX This is a temporary dialog, no need to localize.
1306                    AlertDialog d = new BaseErrorDialog(mContext);
1307                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1308                    d.setCancelable(false);
1309                    d.setTitle(title);
1310                    d.setMessage(text);
1311                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1312                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1313                    mUidAlert = d;
1314                    d.show();
1315                }
1316            } break;
1317            case IM_FEELING_LUCKY_MSG: {
1318                if (mUidAlert != null) {
1319                    mUidAlert.dismiss();
1320                    mUidAlert = null;
1321                }
1322            } break;
1323            case PROC_START_TIMEOUT_MSG: {
1324                if (mDidDexOpt) {
1325                    mDidDexOpt = false;
1326                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1327                    nmsg.obj = msg.obj;
1328                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1329                    return;
1330                }
1331                ProcessRecord app = (ProcessRecord)msg.obj;
1332                synchronized (ActivityManagerService.this) {
1333                    processStartTimedOutLocked(app);
1334                }
1335            } break;
1336            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1337                synchronized (ActivityManagerService.this) {
1338                    doPendingActivityLaunchesLocked(true);
1339                }
1340            } break;
1341            case KILL_APPLICATION_MSG: {
1342                synchronized (ActivityManagerService.this) {
1343                    int appid = msg.arg1;
1344                    boolean restart = (msg.arg2 == 1);
1345                    Bundle bundle = (Bundle)msg.obj;
1346                    String pkg = bundle.getString("pkg");
1347                    String reason = bundle.getString("reason");
1348                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1349                            false, UserHandle.USER_ALL, reason);
1350                }
1351            } break;
1352            case FINALIZE_PENDING_INTENT_MSG: {
1353                ((PendingIntentRecord)msg.obj).completeFinalize();
1354            } break;
1355            case POST_HEAVY_NOTIFICATION_MSG: {
1356                INotificationManager inm = NotificationManager.getService();
1357                if (inm == null) {
1358                    return;
1359                }
1360
1361                ActivityRecord root = (ActivityRecord)msg.obj;
1362                ProcessRecord process = root.app;
1363                if (process == null) {
1364                    return;
1365                }
1366
1367                try {
1368                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1369                    String text = mContext.getString(R.string.heavy_weight_notification,
1370                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1371                    Notification notification = new Notification();
1372                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1373                    notification.when = 0;
1374                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1375                    notification.tickerText = text;
1376                    notification.defaults = 0; // please be quiet
1377                    notification.sound = null;
1378                    notification.vibrate = null;
1379                    notification.setLatestEventInfo(context, text,
1380                            mContext.getText(R.string.heavy_weight_notification_detail),
1381                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1382                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1383                                    new UserHandle(root.userId)));
1384
1385                    try {
1386                        int[] outId = new int[1];
1387                        inm.enqueueNotificationWithTag("android", "android", null,
1388                                R.string.heavy_weight_notification,
1389                                notification, outId, root.userId);
1390                    } catch (RuntimeException e) {
1391                        Slog.w(ActivityManagerService.TAG,
1392                                "Error showing notification for heavy-weight app", e);
1393                    } catch (RemoteException e) {
1394                    }
1395                } catch (NameNotFoundException e) {
1396                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1397                }
1398            } break;
1399            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1400                INotificationManager inm = NotificationManager.getService();
1401                if (inm == null) {
1402                    return;
1403                }
1404                try {
1405                    inm.cancelNotificationWithTag("android", null,
1406                            R.string.heavy_weight_notification,  msg.arg1);
1407                } catch (RuntimeException e) {
1408                    Slog.w(ActivityManagerService.TAG,
1409                            "Error canceling notification for service", e);
1410                } catch (RemoteException e) {
1411                }
1412            } break;
1413            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1414                synchronized (ActivityManagerService.this) {
1415                    checkExcessivePowerUsageLocked(true);
1416                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1417                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1418                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1419                }
1420            } break;
1421            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1422                synchronized (ActivityManagerService.this) {
1423                    ActivityRecord ar = (ActivityRecord)msg.obj;
1424                    if (mCompatModeDialog != null) {
1425                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1426                                ar.info.applicationInfo.packageName)) {
1427                            return;
1428                        }
1429                        mCompatModeDialog.dismiss();
1430                        mCompatModeDialog = null;
1431                    }
1432                    if (ar != null && false) {
1433                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1434                                ar.packageName)) {
1435                            int mode = mCompatModePackages.computeCompatModeLocked(
1436                                    ar.info.applicationInfo);
1437                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1438                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1439                                mCompatModeDialog = new CompatModeDialog(
1440                                        ActivityManagerService.this, mContext,
1441                                        ar.info.applicationInfo);
1442                                mCompatModeDialog.show();
1443                            }
1444                        }
1445                    }
1446                }
1447                break;
1448            }
1449            case DISPATCH_PROCESSES_CHANGED: {
1450                dispatchProcessesChanged();
1451                break;
1452            }
1453            case DISPATCH_PROCESS_DIED: {
1454                final int pid = msg.arg1;
1455                final int uid = msg.arg2;
1456                dispatchProcessDied(pid, uid);
1457                break;
1458            }
1459            case REPORT_MEM_USAGE_MSG: {
1460                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1461                Thread thread = new Thread() {
1462                    @Override public void run() {
1463                        final SparseArray<ProcessMemInfo> infoMap
1464                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1465                        for (int i=0, N=memInfos.size(); i<N; i++) {
1466                            ProcessMemInfo mi = memInfos.get(i);
1467                            infoMap.put(mi.pid, mi);
1468                        }
1469                        updateCpuStatsNow();
1470                        synchronized (mProcessCpuThread) {
1471                            final int N = mProcessCpuTracker.countStats();
1472                            for (int i=0; i<N; i++) {
1473                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1474                                if (st.vsize > 0) {
1475                                    long pss = Debug.getPss(st.pid, null);
1476                                    if (pss > 0) {
1477                                        if (infoMap.indexOfKey(st.pid) < 0) {
1478                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1479                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1480                                            mi.pss = pss;
1481                                            memInfos.add(mi);
1482                                        }
1483                                    }
1484                                }
1485                            }
1486                        }
1487
1488                        long totalPss = 0;
1489                        for (int i=0, N=memInfos.size(); i<N; i++) {
1490                            ProcessMemInfo mi = memInfos.get(i);
1491                            if (mi.pss == 0) {
1492                                mi.pss = Debug.getPss(mi.pid, null);
1493                            }
1494                            totalPss += mi.pss;
1495                        }
1496                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1497                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1498                                if (lhs.oomAdj != rhs.oomAdj) {
1499                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1500                                }
1501                                if (lhs.pss != rhs.pss) {
1502                                    return lhs.pss < rhs.pss ? 1 : -1;
1503                                }
1504                                return 0;
1505                            }
1506                        });
1507
1508                        StringBuilder tag = new StringBuilder(128);
1509                        StringBuilder stack = new StringBuilder(128);
1510                        tag.append("Low on memory -- ");
1511                        appendMemBucket(tag, totalPss, "total", false);
1512                        appendMemBucket(stack, totalPss, "total", true);
1513
1514                        StringBuilder logBuilder = new StringBuilder(1024);
1515                        logBuilder.append("Low on memory:\n");
1516
1517                        boolean firstLine = true;
1518                        int lastOomAdj = Integer.MIN_VALUE;
1519                        for (int i=0, N=memInfos.size(); i<N; i++) {
1520                            ProcessMemInfo mi = memInfos.get(i);
1521
1522                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1523                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1524                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1525                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1526                                if (lastOomAdj != mi.oomAdj) {
1527                                    lastOomAdj = mi.oomAdj;
1528                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1529                                        tag.append(" / ");
1530                                    }
1531                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1532                                        if (firstLine) {
1533                                            stack.append(":");
1534                                            firstLine = false;
1535                                        }
1536                                        stack.append("\n\t at ");
1537                                    } else {
1538                                        stack.append("$");
1539                                    }
1540                                } else {
1541                                    tag.append(" ");
1542                                    stack.append("$");
1543                                }
1544                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1545                                    appendMemBucket(tag, mi.pss, mi.name, false);
1546                                }
1547                                appendMemBucket(stack, mi.pss, mi.name, true);
1548                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1549                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1550                                    stack.append("(");
1551                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1552                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1553                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1554                                            stack.append(":");
1555                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1556                                        }
1557                                    }
1558                                    stack.append(")");
1559                                }
1560                            }
1561
1562                            logBuilder.append("  ");
1563                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1564                            logBuilder.append(' ');
1565                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1566                            logBuilder.append(' ');
1567                            ProcessList.appendRamKb(logBuilder, mi.pss);
1568                            logBuilder.append(" kB: ");
1569                            logBuilder.append(mi.name);
1570                            logBuilder.append(" (");
1571                            logBuilder.append(mi.pid);
1572                            logBuilder.append(") ");
1573                            logBuilder.append(mi.adjType);
1574                            logBuilder.append('\n');
1575                            if (mi.adjReason != null) {
1576                                logBuilder.append("                      ");
1577                                logBuilder.append(mi.adjReason);
1578                                logBuilder.append('\n');
1579                            }
1580                        }
1581
1582                        logBuilder.append("           ");
1583                        ProcessList.appendRamKb(logBuilder, totalPss);
1584                        logBuilder.append(" kB: TOTAL\n");
1585
1586                        long[] infos = new long[Debug.MEMINFO_COUNT];
1587                        Debug.getMemInfo(infos);
1588                        logBuilder.append("  MemInfo: ");
1589                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1590                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1591                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1592                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1593                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1594                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1595                            logBuilder.append("  ZRAM: ");
1596                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1597                            logBuilder.append(" kB RAM, ");
1598                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1599                            logBuilder.append(" kB swap total, ");
1600                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1601                            logBuilder.append(" kB swap free\n");
1602                        }
1603                        Slog.i(TAG, logBuilder.toString());
1604
1605                        StringBuilder dropBuilder = new StringBuilder(1024);
1606                        /*
1607                        StringWriter oomSw = new StringWriter();
1608                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1609                        StringWriter catSw = new StringWriter();
1610                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1611                        String[] emptyArgs = new String[] { };
1612                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1613                        oomPw.flush();
1614                        String oomString = oomSw.toString();
1615                        */
1616                        dropBuilder.append(stack);
1617                        dropBuilder.append('\n');
1618                        dropBuilder.append('\n');
1619                        dropBuilder.append(logBuilder);
1620                        dropBuilder.append('\n');
1621                        /*
1622                        dropBuilder.append(oomString);
1623                        dropBuilder.append('\n');
1624                        */
1625                        StringWriter catSw = new StringWriter();
1626                        synchronized (ActivityManagerService.this) {
1627                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1628                            String[] emptyArgs = new String[] { };
1629                            catPw.println();
1630                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1631                            catPw.println();
1632                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1633                                    false, false, null);
1634                            catPw.println();
1635                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1636                            catPw.flush();
1637                        }
1638                        dropBuilder.append(catSw.toString());
1639                        addErrorToDropBox("lowmem", null, "system_server", null,
1640                                null, tag.toString(), dropBuilder.toString(), null, null);
1641                        //Slog.i(TAG, "Sent to dropbox:");
1642                        //Slog.i(TAG, dropBuilder.toString());
1643                        synchronized (ActivityManagerService.this) {
1644                            long now = SystemClock.uptimeMillis();
1645                            if (mLastMemUsageReportTime < now) {
1646                                mLastMemUsageReportTime = now;
1647                            }
1648                        }
1649                    }
1650                };
1651                thread.start();
1652                break;
1653            }
1654            case REPORT_USER_SWITCH_MSG: {
1655                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1656                break;
1657            }
1658            case CONTINUE_USER_SWITCH_MSG: {
1659                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1660                break;
1661            }
1662            case USER_SWITCH_TIMEOUT_MSG: {
1663                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1664                break;
1665            }
1666            case IMMERSIVE_MODE_LOCK_MSG: {
1667                final boolean nextState = (msg.arg1 != 0);
1668                if (mUpdateLock.isHeld() != nextState) {
1669                    if (DEBUG_IMMERSIVE) {
1670                        final ActivityRecord r = (ActivityRecord) msg.obj;
1671                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1672                    }
1673                    if (nextState) {
1674                        mUpdateLock.acquire();
1675                    } else {
1676                        mUpdateLock.release();
1677                    }
1678                }
1679                break;
1680            }
1681            case PERSIST_URI_GRANTS_MSG: {
1682                writeGrantedUriPermissions();
1683                break;
1684            }
1685            case REQUEST_ALL_PSS_MSG: {
1686                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1687                break;
1688            }
1689            }
1690        }
1691    };
1692
1693    static final int COLLECT_PSS_BG_MSG = 1;
1694
1695    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1696        @Override
1697        public void handleMessage(Message msg) {
1698            switch (msg.what) {
1699            case COLLECT_PSS_BG_MSG: {
1700                int i=0, num=0;
1701                long start = SystemClock.uptimeMillis();
1702                long[] tmp = new long[1];
1703                do {
1704                    ProcessRecord proc;
1705                    int procState;
1706                    int pid;
1707                    synchronized (ActivityManagerService.this) {
1708                        if (i >= mPendingPssProcesses.size()) {
1709                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1710                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1711                            mPendingPssProcesses.clear();
1712                            return;
1713                        }
1714                        proc = mPendingPssProcesses.get(i);
1715                        procState = proc.pssProcState;
1716                        if (proc.thread != null && procState == proc.setProcState) {
1717                            pid = proc.pid;
1718                        } else {
1719                            proc = null;
1720                            pid = 0;
1721                        }
1722                        i++;
1723                    }
1724                    if (proc != null) {
1725                        long pss = Debug.getPss(pid, tmp);
1726                        synchronized (ActivityManagerService.this) {
1727                            if (proc.thread != null && proc.setProcState == procState
1728                                    && proc.pid == pid) {
1729                                num++;
1730                                proc.lastPssTime = SystemClock.uptimeMillis();
1731                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1732                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1733                                        + ": " + pss + " lastPss=" + proc.lastPss
1734                                        + " state=" + ProcessList.makeProcStateString(procState));
1735                                if (proc.initialIdlePss == 0) {
1736                                    proc.initialIdlePss = pss;
1737                                }
1738                                proc.lastPss = pss;
1739                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1740                                    proc.lastCachedPss = pss;
1741                                }
1742                            }
1743                        }
1744                    }
1745                } while (true);
1746            }
1747            }
1748        }
1749    };
1750
1751    public void setSystemProcess() {
1752        try {
1753            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1754            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1755            ServiceManager.addService("meminfo", new MemBinder(this));
1756            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1757            ServiceManager.addService("dbinfo", new DbBinder(this));
1758            if (MONITOR_CPU_USAGE) {
1759                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1760            }
1761            ServiceManager.addService("permission", new PermissionController(this));
1762
1763            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1764                    "android", STOCK_PM_FLAGS);
1765            mSystemThread.installSystemApplicationInfo(info);
1766
1767            synchronized (this) {
1768                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1769                app.persistent = true;
1770                app.pid = MY_PID;
1771                app.maxAdj = ProcessList.SYSTEM_ADJ;
1772                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1773                mProcessNames.put(app.processName, app.uid, app);
1774                synchronized (mPidsSelfLocked) {
1775                    mPidsSelfLocked.put(app.pid, app);
1776                }
1777                updateLruProcessLocked(app, false, null);
1778                updateOomAdjLocked();
1779            }
1780        } catch (PackageManager.NameNotFoundException e) {
1781            throw new RuntimeException(
1782                    "Unable to find android system package", e);
1783        }
1784    }
1785
1786    public void setWindowManager(WindowManagerService wm) {
1787        mWindowManager = wm;
1788        mStackSupervisor.setWindowManager(wm);
1789    }
1790
1791    public void startObservingNativeCrashes() {
1792        final NativeCrashListener ncl = new NativeCrashListener(this);
1793        ncl.start();
1794    }
1795
1796    public IAppOpsService getAppOpsService() {
1797        return mAppOpsService;
1798    }
1799
1800    static class MemBinder extends Binder {
1801        ActivityManagerService mActivityManagerService;
1802        MemBinder(ActivityManagerService activityManagerService) {
1803            mActivityManagerService = activityManagerService;
1804        }
1805
1806        @Override
1807        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1808            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1809                    != PackageManager.PERMISSION_GRANTED) {
1810                pw.println("Permission Denial: can't dump meminfo from from pid="
1811                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1812                        + " without permission " + android.Manifest.permission.DUMP);
1813                return;
1814            }
1815
1816            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1817        }
1818    }
1819
1820    static class GraphicsBinder extends Binder {
1821        ActivityManagerService mActivityManagerService;
1822        GraphicsBinder(ActivityManagerService activityManagerService) {
1823            mActivityManagerService = activityManagerService;
1824        }
1825
1826        @Override
1827        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1828            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1829                    != PackageManager.PERMISSION_GRANTED) {
1830                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1831                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1832                        + " without permission " + android.Manifest.permission.DUMP);
1833                return;
1834            }
1835
1836            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1837        }
1838    }
1839
1840    static class DbBinder extends Binder {
1841        ActivityManagerService mActivityManagerService;
1842        DbBinder(ActivityManagerService activityManagerService) {
1843            mActivityManagerService = activityManagerService;
1844        }
1845
1846        @Override
1847        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1848            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1849                    != PackageManager.PERMISSION_GRANTED) {
1850                pw.println("Permission Denial: can't dump dbinfo from from pid="
1851                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1852                        + " without permission " + android.Manifest.permission.DUMP);
1853                return;
1854            }
1855
1856            mActivityManagerService.dumpDbInfo(fd, pw, args);
1857        }
1858    }
1859
1860    static class CpuBinder extends Binder {
1861        ActivityManagerService mActivityManagerService;
1862        CpuBinder(ActivityManagerService activityManagerService) {
1863            mActivityManagerService = activityManagerService;
1864        }
1865
1866        @Override
1867        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1868            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1869                    != PackageManager.PERMISSION_GRANTED) {
1870                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1871                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1872                        + " without permission " + android.Manifest.permission.DUMP);
1873                return;
1874            }
1875
1876            synchronized (mActivityManagerService.mProcessCpuThread) {
1877                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1878                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1879                        SystemClock.uptimeMillis()));
1880            }
1881        }
1882    }
1883
1884    public static final class Lifecycle extends SystemService {
1885        private final ActivityManagerService mService;
1886
1887        public Lifecycle(Context context) {
1888            super(context);
1889            mService = new ActivityManagerService(context);
1890        }
1891
1892        @Override
1893        public void onStart() {
1894            mService.start();
1895        }
1896
1897        public ActivityManagerService getService() {
1898            return mService;
1899        }
1900    }
1901
1902    // Note: This method is invoked on the main thread but may need to attach various
1903    // handlers to other threads.  So take care to be explicit about the looper.
1904    public ActivityManagerService(Context systemContext) {
1905        mContext = systemContext;
1906        mFactoryTest = FactoryTest.getMode();
1907        mSystemThread = ActivityThread.currentActivityThread();
1908
1909        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1910
1911        mHandlerThread = new ServiceThread(TAG,
1912                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1913        mHandlerThread.start();
1914        mHandler = new MainHandler(mHandlerThread.getLooper());
1915
1916        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1917                "foreground", BROADCAST_FG_TIMEOUT, false);
1918        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1919                "background", BROADCAST_BG_TIMEOUT, true);
1920        mBroadcastQueues[0] = mFgBroadcastQueue;
1921        mBroadcastQueues[1] = mBgBroadcastQueue;
1922
1923        mServices = new ActiveServices(this);
1924        mProviderMap = new ProviderMap(this);
1925
1926        // TODO: Move creation of battery stats service outside of activity manager service.
1927        File dataDir = Environment.getDataDirectory();
1928        File systemDir = new File(dataDir, "system");
1929        systemDir.mkdirs();
1930        mBatteryStatsService = new BatteryStatsService(new File(
1931                systemDir, "batterystats.bin").toString(), mHandler);
1932        mBatteryStatsService.getActiveStatistics().readLocked();
1933        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1934        mOnBattery = DEBUG_POWER ? true
1935                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1936        mBatteryStatsService.getActiveStatistics().setCallback(this);
1937
1938        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1939
1940        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1941        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1942
1943        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1944
1945        // User 0 is the first and only user that runs at boot.
1946        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1947        mUserLru.add(Integer.valueOf(0));
1948        updateStartedUserArrayLocked();
1949
1950        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1951            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1952
1953        mConfiguration.setToDefaults();
1954        mConfiguration.setLocale(Locale.getDefault());
1955
1956        mConfigurationSeq = mConfiguration.seq = 1;
1957        mProcessCpuTracker.init();
1958
1959        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1960        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1961        mStackSupervisor = new ActivityStackSupervisor(this);
1962
1963        mProcessCpuThread = new Thread("CpuTracker") {
1964            @Override
1965            public void run() {
1966                while (true) {
1967                    try {
1968                        try {
1969                            synchronized(this) {
1970                                final long now = SystemClock.uptimeMillis();
1971                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1972                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1973                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1974                                //        + ", write delay=" + nextWriteDelay);
1975                                if (nextWriteDelay < nextCpuDelay) {
1976                                    nextCpuDelay = nextWriteDelay;
1977                                }
1978                                if (nextCpuDelay > 0) {
1979                                    mProcessCpuMutexFree.set(true);
1980                                    this.wait(nextCpuDelay);
1981                                }
1982                            }
1983                        } catch (InterruptedException e) {
1984                        }
1985                        updateCpuStatsNow();
1986                    } catch (Exception e) {
1987                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1988                    }
1989                }
1990            }
1991        };
1992
1993        Watchdog.getInstance().addMonitor(this);
1994        Watchdog.getInstance().addThread(mHandler);
1995    }
1996
1997    private void start() {
1998        mProcessCpuThread.start();
1999
2000        mBatteryStatsService.publish(mContext);
2001        mUsageStatsService.publish(mContext);
2002        mAppOpsService.publish(mContext);
2003        startRunning(null, null, null, null);
2004    }
2005
2006    @Override
2007    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2008            throws RemoteException {
2009        if (code == SYSPROPS_TRANSACTION) {
2010            // We need to tell all apps about the system property change.
2011            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2012            synchronized(this) {
2013                final int NP = mProcessNames.getMap().size();
2014                for (int ip=0; ip<NP; ip++) {
2015                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2016                    final int NA = apps.size();
2017                    for (int ia=0; ia<NA; ia++) {
2018                        ProcessRecord app = apps.valueAt(ia);
2019                        if (app.thread != null) {
2020                            procs.add(app.thread.asBinder());
2021                        }
2022                    }
2023                }
2024            }
2025
2026            int N = procs.size();
2027            for (int i=0; i<N; i++) {
2028                Parcel data2 = Parcel.obtain();
2029                try {
2030                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2031                } catch (RemoteException e) {
2032                }
2033                data2.recycle();
2034            }
2035        }
2036        try {
2037            return super.onTransact(code, data, reply, flags);
2038        } catch (RuntimeException e) {
2039            // The activity manager only throws security exceptions, so let's
2040            // log all others.
2041            if (!(e instanceof SecurityException)) {
2042                Slog.wtf(TAG, "Activity Manager Crash", e);
2043            }
2044            throw e;
2045        }
2046    }
2047
2048    void updateCpuStats() {
2049        final long now = SystemClock.uptimeMillis();
2050        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2051            return;
2052        }
2053        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2054            synchronized (mProcessCpuThread) {
2055                mProcessCpuThread.notify();
2056            }
2057        }
2058    }
2059
2060    void updateCpuStatsNow() {
2061        synchronized (mProcessCpuThread) {
2062            mProcessCpuMutexFree.set(false);
2063            final long now = SystemClock.uptimeMillis();
2064            boolean haveNewCpuStats = false;
2065
2066            if (MONITOR_CPU_USAGE &&
2067                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2068                mLastCpuTime.set(now);
2069                haveNewCpuStats = true;
2070                mProcessCpuTracker.update();
2071                //Slog.i(TAG, mProcessCpu.printCurrentState());
2072                //Slog.i(TAG, "Total CPU usage: "
2073                //        + mProcessCpu.getTotalCpuPercent() + "%");
2074
2075                // Slog the cpu usage if the property is set.
2076                if ("true".equals(SystemProperties.get("events.cpu"))) {
2077                    int user = mProcessCpuTracker.getLastUserTime();
2078                    int system = mProcessCpuTracker.getLastSystemTime();
2079                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2080                    int irq = mProcessCpuTracker.getLastIrqTime();
2081                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2082                    int idle = mProcessCpuTracker.getLastIdleTime();
2083
2084                    int total = user + system + iowait + irq + softIrq + idle;
2085                    if (total == 0) total = 1;
2086
2087                    EventLog.writeEvent(EventLogTags.CPU,
2088                            ((user+system+iowait+irq+softIrq) * 100) / total,
2089                            (user * 100) / total,
2090                            (system * 100) / total,
2091                            (iowait * 100) / total,
2092                            (irq * 100) / total,
2093                            (softIrq * 100) / total);
2094                }
2095            }
2096
2097            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2098            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2099            synchronized(bstats) {
2100                synchronized(mPidsSelfLocked) {
2101                    if (haveNewCpuStats) {
2102                        if (mOnBattery) {
2103                            int perc = bstats.startAddingCpuLocked();
2104                            int totalUTime = 0;
2105                            int totalSTime = 0;
2106                            final int N = mProcessCpuTracker.countStats();
2107                            for (int i=0; i<N; i++) {
2108                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2109                                if (!st.working) {
2110                                    continue;
2111                                }
2112                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2113                                int otherUTime = (st.rel_utime*perc)/100;
2114                                int otherSTime = (st.rel_stime*perc)/100;
2115                                totalUTime += otherUTime;
2116                                totalSTime += otherSTime;
2117                                if (pr != null) {
2118                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2119                                    if (ps == null || !ps.isActive()) {
2120                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2121                                                pr.info.uid, pr.processName);
2122                                    }
2123                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2124                                            st.rel_stime-otherSTime);
2125                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2126                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2127                                } else {
2128                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2129                                    if (ps == null || !ps.isActive()) {
2130                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2131                                                bstats.mapUid(st.uid), st.name);
2132                                    }
2133                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2134                                            st.rel_stime-otherSTime);
2135                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2136                                }
2137                            }
2138                            bstats.finishAddingCpuLocked(perc, totalUTime,
2139                                    totalSTime, cpuSpeedTimes);
2140                        }
2141                    }
2142                }
2143
2144                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2145                    mLastWriteTime = now;
2146                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2147                }
2148            }
2149        }
2150    }
2151
2152    @Override
2153    public void batteryNeedsCpuUpdate() {
2154        updateCpuStatsNow();
2155    }
2156
2157    @Override
2158    public void batteryPowerChanged(boolean onBattery) {
2159        // When plugging in, update the CPU stats first before changing
2160        // the plug state.
2161        updateCpuStatsNow();
2162        synchronized (this) {
2163            synchronized(mPidsSelfLocked) {
2164                mOnBattery = DEBUG_POWER ? true : onBattery;
2165            }
2166        }
2167    }
2168
2169    /**
2170     * Initialize the application bind args. These are passed to each
2171     * process when the bindApplication() IPC is sent to the process. They're
2172     * lazily setup to make sure the services are running when they're asked for.
2173     */
2174    private HashMap<String, IBinder> getCommonServicesLocked() {
2175        if (mAppBindArgs == null) {
2176            mAppBindArgs = new HashMap<String, IBinder>();
2177
2178            // Setup the application init args
2179            mAppBindArgs.put("package", ServiceManager.getService("package"));
2180            mAppBindArgs.put("window", ServiceManager.getService("window"));
2181            mAppBindArgs.put(Context.ALARM_SERVICE,
2182                    ServiceManager.getService(Context.ALARM_SERVICE));
2183        }
2184        return mAppBindArgs;
2185    }
2186
2187    final void setFocusedActivityLocked(ActivityRecord r) {
2188        if (mFocusedActivity != r) {
2189            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2190            mFocusedActivity = r;
2191            mStackSupervisor.setFocusedStack(r);
2192            if (r != null) {
2193                mWindowManager.setFocusedApp(r.appToken, true);
2194            }
2195            applyUpdateLockStateLocked(r);
2196        }
2197    }
2198
2199    @Override
2200    public void setFocusedStack(int stackId) {
2201        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2202        synchronized (ActivityManagerService.this) {
2203            ActivityStack stack = mStackSupervisor.getStack(stackId);
2204            if (stack != null) {
2205                ActivityRecord r = stack.topRunningActivityLocked(null);
2206                if (r != null) {
2207                    setFocusedActivityLocked(r);
2208                }
2209            }
2210        }
2211    }
2212
2213    @Override
2214    public void notifyActivityDrawn(IBinder token) {
2215        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2216        synchronized (this) {
2217            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2218            if (r != null) {
2219                r.task.stack.notifyActivityDrawnLocked(r);
2220            }
2221        }
2222    }
2223
2224    final void applyUpdateLockStateLocked(ActivityRecord r) {
2225        // Modifications to the UpdateLock state are done on our handler, outside
2226        // the activity manager's locks.  The new state is determined based on the
2227        // state *now* of the relevant activity record.  The object is passed to
2228        // the handler solely for logging detail, not to be consulted/modified.
2229        final boolean nextState = r != null && r.immersive;
2230        mHandler.sendMessage(
2231                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2232    }
2233
2234    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2235        Message msg = Message.obtain();
2236        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2237        msg.obj = r.task.askedCompatMode ? null : r;
2238        mHandler.sendMessage(msg);
2239    }
2240
2241    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2242            String what, Object obj, ProcessRecord srcApp) {
2243        app.lastActivityTime = now;
2244
2245        if (app.activities.size() > 0) {
2246            // Don't want to touch dependent processes that are hosting activities.
2247            return index;
2248        }
2249
2250        int lrui = mLruProcesses.lastIndexOf(app);
2251        if (lrui < 0) {
2252            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2253                    + what + " " + obj + " from " + srcApp);
2254            return index;
2255        }
2256
2257        if (lrui >= index) {
2258            // Don't want to cause this to move dependent processes *back* in the
2259            // list as if they were less frequently used.
2260            return index;
2261        }
2262
2263        if (lrui >= mLruProcessActivityStart) {
2264            // Don't want to touch dependent processes that are hosting activities.
2265            return index;
2266        }
2267
2268        mLruProcesses.remove(lrui);
2269        if (index > 0) {
2270            index--;
2271        }
2272        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2273                + " in LRU list: " + app);
2274        mLruProcesses.add(index, app);
2275        return index;
2276    }
2277
2278    final void removeLruProcessLocked(ProcessRecord app) {
2279        int lrui = mLruProcesses.lastIndexOf(app);
2280        if (lrui >= 0) {
2281            if (lrui <= mLruProcessActivityStart) {
2282                mLruProcessActivityStart--;
2283            }
2284            if (lrui <= mLruProcessServiceStart) {
2285                mLruProcessServiceStart--;
2286            }
2287            mLruProcesses.remove(lrui);
2288        }
2289    }
2290
2291    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2292            ProcessRecord client) {
2293        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2294        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2295        if (!activityChange && hasActivity) {
2296            // The process has activties, so we are only going to allow activity-based
2297            // adjustments move it.  It should be kept in the front of the list with other
2298            // processes that have activities, and we don't want those to change their
2299            // order except due to activity operations.
2300            return;
2301        }
2302
2303        mLruSeq++;
2304        final long now = SystemClock.uptimeMillis();
2305        app.lastActivityTime = now;
2306
2307        // First a quick reject: if the app is already at the position we will
2308        // put it, then there is nothing to do.
2309        if (hasActivity) {
2310            final int N = mLruProcesses.size();
2311            if (N > 0 && mLruProcesses.get(N-1) == app) {
2312                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2313                return;
2314            }
2315        } else {
2316            if (mLruProcessServiceStart > 0
2317                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2318                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2319                return;
2320            }
2321        }
2322
2323        int lrui = mLruProcesses.lastIndexOf(app);
2324
2325        if (app.persistent && lrui >= 0) {
2326            // We don't care about the position of persistent processes, as long as
2327            // they are in the list.
2328            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2329            return;
2330        }
2331
2332        /* In progress: compute new position first, so we can avoid doing work
2333           if the process is not actually going to move.  Not yet working.
2334        int addIndex;
2335        int nextIndex;
2336        boolean inActivity = false, inService = false;
2337        if (hasActivity) {
2338            // Process has activities, put it at the very tipsy-top.
2339            addIndex = mLruProcesses.size();
2340            nextIndex = mLruProcessServiceStart;
2341            inActivity = true;
2342        } else if (hasService) {
2343            // Process has services, put it at the top of the service list.
2344            addIndex = mLruProcessActivityStart;
2345            nextIndex = mLruProcessServiceStart;
2346            inActivity = true;
2347            inService = true;
2348        } else  {
2349            // Process not otherwise of interest, it goes to the top of the non-service area.
2350            addIndex = mLruProcessServiceStart;
2351            if (client != null) {
2352                int clientIndex = mLruProcesses.lastIndexOf(client);
2353                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2354                        + app);
2355                if (clientIndex >= 0 && addIndex > clientIndex) {
2356                    addIndex = clientIndex;
2357                }
2358            }
2359            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2360        }
2361
2362        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2363                + mLruProcessActivityStart + "): " + app);
2364        */
2365
2366        if (lrui >= 0) {
2367            if (lrui < mLruProcessActivityStart) {
2368                mLruProcessActivityStart--;
2369            }
2370            if (lrui < mLruProcessServiceStart) {
2371                mLruProcessServiceStart--;
2372            }
2373            /*
2374            if (addIndex > lrui) {
2375                addIndex--;
2376            }
2377            if (nextIndex > lrui) {
2378                nextIndex--;
2379            }
2380            */
2381            mLruProcesses.remove(lrui);
2382        }
2383
2384        /*
2385        mLruProcesses.add(addIndex, app);
2386        if (inActivity) {
2387            mLruProcessActivityStart++;
2388        }
2389        if (inService) {
2390            mLruProcessActivityStart++;
2391        }
2392        */
2393
2394        int nextIndex;
2395        if (hasActivity) {
2396            final int N = mLruProcesses.size();
2397            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2398                // Process doesn't have activities, but has clients with
2399                // activities...  move it up, but one below the top (the top
2400                // should always have a real activity).
2401                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2402                mLruProcesses.add(N-1, app);
2403                // To keep it from spamming the LRU list (by making a bunch of clients),
2404                // we will push down any other entries owned by the app.
2405                final int uid = app.info.uid;
2406                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2407                    ProcessRecord subProc = mLruProcesses.get(i);
2408                    if (subProc.info.uid == uid) {
2409                        // We want to push this one down the list.  If the process after
2410                        // it is for the same uid, however, don't do so, because we don't
2411                        // want them internally to be re-ordered.
2412                        if (mLruProcesses.get(i-1).info.uid != uid) {
2413                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2414                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2415                            ProcessRecord tmp = mLruProcesses.get(i);
2416                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2417                            mLruProcesses.set(i-1, tmp);
2418                            i--;
2419                        }
2420                    } else {
2421                        // A gap, we can stop here.
2422                        break;
2423                    }
2424                }
2425            } else {
2426                // Process has activities, put it at the very tipsy-top.
2427                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2428                mLruProcesses.add(app);
2429            }
2430            nextIndex = mLruProcessServiceStart;
2431        } else if (hasService) {
2432            // Process has services, put it at the top of the service list.
2433            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2434            mLruProcesses.add(mLruProcessActivityStart, app);
2435            nextIndex = mLruProcessServiceStart;
2436            mLruProcessActivityStart++;
2437        } else  {
2438            // Process not otherwise of interest, it goes to the top of the non-service area.
2439            int index = mLruProcessServiceStart;
2440            if (client != null) {
2441                // If there is a client, don't allow the process to be moved up higher
2442                // in the list than that client.
2443                int clientIndex = mLruProcesses.lastIndexOf(client);
2444                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2445                        + " when updating " + app);
2446                if (clientIndex <= lrui) {
2447                    // Don't allow the client index restriction to push it down farther in the
2448                    // list than it already is.
2449                    clientIndex = lrui;
2450                }
2451                if (clientIndex >= 0 && index > clientIndex) {
2452                    index = clientIndex;
2453                }
2454            }
2455            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2456            mLruProcesses.add(index, app);
2457            nextIndex = index-1;
2458            mLruProcessActivityStart++;
2459            mLruProcessServiceStart++;
2460        }
2461
2462        // If the app is currently using a content provider or service,
2463        // bump those processes as well.
2464        for (int j=app.connections.size()-1; j>=0; j--) {
2465            ConnectionRecord cr = app.connections.valueAt(j);
2466            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2467                    && cr.binding.service.app != null
2468                    && cr.binding.service.app.lruSeq != mLruSeq
2469                    && !cr.binding.service.app.persistent) {
2470                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2471                        "service connection", cr, app);
2472            }
2473        }
2474        for (int j=app.conProviders.size()-1; j>=0; j--) {
2475            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2476            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2477                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2478                        "provider reference", cpr, app);
2479            }
2480        }
2481    }
2482
2483    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2484        if (uid == Process.SYSTEM_UID) {
2485            // The system gets to run in any process.  If there are multiple
2486            // processes with the same uid, just pick the first (this
2487            // should never happen).
2488            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2489            if (procs == null) return null;
2490            final int N = procs.size();
2491            for (int i = 0; i < N; i++) {
2492                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2493            }
2494        }
2495        ProcessRecord proc = mProcessNames.get(processName, uid);
2496        if (false && proc != null && !keepIfLarge
2497                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2498                && proc.lastCachedPss >= 4000) {
2499            // Turn this condition on to cause killing to happen regularly, for testing.
2500            if (proc.baseProcessTracker != null) {
2501                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2502            }
2503            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2504                    + "k from cached");
2505        } else if (proc != null && !keepIfLarge
2506                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2507                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2508            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2509            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2510                if (proc.baseProcessTracker != null) {
2511                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2512                }
2513                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2514                        + "k from cached");
2515            }
2516        }
2517        return proc;
2518    }
2519
2520    void ensurePackageDexOpt(String packageName) {
2521        IPackageManager pm = AppGlobals.getPackageManager();
2522        try {
2523            if (pm.performDexOpt(packageName)) {
2524                mDidDexOpt = true;
2525            }
2526        } catch (RemoteException e) {
2527        }
2528    }
2529
2530    boolean isNextTransitionForward() {
2531        int transit = mWindowManager.getPendingAppTransition();
2532        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2533                || transit == AppTransition.TRANSIT_TASK_OPEN
2534                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2535    }
2536
2537    final ProcessRecord startProcessLocked(String processName,
2538            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2539            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2540            boolean isolated, boolean keepIfLarge) {
2541        ProcessRecord app;
2542        if (!isolated) {
2543            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2544        } else {
2545            // If this is an isolated process, it can't re-use an existing process.
2546            app = null;
2547        }
2548        // We don't have to do anything more if:
2549        // (1) There is an existing application record; and
2550        // (2) The caller doesn't think it is dead, OR there is no thread
2551        //     object attached to it so we know it couldn't have crashed; and
2552        // (3) There is a pid assigned to it, so it is either starting or
2553        //     already running.
2554        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2555                + " app=" + app + " knownToBeDead=" + knownToBeDead
2556                + " thread=" + (app != null ? app.thread : null)
2557                + " pid=" + (app != null ? app.pid : -1));
2558        if (app != null && app.pid > 0) {
2559            if (!knownToBeDead || app.thread == null) {
2560                // We already have the app running, or are waiting for it to
2561                // come up (we have a pid but not yet its thread), so keep it.
2562                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2563                // If this is a new package in the process, add the package to the list
2564                app.addPackage(info.packageName, mProcessStats);
2565                return app;
2566            }
2567
2568            // An application record is attached to a previous process,
2569            // clean it up now.
2570            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2571            handleAppDiedLocked(app, true, true);
2572        }
2573
2574        String hostingNameStr = hostingName != null
2575                ? hostingName.flattenToShortString() : null;
2576
2577        if (!isolated) {
2578            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2579                // If we are in the background, then check to see if this process
2580                // is bad.  If so, we will just silently fail.
2581                if (mBadProcesses.get(info.processName, info.uid) != null) {
2582                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2583                            + "/" + info.processName);
2584                    return null;
2585                }
2586            } else {
2587                // When the user is explicitly starting a process, then clear its
2588                // crash count so that we won't make it bad until they see at
2589                // least one crash dialog again, and make the process good again
2590                // if it had been bad.
2591                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2592                        + "/" + info.processName);
2593                mProcessCrashTimes.remove(info.processName, info.uid);
2594                if (mBadProcesses.get(info.processName, info.uid) != null) {
2595                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2596                            UserHandle.getUserId(info.uid), info.uid,
2597                            info.processName);
2598                    mBadProcesses.remove(info.processName, info.uid);
2599                    if (app != null) {
2600                        app.bad = false;
2601                    }
2602                }
2603            }
2604        }
2605
2606        if (app == null) {
2607            app = newProcessRecordLocked(info, processName, isolated);
2608            if (app == null) {
2609                Slog.w(TAG, "Failed making new process record for "
2610                        + processName + "/" + info.uid + " isolated=" + isolated);
2611                return null;
2612            }
2613            mProcessNames.put(processName, app.uid, app);
2614            if (isolated) {
2615                mIsolatedProcesses.put(app.uid, app);
2616            }
2617        } else {
2618            // If this is a new package in the process, add the package to the list
2619            app.addPackage(info.packageName, mProcessStats);
2620        }
2621
2622        // If the system is not ready yet, then hold off on starting this
2623        // process until it is.
2624        if (!mProcessesReady
2625                && !isAllowedWhileBooting(info)
2626                && !allowWhileBooting) {
2627            if (!mProcessesOnHold.contains(app)) {
2628                mProcessesOnHold.add(app);
2629            }
2630            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2631            return app;
2632        }
2633
2634        startProcessLocked(app, hostingType, hostingNameStr);
2635        return (app.pid != 0) ? app : null;
2636    }
2637
2638    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2639        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2640    }
2641
2642    private final void startProcessLocked(ProcessRecord app,
2643            String hostingType, String hostingNameStr) {
2644        if (app.pid > 0 && app.pid != MY_PID) {
2645            synchronized (mPidsSelfLocked) {
2646                mPidsSelfLocked.remove(app.pid);
2647                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2648            }
2649            app.setPid(0);
2650        }
2651
2652        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2653                "startProcessLocked removing on hold: " + app);
2654        mProcessesOnHold.remove(app);
2655
2656        updateCpuStats();
2657
2658        try {
2659            int uid = app.uid;
2660
2661            int[] gids = null;
2662            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2663            if (!app.isolated) {
2664                int[] permGids = null;
2665                try {
2666                    final PackageManager pm = mContext.getPackageManager();
2667                    permGids = pm.getPackageGids(app.info.packageName);
2668
2669                    if (Environment.isExternalStorageEmulated()) {
2670                        if (pm.checkPermission(
2671                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2672                                app.info.packageName) == PERMISSION_GRANTED) {
2673                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2674                        } else {
2675                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2676                        }
2677                    }
2678                } catch (PackageManager.NameNotFoundException e) {
2679                    Slog.w(TAG, "Unable to retrieve gids", e);
2680                }
2681
2682                /*
2683                 * Add shared application GID so applications can share some
2684                 * resources like shared libraries
2685                 */
2686                if (permGids == null) {
2687                    gids = new int[1];
2688                } else {
2689                    gids = new int[permGids.length + 1];
2690                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2691                }
2692                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2693            }
2694            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2695                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2696                        && mTopComponent != null
2697                        && app.processName.equals(mTopComponent.getPackageName())) {
2698                    uid = 0;
2699                }
2700                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2701                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2702                    uid = 0;
2703                }
2704            }
2705            int debugFlags = 0;
2706            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2707                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2708                // Also turn on CheckJNI for debuggable apps. It's quite
2709                // awkward to turn on otherwise.
2710                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2711            }
2712            // Run the app in safe mode if its manifest requests so or the
2713            // system is booted in safe mode.
2714            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2715                Zygote.systemInSafeMode == true) {
2716                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2717            }
2718            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2719                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2720            }
2721            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2722                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2723            }
2724            if ("1".equals(SystemProperties.get("debug.assert"))) {
2725                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2726            }
2727
2728            // Start the process.  It will either succeed and return a result containing
2729            // the PID of the new process, or else throw a RuntimeException.
2730            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2731                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2732                    app.info.targetSdkVersion, app.info.seinfo, null);
2733
2734            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2735            synchronized (bs) {
2736                if (bs.isOnBattery()) {
2737                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2738                }
2739            }
2740
2741            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2742                    UserHandle.getUserId(uid), startResult.pid, uid,
2743                    app.processName, hostingType,
2744                    hostingNameStr != null ? hostingNameStr : "");
2745
2746            if (app.persistent) {
2747                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2748            }
2749
2750            StringBuilder buf = mStringBuilder;
2751            buf.setLength(0);
2752            buf.append("Start proc ");
2753            buf.append(app.processName);
2754            buf.append(" for ");
2755            buf.append(hostingType);
2756            if (hostingNameStr != null) {
2757                buf.append(" ");
2758                buf.append(hostingNameStr);
2759            }
2760            buf.append(": pid=");
2761            buf.append(startResult.pid);
2762            buf.append(" uid=");
2763            buf.append(uid);
2764            buf.append(" gids={");
2765            if (gids != null) {
2766                for (int gi=0; gi<gids.length; gi++) {
2767                    if (gi != 0) buf.append(", ");
2768                    buf.append(gids[gi]);
2769
2770                }
2771            }
2772            buf.append("}");
2773            Slog.i(TAG, buf.toString());
2774            app.setPid(startResult.pid);
2775            app.usingWrapper = startResult.usingWrapper;
2776            app.removed = false;
2777            synchronized (mPidsSelfLocked) {
2778                this.mPidsSelfLocked.put(startResult.pid, app);
2779                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2780                msg.obj = app;
2781                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2782                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2783            }
2784            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2785                    app.processName, app.info.uid);
2786            if (app.isolated) {
2787                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2788            }
2789        } catch (RuntimeException e) {
2790            // XXX do better error recovery.
2791            app.setPid(0);
2792            Slog.e(TAG, "Failure starting process " + app.processName, e);
2793        }
2794    }
2795
2796    void updateUsageStats(ActivityRecord component, boolean resumed) {
2797        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2798        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2799        if (resumed) {
2800            mUsageStatsService.noteResumeComponent(component.realActivity);
2801            synchronized (stats) {
2802                stats.noteActivityResumedLocked(component.app.uid);
2803            }
2804        } else {
2805            mUsageStatsService.notePauseComponent(component.realActivity);
2806            synchronized (stats) {
2807                stats.noteActivityPausedLocked(component.app.uid);
2808            }
2809        }
2810    }
2811
2812    Intent getHomeIntent() {
2813        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2814        intent.setComponent(mTopComponent);
2815        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2816            intent.addCategory(Intent.CATEGORY_HOME);
2817        }
2818        return intent;
2819    }
2820
2821    boolean startHomeActivityLocked(int userId) {
2822        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2823                && mTopAction == null) {
2824            // We are running in factory test mode, but unable to find
2825            // the factory test app, so just sit around displaying the
2826            // error message and don't try to start anything.
2827            return false;
2828        }
2829        Intent intent = getHomeIntent();
2830        ActivityInfo aInfo =
2831            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2832        if (aInfo != null) {
2833            intent.setComponent(new ComponentName(
2834                    aInfo.applicationInfo.packageName, aInfo.name));
2835            // Don't do this if the home app is currently being
2836            // instrumented.
2837            aInfo = new ActivityInfo(aInfo);
2838            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2839            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2840                    aInfo.applicationInfo.uid, true);
2841            if (app == null || app.instrumentationClass == null) {
2842                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2843                mStackSupervisor.startHomeActivity(intent, aInfo);
2844            }
2845        }
2846
2847        return true;
2848    }
2849
2850    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2851        ActivityInfo ai = null;
2852        ComponentName comp = intent.getComponent();
2853        try {
2854            if (comp != null) {
2855                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2856            } else {
2857                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2858                        intent,
2859                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2860                            flags, userId);
2861
2862                if (info != null) {
2863                    ai = info.activityInfo;
2864                }
2865            }
2866        } catch (RemoteException e) {
2867            // ignore
2868        }
2869
2870        return ai;
2871    }
2872
2873    /**
2874     * Starts the "new version setup screen" if appropriate.
2875     */
2876    void startSetupActivityLocked() {
2877        // Only do this once per boot.
2878        if (mCheckedForSetup) {
2879            return;
2880        }
2881
2882        // We will show this screen if the current one is a different
2883        // version than the last one shown, and we are not running in
2884        // low-level factory test mode.
2885        final ContentResolver resolver = mContext.getContentResolver();
2886        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2887                Settings.Global.getInt(resolver,
2888                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2889            mCheckedForSetup = true;
2890
2891            // See if we should be showing the platform update setup UI.
2892            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2893            List<ResolveInfo> ris = mContext.getPackageManager()
2894                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2895
2896            // We don't allow third party apps to replace this.
2897            ResolveInfo ri = null;
2898            for (int i=0; ris != null && i<ris.size(); i++) {
2899                if ((ris.get(i).activityInfo.applicationInfo.flags
2900                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2901                    ri = ris.get(i);
2902                    break;
2903                }
2904            }
2905
2906            if (ri != null) {
2907                String vers = ri.activityInfo.metaData != null
2908                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2909                        : null;
2910                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2911                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2912                            Intent.METADATA_SETUP_VERSION);
2913                }
2914                String lastVers = Settings.Secure.getString(
2915                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2916                if (vers != null && !vers.equals(lastVers)) {
2917                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2918                    intent.setComponent(new ComponentName(
2919                            ri.activityInfo.packageName, ri.activityInfo.name));
2920                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2921                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2922                }
2923            }
2924        }
2925    }
2926
2927    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2928        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2929    }
2930
2931    void enforceNotIsolatedCaller(String caller) {
2932        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2933            throw new SecurityException("Isolated process not allowed to call " + caller);
2934        }
2935    }
2936
2937    @Override
2938    public int getFrontActivityScreenCompatMode() {
2939        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2940        synchronized (this) {
2941            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2942        }
2943    }
2944
2945    @Override
2946    public void setFrontActivityScreenCompatMode(int mode) {
2947        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2948                "setFrontActivityScreenCompatMode");
2949        synchronized (this) {
2950            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2951        }
2952    }
2953
2954    @Override
2955    public int getPackageScreenCompatMode(String packageName) {
2956        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2957        synchronized (this) {
2958            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2959        }
2960    }
2961
2962    @Override
2963    public void setPackageScreenCompatMode(String packageName, int mode) {
2964        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2965                "setPackageScreenCompatMode");
2966        synchronized (this) {
2967            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2968        }
2969    }
2970
2971    @Override
2972    public boolean getPackageAskScreenCompat(String packageName) {
2973        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2974        synchronized (this) {
2975            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2976        }
2977    }
2978
2979    @Override
2980    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2981        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2982                "setPackageAskScreenCompat");
2983        synchronized (this) {
2984            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2985        }
2986    }
2987
2988    private void dispatchProcessesChanged() {
2989        int N;
2990        synchronized (this) {
2991            N = mPendingProcessChanges.size();
2992            if (mActiveProcessChanges.length < N) {
2993                mActiveProcessChanges = new ProcessChangeItem[N];
2994            }
2995            mPendingProcessChanges.toArray(mActiveProcessChanges);
2996            mAvailProcessChanges.addAll(mPendingProcessChanges);
2997            mPendingProcessChanges.clear();
2998            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2999        }
3000
3001        int i = mProcessObservers.beginBroadcast();
3002        while (i > 0) {
3003            i--;
3004            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3005            if (observer != null) {
3006                try {
3007                    for (int j=0; j<N; j++) {
3008                        ProcessChangeItem item = mActiveProcessChanges[j];
3009                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3010                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3011                                    + item.pid + " uid=" + item.uid + ": "
3012                                    + item.foregroundActivities);
3013                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3014                                    item.foregroundActivities);
3015                        }
3016                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3017                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3018                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3019                            observer.onImportanceChanged(item.pid, item.uid,
3020                                    item.importance);
3021                        }
3022                    }
3023                } catch (RemoteException e) {
3024                }
3025            }
3026        }
3027        mProcessObservers.finishBroadcast();
3028    }
3029
3030    private void dispatchProcessDied(int pid, int uid) {
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                    observer.onProcessDied(pid, uid);
3038                } catch (RemoteException e) {
3039                }
3040            }
3041        }
3042        mProcessObservers.finishBroadcast();
3043    }
3044
3045    final void doPendingActivityLaunchesLocked(boolean doResume) {
3046        final int N = mPendingActivityLaunches.size();
3047        if (N <= 0) {
3048            return;
3049        }
3050        for (int i=0; i<N; i++) {
3051            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3052            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3053                    doResume && i == (N-1), null);
3054        }
3055        mPendingActivityLaunches.clear();
3056    }
3057
3058    @Override
3059    public final int startActivity(IApplicationThread caller, String callingPackage,
3060            Intent intent, String resolvedType, IBinder resultTo,
3061            String resultWho, int requestCode, int startFlags,
3062            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3063        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3064                resultWho, requestCode,
3065                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3066    }
3067
3068    @Override
3069    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3070            Intent intent, String resolvedType, IBinder resultTo,
3071            String resultWho, int requestCode, int startFlags,
3072            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3073        enforceNotIsolatedCaller("startActivity");
3074        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3075                false, true, "startActivity", null);
3076        // TODO: Switch to user app stacks here.
3077        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3078                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3079                null, null, options, userId, null);
3080    }
3081
3082    @Override
3083    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3084            Intent intent, String resolvedType, IBinder resultTo,
3085            String resultWho, int requestCode, int startFlags, String profileFile,
3086            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3087        enforceNotIsolatedCaller("startActivityAndWait");
3088        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3089                false, true, "startActivityAndWait", null);
3090        WaitResult res = new WaitResult();
3091        // TODO: Switch to user app stacks here.
3092        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3093                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3094                res, null, options, UserHandle.getCallingUserId(), null);
3095        return res;
3096    }
3097
3098    @Override
3099    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3100            Intent intent, String resolvedType, IBinder resultTo,
3101            String resultWho, int requestCode, int startFlags, Configuration config,
3102            Bundle options, int userId) {
3103        enforceNotIsolatedCaller("startActivityWithConfig");
3104        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3105                false, true, "startActivityWithConfig", null);
3106        // TODO: Switch to user app stacks here.
3107        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3108                resolvedType, resultTo, resultWho, requestCode, startFlags,
3109                null, null, null, config, options, userId, null);
3110        return ret;
3111    }
3112
3113    @Override
3114    public int startActivityIntentSender(IApplicationThread caller,
3115            IntentSender intent, Intent fillInIntent, String resolvedType,
3116            IBinder resultTo, String resultWho, int requestCode,
3117            int flagsMask, int flagsValues, Bundle options) {
3118        enforceNotIsolatedCaller("startActivityIntentSender");
3119        // Refuse possible leaked file descriptors
3120        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3121            throw new IllegalArgumentException("File descriptors passed in Intent");
3122        }
3123
3124        IIntentSender sender = intent.getTarget();
3125        if (!(sender instanceof PendingIntentRecord)) {
3126            throw new IllegalArgumentException("Bad PendingIntent object");
3127        }
3128
3129        PendingIntentRecord pir = (PendingIntentRecord)sender;
3130
3131        synchronized (this) {
3132            // If this is coming from the currently resumed activity, it is
3133            // effectively saying that app switches are allowed at this point.
3134            final ActivityStack stack = getFocusedStack();
3135            if (stack.mResumedActivity != null &&
3136                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3137                mAppSwitchesAllowedTime = 0;
3138            }
3139        }
3140        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3141                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3142        return ret;
3143    }
3144
3145    @Override
3146    public boolean startNextMatchingActivity(IBinder callingActivity,
3147            Intent intent, Bundle options) {
3148        // Refuse possible leaked file descriptors
3149        if (intent != null && intent.hasFileDescriptors() == true) {
3150            throw new IllegalArgumentException("File descriptors passed in Intent");
3151        }
3152
3153        synchronized (this) {
3154            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3155            if (r == null) {
3156                ActivityOptions.abort(options);
3157                return false;
3158            }
3159            if (r.app == null || r.app.thread == null) {
3160                // The caller is not running...  d'oh!
3161                ActivityOptions.abort(options);
3162                return false;
3163            }
3164            intent = new Intent(intent);
3165            // The caller is not allowed to change the data.
3166            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3167            // And we are resetting to find the next component...
3168            intent.setComponent(null);
3169
3170            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3171
3172            ActivityInfo aInfo = null;
3173            try {
3174                List<ResolveInfo> resolves =
3175                    AppGlobals.getPackageManager().queryIntentActivities(
3176                            intent, r.resolvedType,
3177                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3178                            UserHandle.getCallingUserId());
3179
3180                // Look for the original activity in the list...
3181                final int N = resolves != null ? resolves.size() : 0;
3182                for (int i=0; i<N; i++) {
3183                    ResolveInfo rInfo = resolves.get(i);
3184                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3185                            && rInfo.activityInfo.name.equals(r.info.name)) {
3186                        // We found the current one...  the next matching is
3187                        // after it.
3188                        i++;
3189                        if (i<N) {
3190                            aInfo = resolves.get(i).activityInfo;
3191                        }
3192                        if (debug) {
3193                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3194                                    + "/" + r.info.name);
3195                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3196                                    + "/" + aInfo.name);
3197                        }
3198                        break;
3199                    }
3200                }
3201            } catch (RemoteException e) {
3202            }
3203
3204            if (aInfo == null) {
3205                // Nobody who is next!
3206                ActivityOptions.abort(options);
3207                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3208                return false;
3209            }
3210
3211            intent.setComponent(new ComponentName(
3212                    aInfo.applicationInfo.packageName, aInfo.name));
3213            intent.setFlags(intent.getFlags()&~(
3214                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3215                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3216                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3217                    Intent.FLAG_ACTIVITY_NEW_TASK));
3218
3219            // Okay now we need to start the new activity, replacing the
3220            // currently running activity.  This is a little tricky because
3221            // we want to start the new one as if the current one is finished,
3222            // but not finish the current one first so that there is no flicker.
3223            // And thus...
3224            final boolean wasFinishing = r.finishing;
3225            r.finishing = true;
3226
3227            // Propagate reply information over to the new activity.
3228            final ActivityRecord resultTo = r.resultTo;
3229            final String resultWho = r.resultWho;
3230            final int requestCode = r.requestCode;
3231            r.resultTo = null;
3232            if (resultTo != null) {
3233                resultTo.removeResultsLocked(r, resultWho, requestCode);
3234            }
3235
3236            final long origId = Binder.clearCallingIdentity();
3237            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3238                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3239                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3240                    options, false, null, null);
3241            Binder.restoreCallingIdentity(origId);
3242
3243            r.finishing = wasFinishing;
3244            if (res != ActivityManager.START_SUCCESS) {
3245                return false;
3246            }
3247            return true;
3248        }
3249    }
3250
3251    final int startActivityInPackage(int uid, String callingPackage,
3252            Intent intent, String resolvedType, IBinder resultTo,
3253            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3254                    IActivityContainer container) {
3255
3256        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3257                false, true, "startActivityInPackage", null);
3258
3259        // TODO: Switch to user app stacks here.
3260        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3261                resultTo, resultWho, requestCode, startFlags,
3262                null, null, null, null, options, userId, container);
3263        return ret;
3264    }
3265
3266    @Override
3267    public final int startActivities(IApplicationThread caller, String callingPackage,
3268            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3269            int userId) {
3270        enforceNotIsolatedCaller("startActivities");
3271        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3272                false, true, "startActivity", null);
3273        // TODO: Switch to user app stacks here.
3274        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3275                resolvedTypes, resultTo, options, userId);
3276        return ret;
3277    }
3278
3279    final int startActivitiesInPackage(int uid, String callingPackage,
3280            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3281            Bundle options, int userId) {
3282
3283        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3284                false, true, "startActivityInPackage", null);
3285        // TODO: Switch to user app stacks here.
3286        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3287                resultTo, options, userId);
3288        return ret;
3289    }
3290
3291    final void addRecentTaskLocked(TaskRecord task) {
3292        int N = mRecentTasks.size();
3293        // Quick case: check if the top-most recent task is the same.
3294        if (N > 0 && mRecentTasks.get(0) == task) {
3295            return;
3296        }
3297        // Remove any existing entries that are the same kind of task.
3298        for (int i=0; i<N; i++) {
3299            TaskRecord tr = mRecentTasks.get(i);
3300            if (task.userId == tr.userId
3301                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3302                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3303                tr.disposeThumbnail();
3304                mRecentTasks.remove(i);
3305                i--;
3306                N--;
3307                if (task.intent == null) {
3308                    // If the new recent task we are adding is not fully
3309                    // specified, then replace it with the existing recent task.
3310                    task = tr;
3311                }
3312            }
3313        }
3314        if (N >= MAX_RECENT_TASKS) {
3315            mRecentTasks.remove(N-1).disposeThumbnail();
3316        }
3317        mRecentTasks.add(0, task);
3318    }
3319
3320    @Override
3321    public void reportActivityFullyDrawn(IBinder token) {
3322        synchronized (this) {
3323            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3324            if (r == null) {
3325                return;
3326            }
3327            r.reportFullyDrawnLocked();
3328        }
3329    }
3330
3331    @Override
3332    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3333        synchronized (this) {
3334            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3335            if (r == null) {
3336                return;
3337            }
3338            final long origId = Binder.clearCallingIdentity();
3339            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3340            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3341                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3342            if (config != null) {
3343                r.frozenBeforeDestroy = true;
3344                if (!updateConfigurationLocked(config, r, false, false)) {
3345                    mStackSupervisor.resumeTopActivitiesLocked();
3346                }
3347            }
3348            Binder.restoreCallingIdentity(origId);
3349        }
3350    }
3351
3352    @Override
3353    public int getRequestedOrientation(IBinder token) {
3354        synchronized (this) {
3355            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3356            if (r == null) {
3357                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3358            }
3359            return mWindowManager.getAppOrientation(r.appToken);
3360        }
3361    }
3362
3363    /**
3364     * This is the internal entry point for handling Activity.finish().
3365     *
3366     * @param token The Binder token referencing the Activity we want to finish.
3367     * @param resultCode Result code, if any, from this Activity.
3368     * @param resultData Result data (Intent), if any, from this Activity.
3369     *
3370     * @return Returns true if the activity successfully finished, or false if it is still running.
3371     */
3372    @Override
3373    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3374        // Refuse possible leaked file descriptors
3375        if (resultData != null && resultData.hasFileDescriptors() == true) {
3376            throw new IllegalArgumentException("File descriptors passed in Intent");
3377        }
3378
3379        synchronized(this) {
3380            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3381            if (r == null) {
3382                return true;
3383            }
3384            if (mController != null) {
3385                // Find the first activity that is not finishing.
3386                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3387                if (next != null) {
3388                    // ask watcher if this is allowed
3389                    boolean resumeOK = true;
3390                    try {
3391                        resumeOK = mController.activityResuming(next.packageName);
3392                    } catch (RemoteException e) {
3393                        mController = null;
3394                        Watchdog.getInstance().setActivityController(null);
3395                    }
3396
3397                    if (!resumeOK) {
3398                        return false;
3399                    }
3400                }
3401            }
3402            final long origId = Binder.clearCallingIdentity();
3403            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3404                    resultData, "app-request", true);
3405            Binder.restoreCallingIdentity(origId);
3406            return res;
3407        }
3408    }
3409
3410    @Override
3411    public final void finishHeavyWeightApp() {
3412        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3413                != PackageManager.PERMISSION_GRANTED) {
3414            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3415                    + Binder.getCallingPid()
3416                    + ", uid=" + Binder.getCallingUid()
3417                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3418            Slog.w(TAG, msg);
3419            throw new SecurityException(msg);
3420        }
3421
3422        synchronized(this) {
3423            if (mHeavyWeightProcess == null) {
3424                return;
3425            }
3426
3427            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3428                    mHeavyWeightProcess.activities);
3429            for (int i=0; i<activities.size(); i++) {
3430                ActivityRecord r = activities.get(i);
3431                if (!r.finishing) {
3432                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3433                            null, "finish-heavy", true);
3434                }
3435            }
3436
3437            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3438                    mHeavyWeightProcess.userId, 0));
3439            mHeavyWeightProcess = null;
3440        }
3441    }
3442
3443    @Override
3444    public void crashApplication(int uid, int initialPid, String packageName,
3445            String message) {
3446        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3447                != PackageManager.PERMISSION_GRANTED) {
3448            String msg = "Permission Denial: crashApplication() from pid="
3449                    + Binder.getCallingPid()
3450                    + ", uid=" + Binder.getCallingUid()
3451                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3452            Slog.w(TAG, msg);
3453            throw new SecurityException(msg);
3454        }
3455
3456        synchronized(this) {
3457            ProcessRecord proc = null;
3458
3459            // Figure out which process to kill.  We don't trust that initialPid
3460            // still has any relation to current pids, so must scan through the
3461            // list.
3462            synchronized (mPidsSelfLocked) {
3463                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3464                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3465                    if (p.uid != uid) {
3466                        continue;
3467                    }
3468                    if (p.pid == initialPid) {
3469                        proc = p;
3470                        break;
3471                    }
3472                    if (p.pkgList.containsKey(packageName)) {
3473                        proc = p;
3474                    }
3475                }
3476            }
3477
3478            if (proc == null) {
3479                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3480                        + " initialPid=" + initialPid
3481                        + " packageName=" + packageName);
3482                return;
3483            }
3484
3485            if (proc.thread != null) {
3486                if (proc.pid == Process.myPid()) {
3487                    Log.w(TAG, "crashApplication: trying to crash self!");
3488                    return;
3489                }
3490                long ident = Binder.clearCallingIdentity();
3491                try {
3492                    proc.thread.scheduleCrash(message);
3493                } catch (RemoteException e) {
3494                }
3495                Binder.restoreCallingIdentity(ident);
3496            }
3497        }
3498    }
3499
3500    @Override
3501    public final void finishSubActivity(IBinder token, String resultWho,
3502            int requestCode) {
3503        synchronized(this) {
3504            final long origId = Binder.clearCallingIdentity();
3505            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3506            if (r != null) {
3507                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3508            }
3509            Binder.restoreCallingIdentity(origId);
3510        }
3511    }
3512
3513    @Override
3514    public boolean finishActivityAffinity(IBinder token) {
3515        synchronized(this) {
3516            final long origId = Binder.clearCallingIdentity();
3517            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3518            boolean res = false;
3519            if (r != null) {
3520                res = r.task.stack.finishActivityAffinityLocked(r);
3521            }
3522            Binder.restoreCallingIdentity(origId);
3523            return res;
3524        }
3525    }
3526
3527    @Override
3528    public boolean willActivityBeVisible(IBinder token) {
3529        synchronized(this) {
3530            ActivityStack stack = ActivityRecord.getStackLocked(token);
3531            if (stack != null) {
3532                return stack.willActivityBeVisibleLocked(token);
3533            }
3534            return false;
3535        }
3536    }
3537
3538    @Override
3539    public void overridePendingTransition(IBinder token, String packageName,
3540            int enterAnim, int exitAnim) {
3541        synchronized(this) {
3542            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3543            if (self == null) {
3544                return;
3545            }
3546
3547            final long origId = Binder.clearCallingIdentity();
3548
3549            if (self.state == ActivityState.RESUMED
3550                    || self.state == ActivityState.PAUSING) {
3551                mWindowManager.overridePendingAppTransition(packageName,
3552                        enterAnim, exitAnim, null);
3553            }
3554
3555            Binder.restoreCallingIdentity(origId);
3556        }
3557    }
3558
3559    /**
3560     * Main function for removing an existing process from the activity manager
3561     * as a result of that process going away.  Clears out all connections
3562     * to the process.
3563     */
3564    private final void handleAppDiedLocked(ProcessRecord app,
3565            boolean restarting, boolean allowRestart) {
3566        int pid = app.pid;
3567        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3568        if (!restarting) {
3569            removeLruProcessLocked(app);
3570            if (pid > 0) {
3571                ProcessList.remove(pid);
3572            }
3573        }
3574
3575        if (mProfileProc == app) {
3576            clearProfilerLocked();
3577        }
3578
3579        // Remove this application's activities from active lists.
3580        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3581
3582        app.activities.clear();
3583
3584        if (app.instrumentationClass != null) {
3585            Slog.w(TAG, "Crash of app " + app.processName
3586                  + " running instrumentation " + app.instrumentationClass);
3587            Bundle info = new Bundle();
3588            info.putString("shortMsg", "Process crashed.");
3589            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3590        }
3591
3592        if (!restarting) {
3593            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3594                // If there was nothing to resume, and we are not already
3595                // restarting this process, but there is a visible activity that
3596                // is hosted by the process...  then make sure all visible
3597                // activities are running, taking care of restarting this
3598                // process.
3599                if (hasVisibleActivities) {
3600                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3601                }
3602            }
3603        }
3604    }
3605
3606    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3607        IBinder threadBinder = thread.asBinder();
3608        // Find the application record.
3609        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3610            ProcessRecord rec = mLruProcesses.get(i);
3611            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3612                return i;
3613            }
3614        }
3615        return -1;
3616    }
3617
3618    final ProcessRecord getRecordForAppLocked(
3619            IApplicationThread thread) {
3620        if (thread == null) {
3621            return null;
3622        }
3623
3624        int appIndex = getLRURecordIndexForAppLocked(thread);
3625        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3626    }
3627
3628    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3629        // If there are no longer any background processes running,
3630        // and the app that died was not running instrumentation,
3631        // then tell everyone we are now low on memory.
3632        boolean haveBg = false;
3633        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3634            ProcessRecord rec = mLruProcesses.get(i);
3635            if (rec.thread != null
3636                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3637                haveBg = true;
3638                break;
3639            }
3640        }
3641
3642        if (!haveBg) {
3643            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3644            if (doReport) {
3645                long now = SystemClock.uptimeMillis();
3646                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3647                    doReport = false;
3648                } else {
3649                    mLastMemUsageReportTime = now;
3650                }
3651            }
3652            final ArrayList<ProcessMemInfo> memInfos
3653                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3654            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3655            long now = SystemClock.uptimeMillis();
3656            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3657                ProcessRecord rec = mLruProcesses.get(i);
3658                if (rec == dyingProc || rec.thread == null) {
3659                    continue;
3660                }
3661                if (doReport) {
3662                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3663                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3664                }
3665                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3666                    // The low memory report is overriding any current
3667                    // state for a GC request.  Make sure to do
3668                    // heavy/important/visible/foreground processes first.
3669                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3670                        rec.lastRequestedGc = 0;
3671                    } else {
3672                        rec.lastRequestedGc = rec.lastLowMemory;
3673                    }
3674                    rec.reportLowMemory = true;
3675                    rec.lastLowMemory = now;
3676                    mProcessesToGc.remove(rec);
3677                    addProcessToGcListLocked(rec);
3678                }
3679            }
3680            if (doReport) {
3681                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3682                mHandler.sendMessage(msg);
3683            }
3684            scheduleAppGcsLocked();
3685        }
3686    }
3687
3688    final void appDiedLocked(ProcessRecord app, int pid,
3689            IApplicationThread thread) {
3690
3691        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3692        synchronized (stats) {
3693            stats.noteProcessDiedLocked(app.info.uid, pid);
3694        }
3695
3696        // Clean up already done if the process has been re-started.
3697        if (app.pid == pid && app.thread != null &&
3698                app.thread.asBinder() == thread.asBinder()) {
3699            boolean doLowMem = app.instrumentationClass == null;
3700            boolean doOomAdj = doLowMem;
3701            if (!app.killedByAm) {
3702                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3703                        + ") has died.");
3704                mAllowLowerMemLevel = true;
3705            } else {
3706                // Note that we always want to do oom adj to update our state with the
3707                // new number of procs.
3708                mAllowLowerMemLevel = false;
3709                doLowMem = false;
3710            }
3711            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3712            if (DEBUG_CLEANUP) Slog.v(
3713                TAG, "Dying app: " + app + ", pid: " + pid
3714                + ", thread: " + thread.asBinder());
3715            handleAppDiedLocked(app, false, true);
3716
3717            if (doOomAdj) {
3718                updateOomAdjLocked();
3719            }
3720            if (doLowMem) {
3721                doLowMemReportIfNeededLocked(app);
3722            }
3723        } else if (app.pid != pid) {
3724            // A new process has already been started.
3725            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3726                    + ") has died and restarted (pid " + app.pid + ").");
3727            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3728        } else if (DEBUG_PROCESSES) {
3729            Slog.d(TAG, "Received spurious death notification for thread "
3730                    + thread.asBinder());
3731        }
3732    }
3733
3734    /**
3735     * If a stack trace dump file is configured, dump process stack traces.
3736     * @param clearTraces causes the dump file to be erased prior to the new
3737     *    traces being written, if true; when false, the new traces will be
3738     *    appended to any existing file content.
3739     * @param firstPids of dalvik VM processes to dump stack traces for first
3740     * @param lastPids of dalvik VM processes to dump stack traces for last
3741     * @param nativeProcs optional list of native process names to dump stack crawls
3742     * @return file containing stack traces, or null if no dump file is configured
3743     */
3744    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3745            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3746        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3747        if (tracesPath == null || tracesPath.length() == 0) {
3748            return null;
3749        }
3750
3751        File tracesFile = new File(tracesPath);
3752        try {
3753            File tracesDir = tracesFile.getParentFile();
3754            if (!tracesDir.exists()) {
3755                tracesFile.mkdirs();
3756                if (!SELinux.restorecon(tracesDir)) {
3757                    return null;
3758                }
3759            }
3760            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3761
3762            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3763            tracesFile.createNewFile();
3764            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3765        } catch (IOException e) {
3766            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3767            return null;
3768        }
3769
3770        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3771        return tracesFile;
3772    }
3773
3774    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3775            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3776        // Use a FileObserver to detect when traces finish writing.
3777        // The order of traces is considered important to maintain for legibility.
3778        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3779            @Override
3780            public synchronized void onEvent(int event, String path) { notify(); }
3781        };
3782
3783        try {
3784            observer.startWatching();
3785
3786            // First collect all of the stacks of the most important pids.
3787            if (firstPids != null) {
3788                try {
3789                    int num = firstPids.size();
3790                    for (int i = 0; i < num; i++) {
3791                        synchronized (observer) {
3792                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3793                            observer.wait(200);  // Wait for write-close, give up after 200msec
3794                        }
3795                    }
3796                } catch (InterruptedException e) {
3797                    Log.wtf(TAG, e);
3798                }
3799            }
3800
3801            // Next collect the stacks of the native pids
3802            if (nativeProcs != null) {
3803                int[] pids = Process.getPidsForCommands(nativeProcs);
3804                if (pids != null) {
3805                    for (int pid : pids) {
3806                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3807                    }
3808                }
3809            }
3810
3811            // Lastly, measure CPU usage.
3812            if (processCpuTracker != null) {
3813                processCpuTracker.init();
3814                System.gc();
3815                processCpuTracker.update();
3816                try {
3817                    synchronized (processCpuTracker) {
3818                        processCpuTracker.wait(500); // measure over 1/2 second.
3819                    }
3820                } catch (InterruptedException e) {
3821                }
3822                processCpuTracker.update();
3823
3824                // We'll take the stack crawls of just the top apps using CPU.
3825                final int N = processCpuTracker.countWorkingStats();
3826                int numProcs = 0;
3827                for (int i=0; i<N && numProcs<5; i++) {
3828                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3829                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3830                        numProcs++;
3831                        try {
3832                            synchronized (observer) {
3833                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3834                                observer.wait(200);  // Wait for write-close, give up after 200msec
3835                            }
3836                        } catch (InterruptedException e) {
3837                            Log.wtf(TAG, e);
3838                        }
3839
3840                    }
3841                }
3842            }
3843        } finally {
3844            observer.stopWatching();
3845        }
3846    }
3847
3848    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3849        if (true || IS_USER_BUILD) {
3850            return;
3851        }
3852        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3853        if (tracesPath == null || tracesPath.length() == 0) {
3854            return;
3855        }
3856
3857        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3858        StrictMode.allowThreadDiskWrites();
3859        try {
3860            final File tracesFile = new File(tracesPath);
3861            final File tracesDir = tracesFile.getParentFile();
3862            final File tracesTmp = new File(tracesDir, "__tmp__");
3863            try {
3864                if (!tracesDir.exists()) {
3865                    tracesFile.mkdirs();
3866                    if (!SELinux.restorecon(tracesDir.getPath())) {
3867                        return;
3868                    }
3869                }
3870                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3871
3872                if (tracesFile.exists()) {
3873                    tracesTmp.delete();
3874                    tracesFile.renameTo(tracesTmp);
3875                }
3876                StringBuilder sb = new StringBuilder();
3877                Time tobj = new Time();
3878                tobj.set(System.currentTimeMillis());
3879                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3880                sb.append(": ");
3881                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3882                sb.append(" since ");
3883                sb.append(msg);
3884                FileOutputStream fos = new FileOutputStream(tracesFile);
3885                fos.write(sb.toString().getBytes());
3886                if (app == null) {
3887                    fos.write("\n*** No application process!".getBytes());
3888                }
3889                fos.close();
3890                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3891            } catch (IOException e) {
3892                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3893                return;
3894            }
3895
3896            if (app != null) {
3897                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3898                firstPids.add(app.pid);
3899                dumpStackTraces(tracesPath, firstPids, null, null, null);
3900            }
3901
3902            File lastTracesFile = null;
3903            File curTracesFile = null;
3904            for (int i=9; i>=0; i--) {
3905                String name = String.format(Locale.US, "slow%02d.txt", i);
3906                curTracesFile = new File(tracesDir, name);
3907                if (curTracesFile.exists()) {
3908                    if (lastTracesFile != null) {
3909                        curTracesFile.renameTo(lastTracesFile);
3910                    } else {
3911                        curTracesFile.delete();
3912                    }
3913                }
3914                lastTracesFile = curTracesFile;
3915            }
3916            tracesFile.renameTo(curTracesFile);
3917            if (tracesTmp.exists()) {
3918                tracesTmp.renameTo(tracesFile);
3919            }
3920        } finally {
3921            StrictMode.setThreadPolicy(oldPolicy);
3922        }
3923    }
3924
3925    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3926            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3927        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3928        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3929
3930        if (mController != null) {
3931            try {
3932                // 0 == continue, -1 = kill process immediately
3933                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3934                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3935            } catch (RemoteException e) {
3936                mController = null;
3937                Watchdog.getInstance().setActivityController(null);
3938            }
3939        }
3940
3941        long anrTime = SystemClock.uptimeMillis();
3942        if (MONITOR_CPU_USAGE) {
3943            updateCpuStatsNow();
3944        }
3945
3946        synchronized (this) {
3947            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3948            if (mShuttingDown) {
3949                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3950                return;
3951            } else if (app.notResponding) {
3952                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3953                return;
3954            } else if (app.crashing) {
3955                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3956                return;
3957            }
3958
3959            // In case we come through here for the same app before completing
3960            // this one, mark as anring now so we will bail out.
3961            app.notResponding = true;
3962
3963            // Log the ANR to the event log.
3964            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3965                    app.processName, app.info.flags, annotation);
3966
3967            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3968            firstPids.add(app.pid);
3969
3970            int parentPid = app.pid;
3971            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3972            if (parentPid != app.pid) firstPids.add(parentPid);
3973
3974            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3975
3976            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3977                ProcessRecord r = mLruProcesses.get(i);
3978                if (r != null && r.thread != null) {
3979                    int pid = r.pid;
3980                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3981                        if (r.persistent) {
3982                            firstPids.add(pid);
3983                        } else {
3984                            lastPids.put(pid, Boolean.TRUE);
3985                        }
3986                    }
3987                }
3988            }
3989        }
3990
3991        // Log the ANR to the main log.
3992        StringBuilder info = new StringBuilder();
3993        info.setLength(0);
3994        info.append("ANR in ").append(app.processName);
3995        if (activity != null && activity.shortComponentName != null) {
3996            info.append(" (").append(activity.shortComponentName).append(")");
3997        }
3998        info.append("\n");
3999        info.append("PID: ").append(app.pid).append("\n");
4000        if (annotation != null) {
4001            info.append("Reason: ").append(annotation).append("\n");
4002        }
4003        if (parent != null && parent != activity) {
4004            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4005        }
4006
4007        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4008
4009        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4010                NATIVE_STACKS_OF_INTEREST);
4011
4012        String cpuInfo = null;
4013        if (MONITOR_CPU_USAGE) {
4014            updateCpuStatsNow();
4015            synchronized (mProcessCpuThread) {
4016                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4017            }
4018            info.append(processCpuTracker.printCurrentLoad());
4019            info.append(cpuInfo);
4020        }
4021
4022        info.append(processCpuTracker.printCurrentState(anrTime));
4023
4024        Slog.e(TAG, info.toString());
4025        if (tracesFile == null) {
4026            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4027            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4028        }
4029
4030        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4031                cpuInfo, tracesFile, null);
4032
4033        if (mController != null) {
4034            try {
4035                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4036                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4037                if (res != 0) {
4038                    if (res < 0 && app.pid != MY_PID) {
4039                        Process.killProcess(app.pid);
4040                    } else {
4041                        synchronized (this) {
4042                            mServices.scheduleServiceTimeoutLocked(app);
4043                        }
4044                    }
4045                    return;
4046                }
4047            } catch (RemoteException e) {
4048                mController = null;
4049                Watchdog.getInstance().setActivityController(null);
4050            }
4051        }
4052
4053        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4054        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4055                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4056
4057        synchronized (this) {
4058            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4059                killUnneededProcessLocked(app, "background ANR");
4060                return;
4061            }
4062
4063            // Set the app's notResponding state, and look up the errorReportReceiver
4064            makeAppNotRespondingLocked(app,
4065                    activity != null ? activity.shortComponentName : null,
4066                    annotation != null ? "ANR " + annotation : "ANR",
4067                    info.toString());
4068
4069            // Bring up the infamous App Not Responding dialog
4070            Message msg = Message.obtain();
4071            HashMap<String, Object> map = new HashMap<String, Object>();
4072            msg.what = SHOW_NOT_RESPONDING_MSG;
4073            msg.obj = map;
4074            msg.arg1 = aboveSystem ? 1 : 0;
4075            map.put("app", app);
4076            if (activity != null) {
4077                map.put("activity", activity);
4078            }
4079
4080            mHandler.sendMessage(msg);
4081        }
4082    }
4083
4084    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4085        if (!mLaunchWarningShown) {
4086            mLaunchWarningShown = true;
4087            mHandler.post(new Runnable() {
4088                @Override
4089                public void run() {
4090                    synchronized (ActivityManagerService.this) {
4091                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4092                        d.show();
4093                        mHandler.postDelayed(new Runnable() {
4094                            @Override
4095                            public void run() {
4096                                synchronized (ActivityManagerService.this) {
4097                                    d.dismiss();
4098                                    mLaunchWarningShown = false;
4099                                }
4100                            }
4101                        }, 4000);
4102                    }
4103                }
4104            });
4105        }
4106    }
4107
4108    @Override
4109    public boolean clearApplicationUserData(final String packageName,
4110            final IPackageDataObserver observer, int userId) {
4111        enforceNotIsolatedCaller("clearApplicationUserData");
4112        int uid = Binder.getCallingUid();
4113        int pid = Binder.getCallingPid();
4114        userId = handleIncomingUser(pid, uid,
4115                userId, false, true, "clearApplicationUserData", null);
4116        long callingId = Binder.clearCallingIdentity();
4117        try {
4118            IPackageManager pm = AppGlobals.getPackageManager();
4119            int pkgUid = -1;
4120            synchronized(this) {
4121                try {
4122                    pkgUid = pm.getPackageUid(packageName, userId);
4123                } catch (RemoteException e) {
4124                }
4125                if (pkgUid == -1) {
4126                    Slog.w(TAG, "Invalid packageName: " + packageName);
4127                    if (observer != null) {
4128                        try {
4129                            observer.onRemoveCompleted(packageName, false);
4130                        } catch (RemoteException e) {
4131                            Slog.i(TAG, "Observer no longer exists.");
4132                        }
4133                    }
4134                    return false;
4135                }
4136                if (uid == pkgUid || checkComponentPermission(
4137                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4138                        pid, uid, -1, true)
4139                        == PackageManager.PERMISSION_GRANTED) {
4140                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4141                } else {
4142                    throw new SecurityException("PID " + pid + " does not have permission "
4143                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4144                                    + " of package " + packageName);
4145                }
4146            }
4147
4148            try {
4149                // Clear application user data
4150                pm.clearApplicationUserData(packageName, observer, userId);
4151
4152                // Remove all permissions granted from/to this package
4153                removeUriPermissionsForPackageLocked(packageName, userId, true);
4154
4155                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4156                        Uri.fromParts("package", packageName, null));
4157                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4158                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4159                        null, null, 0, null, null, null, false, false, userId);
4160            } catch (RemoteException e) {
4161            }
4162        } finally {
4163            Binder.restoreCallingIdentity(callingId);
4164        }
4165        return true;
4166    }
4167
4168    @Override
4169    public void killBackgroundProcesses(final String packageName, int userId) {
4170        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4171                != PackageManager.PERMISSION_GRANTED &&
4172                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4173                        != PackageManager.PERMISSION_GRANTED) {
4174            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4175                    + Binder.getCallingPid()
4176                    + ", uid=" + Binder.getCallingUid()
4177                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4178            Slog.w(TAG, msg);
4179            throw new SecurityException(msg);
4180        }
4181
4182        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4183                userId, true, true, "killBackgroundProcesses", null);
4184        long callingId = Binder.clearCallingIdentity();
4185        try {
4186            IPackageManager pm = AppGlobals.getPackageManager();
4187            synchronized(this) {
4188                int appId = -1;
4189                try {
4190                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4191                } catch (RemoteException e) {
4192                }
4193                if (appId == -1) {
4194                    Slog.w(TAG, "Invalid packageName: " + packageName);
4195                    return;
4196                }
4197                killPackageProcessesLocked(packageName, appId, userId,
4198                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4199            }
4200        } finally {
4201            Binder.restoreCallingIdentity(callingId);
4202        }
4203    }
4204
4205    @Override
4206    public void killAllBackgroundProcesses() {
4207        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4208                != PackageManager.PERMISSION_GRANTED) {
4209            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4210                    + Binder.getCallingPid()
4211                    + ", uid=" + Binder.getCallingUid()
4212                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4213            Slog.w(TAG, msg);
4214            throw new SecurityException(msg);
4215        }
4216
4217        long callingId = Binder.clearCallingIdentity();
4218        try {
4219            synchronized(this) {
4220                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4221                final int NP = mProcessNames.getMap().size();
4222                for (int ip=0; ip<NP; ip++) {
4223                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4224                    final int NA = apps.size();
4225                    for (int ia=0; ia<NA; ia++) {
4226                        ProcessRecord app = apps.valueAt(ia);
4227                        if (app.persistent) {
4228                            // we don't kill persistent processes
4229                            continue;
4230                        }
4231                        if (app.removed) {
4232                            procs.add(app);
4233                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4234                            app.removed = true;
4235                            procs.add(app);
4236                        }
4237                    }
4238                }
4239
4240                int N = procs.size();
4241                for (int i=0; i<N; i++) {
4242                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4243                }
4244                mAllowLowerMemLevel = true;
4245                updateOomAdjLocked();
4246                doLowMemReportIfNeededLocked(null);
4247            }
4248        } finally {
4249            Binder.restoreCallingIdentity(callingId);
4250        }
4251    }
4252
4253    @Override
4254    public void forceStopPackage(final String packageName, int userId) {
4255        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4256                != PackageManager.PERMISSION_GRANTED) {
4257            String msg = "Permission Denial: forceStopPackage() from pid="
4258                    + Binder.getCallingPid()
4259                    + ", uid=" + Binder.getCallingUid()
4260                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4261            Slog.w(TAG, msg);
4262            throw new SecurityException(msg);
4263        }
4264        final int callingPid = Binder.getCallingPid();
4265        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4266                userId, true, true, "forceStopPackage", null);
4267        long callingId = Binder.clearCallingIdentity();
4268        try {
4269            IPackageManager pm = AppGlobals.getPackageManager();
4270            synchronized(this) {
4271                int[] users = userId == UserHandle.USER_ALL
4272                        ? getUsersLocked() : new int[] { userId };
4273                for (int user : users) {
4274                    int pkgUid = -1;
4275                    try {
4276                        pkgUid = pm.getPackageUid(packageName, user);
4277                    } catch (RemoteException e) {
4278                    }
4279                    if (pkgUid == -1) {
4280                        Slog.w(TAG, "Invalid packageName: " + packageName);
4281                        continue;
4282                    }
4283                    try {
4284                        pm.setPackageStoppedState(packageName, true, user);
4285                    } catch (RemoteException e) {
4286                    } catch (IllegalArgumentException e) {
4287                        Slog.w(TAG, "Failed trying to unstop package "
4288                                + packageName + ": " + e);
4289                    }
4290                    if (isUserRunningLocked(user, false)) {
4291                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4292                    }
4293                }
4294            }
4295        } finally {
4296            Binder.restoreCallingIdentity(callingId);
4297        }
4298    }
4299
4300    /*
4301     * The pkg name and app id have to be specified.
4302     */
4303    @Override
4304    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4305        if (pkg == null) {
4306            return;
4307        }
4308        // Make sure the uid is valid.
4309        if (appid < 0) {
4310            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4311            return;
4312        }
4313        int callerUid = Binder.getCallingUid();
4314        // Only the system server can kill an application
4315        if (callerUid == Process.SYSTEM_UID) {
4316            // Post an aysnc message to kill the application
4317            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4318            msg.arg1 = appid;
4319            msg.arg2 = 0;
4320            Bundle bundle = new Bundle();
4321            bundle.putString("pkg", pkg);
4322            bundle.putString("reason", reason);
4323            msg.obj = bundle;
4324            mHandler.sendMessage(msg);
4325        } else {
4326            throw new SecurityException(callerUid + " cannot kill pkg: " +
4327                    pkg);
4328        }
4329    }
4330
4331    @Override
4332    public void closeSystemDialogs(String reason) {
4333        enforceNotIsolatedCaller("closeSystemDialogs");
4334
4335        final int pid = Binder.getCallingPid();
4336        final int uid = Binder.getCallingUid();
4337        final long origId = Binder.clearCallingIdentity();
4338        try {
4339            synchronized (this) {
4340                // Only allow this from foreground processes, so that background
4341                // applications can't abuse it to prevent system UI from being shown.
4342                if (uid >= Process.FIRST_APPLICATION_UID) {
4343                    ProcessRecord proc;
4344                    synchronized (mPidsSelfLocked) {
4345                        proc = mPidsSelfLocked.get(pid);
4346                    }
4347                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4348                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4349                                + " from background process " + proc);
4350                        return;
4351                    }
4352                }
4353                closeSystemDialogsLocked(reason);
4354            }
4355        } finally {
4356            Binder.restoreCallingIdentity(origId);
4357        }
4358    }
4359
4360    void closeSystemDialogsLocked(String reason) {
4361        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4362        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4363                | Intent.FLAG_RECEIVER_FOREGROUND);
4364        if (reason != null) {
4365            intent.putExtra("reason", reason);
4366        }
4367        mWindowManager.closeSystemDialogs(reason);
4368
4369        mStackSupervisor.closeSystemDialogsLocked();
4370
4371        broadcastIntentLocked(null, null, intent, null,
4372                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4373                Process.SYSTEM_UID, UserHandle.USER_ALL);
4374    }
4375
4376    @Override
4377    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4378        enforceNotIsolatedCaller("getProcessMemoryInfo");
4379        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4380        for (int i=pids.length-1; i>=0; i--) {
4381            ProcessRecord proc;
4382            int oomAdj;
4383            synchronized (this) {
4384                synchronized (mPidsSelfLocked) {
4385                    proc = mPidsSelfLocked.get(pids[i]);
4386                    oomAdj = proc != null ? proc.setAdj : 0;
4387                }
4388            }
4389            infos[i] = new Debug.MemoryInfo();
4390            Debug.getMemoryInfo(pids[i], infos[i]);
4391            if (proc != null) {
4392                synchronized (this) {
4393                    if (proc.thread != null && proc.setAdj == oomAdj) {
4394                        // Record this for posterity if the process has been stable.
4395                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4396                                infos[i].getTotalUss(), false, proc.pkgList);
4397                    }
4398                }
4399            }
4400        }
4401        return infos;
4402    }
4403
4404    @Override
4405    public long[] getProcessPss(int[] pids) {
4406        enforceNotIsolatedCaller("getProcessPss");
4407        long[] pss = new long[pids.length];
4408        for (int i=pids.length-1; i>=0; i--) {
4409            ProcessRecord proc;
4410            int oomAdj;
4411            synchronized (this) {
4412                synchronized (mPidsSelfLocked) {
4413                    proc = mPidsSelfLocked.get(pids[i]);
4414                    oomAdj = proc != null ? proc.setAdj : 0;
4415                }
4416            }
4417            long[] tmpUss = new long[1];
4418            pss[i] = Debug.getPss(pids[i], tmpUss);
4419            if (proc != null) {
4420                synchronized (this) {
4421                    if (proc.thread != null && proc.setAdj == oomAdj) {
4422                        // Record this for posterity if the process has been stable.
4423                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4424                    }
4425                }
4426            }
4427        }
4428        return pss;
4429    }
4430
4431    @Override
4432    public void killApplicationProcess(String processName, int uid) {
4433        if (processName == null) {
4434            return;
4435        }
4436
4437        int callerUid = Binder.getCallingUid();
4438        // Only the system server can kill an application
4439        if (callerUid == Process.SYSTEM_UID) {
4440            synchronized (this) {
4441                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4442                if (app != null && app.thread != null) {
4443                    try {
4444                        app.thread.scheduleSuicide();
4445                    } catch (RemoteException e) {
4446                        // If the other end already died, then our work here is done.
4447                    }
4448                } else {
4449                    Slog.w(TAG, "Process/uid not found attempting kill of "
4450                            + processName + " / " + uid);
4451                }
4452            }
4453        } else {
4454            throw new SecurityException(callerUid + " cannot kill app process: " +
4455                    processName);
4456        }
4457    }
4458
4459    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4460        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4461                false, true, false, false, UserHandle.getUserId(uid), reason);
4462        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4463                Uri.fromParts("package", packageName, null));
4464        if (!mProcessesReady) {
4465            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4466                    | Intent.FLAG_RECEIVER_FOREGROUND);
4467        }
4468        intent.putExtra(Intent.EXTRA_UID, uid);
4469        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4470        broadcastIntentLocked(null, null, intent,
4471                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4472                false, false,
4473                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4474    }
4475
4476    private void forceStopUserLocked(int userId, String reason) {
4477        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4478        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4479        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4480                | Intent.FLAG_RECEIVER_FOREGROUND);
4481        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4482        broadcastIntentLocked(null, null, intent,
4483                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4484                false, false,
4485                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4486    }
4487
4488    private final boolean killPackageProcessesLocked(String packageName, int appId,
4489            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4490            boolean doit, boolean evenPersistent, String reason) {
4491        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4492
4493        // Remove all processes this package may have touched: all with the
4494        // same UID (except for the system or root user), and all whose name
4495        // matches the package name.
4496        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4497        final int NP = mProcessNames.getMap().size();
4498        for (int ip=0; ip<NP; ip++) {
4499            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4500            final int NA = apps.size();
4501            for (int ia=0; ia<NA; ia++) {
4502                ProcessRecord app = apps.valueAt(ia);
4503                if (app.persistent && !evenPersistent) {
4504                    // we don't kill persistent processes
4505                    continue;
4506                }
4507                if (app.removed) {
4508                    if (doit) {
4509                        procs.add(app);
4510                    }
4511                    continue;
4512                }
4513
4514                // Skip process if it doesn't meet our oom adj requirement.
4515                if (app.setAdj < minOomAdj) {
4516                    continue;
4517                }
4518
4519                // If no package is specified, we call all processes under the
4520                // give user id.
4521                if (packageName == null) {
4522                    if (app.userId != userId) {
4523                        continue;
4524                    }
4525                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4526                        continue;
4527                    }
4528                // Package has been specified, we want to hit all processes
4529                // that match it.  We need to qualify this by the processes
4530                // that are running under the specified app and user ID.
4531                } else {
4532                    if (UserHandle.getAppId(app.uid) != appId) {
4533                        continue;
4534                    }
4535                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4536                        continue;
4537                    }
4538                    if (!app.pkgList.containsKey(packageName)) {
4539                        continue;
4540                    }
4541                }
4542
4543                // Process has passed all conditions, kill it!
4544                if (!doit) {
4545                    return true;
4546                }
4547                app.removed = true;
4548                procs.add(app);
4549            }
4550        }
4551
4552        int N = procs.size();
4553        for (int i=0; i<N; i++) {
4554            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4555        }
4556        updateOomAdjLocked();
4557        return N > 0;
4558    }
4559
4560    private final boolean forceStopPackageLocked(String name, int appId,
4561            boolean callerWillRestart, boolean purgeCache, boolean doit,
4562            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4563        int i;
4564        int N;
4565
4566        if (userId == UserHandle.USER_ALL && name == null) {
4567            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4568        }
4569
4570        if (appId < 0 && name != null) {
4571            try {
4572                appId = UserHandle.getAppId(
4573                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4574            } catch (RemoteException e) {
4575            }
4576        }
4577
4578        if (doit) {
4579            if (name != null) {
4580                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4581                        + " user=" + userId + ": " + reason);
4582            } else {
4583                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4584            }
4585
4586            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4587            for (int ip=pmap.size()-1; ip>=0; ip--) {
4588                SparseArray<Long> ba = pmap.valueAt(ip);
4589                for (i=ba.size()-1; i>=0; i--) {
4590                    boolean remove = false;
4591                    final int entUid = ba.keyAt(i);
4592                    if (name != null) {
4593                        if (userId == UserHandle.USER_ALL) {
4594                            if (UserHandle.getAppId(entUid) == appId) {
4595                                remove = true;
4596                            }
4597                        } else {
4598                            if (entUid == UserHandle.getUid(userId, appId)) {
4599                                remove = true;
4600                            }
4601                        }
4602                    } else if (UserHandle.getUserId(entUid) == userId) {
4603                        remove = true;
4604                    }
4605                    if (remove) {
4606                        ba.removeAt(i);
4607                    }
4608                }
4609                if (ba.size() == 0) {
4610                    pmap.removeAt(ip);
4611                }
4612            }
4613        }
4614
4615        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4616                -100, callerWillRestart, true, doit, evenPersistent,
4617                name == null ? ("stop user " + userId) : ("stop " + name));
4618
4619        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4620            if (!doit) {
4621                return true;
4622            }
4623            didSomething = true;
4624        }
4625
4626        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4627            if (!doit) {
4628                return true;
4629            }
4630            didSomething = true;
4631        }
4632
4633        if (name == null) {
4634            // Remove all sticky broadcasts from this user.
4635            mStickyBroadcasts.remove(userId);
4636        }
4637
4638        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4639        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4640                userId, providers)) {
4641            if (!doit) {
4642                return true;
4643            }
4644            didSomething = true;
4645        }
4646        N = providers.size();
4647        for (i=0; i<N; i++) {
4648            removeDyingProviderLocked(null, providers.get(i), true);
4649        }
4650
4651        // Remove transient permissions granted from/to this package/user
4652        removeUriPermissionsForPackageLocked(name, userId, false);
4653
4654        if (name == null || uninstalling) {
4655            // Remove pending intents.  For now we only do this when force
4656            // stopping users, because we have some problems when doing this
4657            // for packages -- app widgets are not currently cleaned up for
4658            // such packages, so they can be left with bad pending intents.
4659            if (mIntentSenderRecords.size() > 0) {
4660                Iterator<WeakReference<PendingIntentRecord>> it
4661                        = mIntentSenderRecords.values().iterator();
4662                while (it.hasNext()) {
4663                    WeakReference<PendingIntentRecord> wpir = it.next();
4664                    if (wpir == null) {
4665                        it.remove();
4666                        continue;
4667                    }
4668                    PendingIntentRecord pir = wpir.get();
4669                    if (pir == null) {
4670                        it.remove();
4671                        continue;
4672                    }
4673                    if (name == null) {
4674                        // Stopping user, remove all objects for the user.
4675                        if (pir.key.userId != userId) {
4676                            // Not the same user, skip it.
4677                            continue;
4678                        }
4679                    } else {
4680                        if (UserHandle.getAppId(pir.uid) != appId) {
4681                            // Different app id, skip it.
4682                            continue;
4683                        }
4684                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4685                            // Different user, skip it.
4686                            continue;
4687                        }
4688                        if (!pir.key.packageName.equals(name)) {
4689                            // Different package, skip it.
4690                            continue;
4691                        }
4692                    }
4693                    if (!doit) {
4694                        return true;
4695                    }
4696                    didSomething = true;
4697                    it.remove();
4698                    pir.canceled = true;
4699                    if (pir.key.activity != null) {
4700                        pir.key.activity.pendingResults.remove(pir.ref);
4701                    }
4702                }
4703            }
4704        }
4705
4706        if (doit) {
4707            if (purgeCache && name != null) {
4708                AttributeCache ac = AttributeCache.instance();
4709                if (ac != null) {
4710                    ac.removePackage(name);
4711                }
4712            }
4713            if (mBooted) {
4714                mStackSupervisor.resumeTopActivitiesLocked();
4715                mStackSupervisor.scheduleIdleLocked();
4716            }
4717        }
4718
4719        return didSomething;
4720    }
4721
4722    private final boolean removeProcessLocked(ProcessRecord app,
4723            boolean callerWillRestart, boolean allowRestart, String reason) {
4724        final String name = app.processName;
4725        final int uid = app.uid;
4726        if (DEBUG_PROCESSES) Slog.d(
4727            TAG, "Force removing proc " + app.toShortString() + " (" + name
4728            + "/" + uid + ")");
4729
4730        mProcessNames.remove(name, uid);
4731        mIsolatedProcesses.remove(app.uid);
4732        if (mHeavyWeightProcess == app) {
4733            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4734                    mHeavyWeightProcess.userId, 0));
4735            mHeavyWeightProcess = null;
4736        }
4737        boolean needRestart = false;
4738        if (app.pid > 0 && app.pid != MY_PID) {
4739            int pid = app.pid;
4740            synchronized (mPidsSelfLocked) {
4741                mPidsSelfLocked.remove(pid);
4742                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4743            }
4744            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4745                    app.processName, app.info.uid);
4746            if (app.isolated) {
4747                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4748            }
4749            killUnneededProcessLocked(app, reason);
4750            handleAppDiedLocked(app, true, allowRestart);
4751            removeLruProcessLocked(app);
4752
4753            if (app.persistent && !app.isolated) {
4754                if (!callerWillRestart) {
4755                    addAppLocked(app.info, false);
4756                } else {
4757                    needRestart = true;
4758                }
4759            }
4760        } else {
4761            mRemovedProcesses.add(app);
4762        }
4763
4764        return needRestart;
4765    }
4766
4767    private final void processStartTimedOutLocked(ProcessRecord app) {
4768        final int pid = app.pid;
4769        boolean gone = false;
4770        synchronized (mPidsSelfLocked) {
4771            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4772            if (knownApp != null && knownApp.thread == null) {
4773                mPidsSelfLocked.remove(pid);
4774                gone = true;
4775            }
4776        }
4777
4778        if (gone) {
4779            Slog.w(TAG, "Process " + app + " failed to attach");
4780            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4781                    pid, app.uid, app.processName);
4782            mProcessNames.remove(app.processName, app.uid);
4783            mIsolatedProcesses.remove(app.uid);
4784            if (mHeavyWeightProcess == app) {
4785                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4786                        mHeavyWeightProcess.userId, 0));
4787                mHeavyWeightProcess = null;
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            // Take care of any launching providers waiting for this process.
4795            checkAppInLaunchingProvidersLocked(app, true);
4796            // Take care of any services that are waiting for the process.
4797            mServices.processStartTimedOutLocked(app);
4798            killUnneededProcessLocked(app, "start timeout");
4799            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4800                Slog.w(TAG, "Unattached app died before backup, skipping");
4801                try {
4802                    IBackupManager bm = IBackupManager.Stub.asInterface(
4803                            ServiceManager.getService(Context.BACKUP_SERVICE));
4804                    bm.agentDisconnected(app.info.packageName);
4805                } catch (RemoteException e) {
4806                    // Can't happen; the backup manager is local
4807                }
4808            }
4809            if (isPendingBroadcastProcessLocked(pid)) {
4810                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4811                skipPendingBroadcastLocked(pid);
4812            }
4813        } else {
4814            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4815        }
4816    }
4817
4818    private final boolean attachApplicationLocked(IApplicationThread thread,
4819            int pid) {
4820
4821        // Find the application record that is being attached...  either via
4822        // the pid if we are running in multiple processes, or just pull the
4823        // next app record if we are emulating process with anonymous threads.
4824        ProcessRecord app;
4825        if (pid != MY_PID && pid >= 0) {
4826            synchronized (mPidsSelfLocked) {
4827                app = mPidsSelfLocked.get(pid);
4828            }
4829        } else {
4830            app = null;
4831        }
4832
4833        if (app == null) {
4834            Slog.w(TAG, "No pending application record for pid " + pid
4835                    + " (IApplicationThread " + thread + "); dropping process");
4836            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4837            if (pid > 0 && pid != MY_PID) {
4838                Process.killProcessQuiet(pid);
4839            } else {
4840                try {
4841                    thread.scheduleExit();
4842                } catch (Exception e) {
4843                    // Ignore exceptions.
4844                }
4845            }
4846            return false;
4847        }
4848
4849        // If this application record is still attached to a previous
4850        // process, clean it up now.
4851        if (app.thread != null) {
4852            handleAppDiedLocked(app, true, true);
4853        }
4854
4855        // Tell the process all about itself.
4856
4857        if (localLOGV) Slog.v(
4858                TAG, "Binding process pid " + pid + " to record " + app);
4859
4860        final String processName = app.processName;
4861        try {
4862            AppDeathRecipient adr = new AppDeathRecipient(
4863                    app, pid, thread);
4864            thread.asBinder().linkToDeath(adr, 0);
4865            app.deathRecipient = adr;
4866        } catch (RemoteException e) {
4867            app.resetPackageList(mProcessStats);
4868            startProcessLocked(app, "link fail", processName);
4869            return false;
4870        }
4871
4872        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4873
4874        app.makeActive(thread, mProcessStats);
4875        app.curAdj = app.setAdj = -100;
4876        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4877        app.forcingToForeground = null;
4878        updateProcessForegroundLocked(app, false, false);
4879        app.hasShownUi = false;
4880        app.debugging = false;
4881        app.cached = false;
4882
4883        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4884
4885        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4886        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4887
4888        if (!normalMode) {
4889            Slog.i(TAG, "Launching preboot mode app: " + app);
4890        }
4891
4892        if (localLOGV) Slog.v(
4893            TAG, "New app record " + app
4894            + " thread=" + thread.asBinder() + " pid=" + pid);
4895        try {
4896            int testMode = IApplicationThread.DEBUG_OFF;
4897            if (mDebugApp != null && mDebugApp.equals(processName)) {
4898                testMode = mWaitForDebugger
4899                    ? IApplicationThread.DEBUG_WAIT
4900                    : IApplicationThread.DEBUG_ON;
4901                app.debugging = true;
4902                if (mDebugTransient) {
4903                    mDebugApp = mOrigDebugApp;
4904                    mWaitForDebugger = mOrigWaitForDebugger;
4905                }
4906            }
4907            String profileFile = app.instrumentationProfileFile;
4908            ParcelFileDescriptor profileFd = null;
4909            boolean profileAutoStop = false;
4910            if (mProfileApp != null && mProfileApp.equals(processName)) {
4911                mProfileProc = app;
4912                profileFile = mProfileFile;
4913                profileFd = mProfileFd;
4914                profileAutoStop = mAutoStopProfiler;
4915            }
4916            boolean enableOpenGlTrace = false;
4917            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4918                enableOpenGlTrace = true;
4919                mOpenGlTraceApp = null;
4920            }
4921
4922            // If the app is being launched for restore or full backup, set it up specially
4923            boolean isRestrictedBackupMode = false;
4924            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4925                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4926                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4927                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4928            }
4929
4930            ensurePackageDexOpt(app.instrumentationInfo != null
4931                    ? app.instrumentationInfo.packageName
4932                    : app.info.packageName);
4933            if (app.instrumentationClass != null) {
4934                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4935            }
4936            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4937                    + processName + " with config " + mConfiguration);
4938            ApplicationInfo appInfo = app.instrumentationInfo != null
4939                    ? app.instrumentationInfo : app.info;
4940            app.compat = compatibilityInfoForPackageLocked(appInfo);
4941            if (profileFd != null) {
4942                profileFd = profileFd.dup();
4943            }
4944            thread.bindApplication(processName, appInfo, providers,
4945                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4946                    app.instrumentationArguments, app.instrumentationWatcher,
4947                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4948                    isRestrictedBackupMode || !normalMode, app.persistent,
4949                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4950                    mCoreSettingsObserver.getCoreSettingsLocked());
4951            updateLruProcessLocked(app, false, null);
4952            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4953        } catch (Exception e) {
4954            // todo: Yikes!  What should we do?  For now we will try to
4955            // start another process, but that could easily get us in
4956            // an infinite loop of restarting processes...
4957            Slog.w(TAG, "Exception thrown during bind!", e);
4958
4959            app.resetPackageList(mProcessStats);
4960            app.unlinkDeathRecipient();
4961            startProcessLocked(app, "bind fail", processName);
4962            return false;
4963        }
4964
4965        // Remove this record from the list of starting applications.
4966        mPersistentStartingProcesses.remove(app);
4967        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4968                "Attach application locked removing on hold: " + app);
4969        mProcessesOnHold.remove(app);
4970
4971        boolean badApp = false;
4972        boolean didSomething = false;
4973
4974        // See if the top visible activity is waiting to run in this process...
4975        if (normalMode) {
4976            try {
4977                if (mStackSupervisor.attachApplicationLocked(app)) {
4978                    didSomething = true;
4979                }
4980            } catch (Exception e) {
4981                badApp = true;
4982            }
4983        }
4984
4985        // Find any services that should be running in this process...
4986        if (!badApp) {
4987            try {
4988                didSomething |= mServices.attachApplicationLocked(app, processName);
4989            } catch (Exception e) {
4990                badApp = true;
4991            }
4992        }
4993
4994        // Check if a next-broadcast receiver is in this process...
4995        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4996            try {
4997                didSomething |= sendPendingBroadcastsLocked(app);
4998            } catch (Exception e) {
4999                // If the app died trying to launch the receiver we declare it 'bad'
5000                badApp = true;
5001            }
5002        }
5003
5004        // Check whether the next backup agent is in this process...
5005        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5006            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5007            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5008            try {
5009                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5010                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5011                        mBackupTarget.backupMode);
5012            } catch (Exception e) {
5013                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5014                e.printStackTrace();
5015            }
5016        }
5017
5018        if (badApp) {
5019            // todo: Also need to kill application to deal with all
5020            // kinds of exceptions.
5021            handleAppDiedLocked(app, false, true);
5022            return false;
5023        }
5024
5025        if (!didSomething) {
5026            updateOomAdjLocked();
5027        }
5028
5029        return true;
5030    }
5031
5032    @Override
5033    public final void attachApplication(IApplicationThread thread) {
5034        synchronized (this) {
5035            int callingPid = Binder.getCallingPid();
5036            final long origId = Binder.clearCallingIdentity();
5037            attachApplicationLocked(thread, callingPid);
5038            Binder.restoreCallingIdentity(origId);
5039        }
5040    }
5041
5042    @Override
5043    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5044        final long origId = Binder.clearCallingIdentity();
5045        synchronized (this) {
5046            ActivityStack stack = ActivityRecord.getStackLocked(token);
5047            if (stack != null) {
5048                ActivityRecord r =
5049                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5050                if (stopProfiling) {
5051                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5052                        try {
5053                            mProfileFd.close();
5054                        } catch (IOException e) {
5055                        }
5056                        clearProfilerLocked();
5057                    }
5058                }
5059            }
5060        }
5061        Binder.restoreCallingIdentity(origId);
5062    }
5063
5064    void enableScreenAfterBoot() {
5065        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5066                SystemClock.uptimeMillis());
5067        mWindowManager.enableScreenAfterBoot();
5068
5069        synchronized (this) {
5070            updateEventDispatchingLocked();
5071        }
5072    }
5073
5074    @Override
5075    public void showBootMessage(final CharSequence msg, final boolean always) {
5076        enforceNotIsolatedCaller("showBootMessage");
5077        mWindowManager.showBootMessage(msg, always);
5078    }
5079
5080    @Override
5081    public void dismissKeyguardOnNextActivity() {
5082        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5083        final long token = Binder.clearCallingIdentity();
5084        try {
5085            synchronized (this) {
5086                if (DEBUG_LOCKSCREEN) logLockScreen("");
5087                if (mLockScreenShown) {
5088                    mLockScreenShown = false;
5089                    comeOutOfSleepIfNeededLocked();
5090                }
5091                mStackSupervisor.setDismissKeyguard(true);
5092            }
5093        } finally {
5094            Binder.restoreCallingIdentity(token);
5095        }
5096    }
5097
5098    final void finishBooting() {
5099        IntentFilter pkgFilter = new IntentFilter();
5100        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5101        pkgFilter.addDataScheme("package");
5102        mContext.registerReceiver(new BroadcastReceiver() {
5103            @Override
5104            public void onReceive(Context context, Intent intent) {
5105                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5106                if (pkgs != null) {
5107                    for (String pkg : pkgs) {
5108                        synchronized (ActivityManagerService.this) {
5109                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5110                                    "finished booting")) {
5111                                setResultCode(Activity.RESULT_OK);
5112                                return;
5113                            }
5114                        }
5115                    }
5116                }
5117            }
5118        }, pkgFilter);
5119
5120        synchronized (this) {
5121            // Ensure that any processes we had put on hold are now started
5122            // up.
5123            final int NP = mProcessesOnHold.size();
5124            if (NP > 0) {
5125                ArrayList<ProcessRecord> procs =
5126                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5127                for (int ip=0; ip<NP; ip++) {
5128                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5129                            + procs.get(ip));
5130                    startProcessLocked(procs.get(ip), "on-hold", null);
5131                }
5132            }
5133
5134            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5135                // Start looking for apps that are abusing wake locks.
5136                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5137                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5138                // Tell anyone interested that we are done booting!
5139                SystemProperties.set("sys.boot_completed", "1");
5140                SystemProperties.set("dev.bootcomplete", "1");
5141                for (int i=0; i<mStartedUsers.size(); i++) {
5142                    UserStartedState uss = mStartedUsers.valueAt(i);
5143                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5144                        uss.mState = UserStartedState.STATE_RUNNING;
5145                        final int userId = mStartedUsers.keyAt(i);
5146                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5147                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5148                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5149                        broadcastIntentLocked(null, null, intent, null,
5150                                new IIntentReceiver.Stub() {
5151                                    @Override
5152                                    public void performReceive(Intent intent, int resultCode,
5153                                            String data, Bundle extras, boolean ordered,
5154                                            boolean sticky, int sendingUser) {
5155                                        synchronized (ActivityManagerService.this) {
5156                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5157                                                    true, false);
5158                                        }
5159                                    }
5160                                },
5161                                0, null, null,
5162                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5163                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5164                                userId);
5165                    }
5166                }
5167            }
5168        }
5169    }
5170
5171    final void ensureBootCompleted() {
5172        boolean booting;
5173        boolean enableScreen;
5174        synchronized (this) {
5175            booting = mBooting;
5176            mBooting = false;
5177            enableScreen = !mBooted;
5178            mBooted = true;
5179        }
5180
5181        if (booting) {
5182            finishBooting();
5183        }
5184
5185        if (enableScreen) {
5186            enableScreenAfterBoot();
5187        }
5188    }
5189
5190    @Override
5191    public final void activityResumed(IBinder token) {
5192        final long origId = Binder.clearCallingIdentity();
5193        synchronized(this) {
5194            ActivityStack stack = ActivityRecord.getStackLocked(token);
5195            if (stack != null) {
5196                ActivityRecord.activityResumedLocked(token);
5197            }
5198        }
5199        Binder.restoreCallingIdentity(origId);
5200    }
5201
5202    @Override
5203    public final void activityPaused(IBinder token) {
5204        final long origId = Binder.clearCallingIdentity();
5205        synchronized(this) {
5206            ActivityStack stack = ActivityRecord.getStackLocked(token);
5207            if (stack != null) {
5208                stack.activityPausedLocked(token, false);
5209            }
5210        }
5211        Binder.restoreCallingIdentity(origId);
5212    }
5213
5214    @Override
5215    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5216            CharSequence description) {
5217        if (localLOGV) Slog.v(
5218            TAG, "Activity stopped: token=" + token);
5219
5220        // Refuse possible leaked file descriptors
5221        if (icicle != null && icicle.hasFileDescriptors()) {
5222            throw new IllegalArgumentException("File descriptors passed in Bundle");
5223        }
5224
5225        ActivityRecord r = null;
5226
5227        final long origId = Binder.clearCallingIdentity();
5228
5229        synchronized (this) {
5230            r = ActivityRecord.isInStackLocked(token);
5231            if (r != null) {
5232                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5233            }
5234        }
5235
5236        if (r != null) {
5237            sendPendingThumbnail(r, null, null, null, false);
5238        }
5239
5240        trimApplications();
5241
5242        Binder.restoreCallingIdentity(origId);
5243    }
5244
5245    @Override
5246    public final void activityDestroyed(IBinder token) {
5247        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5248        synchronized (this) {
5249            ActivityStack stack = ActivityRecord.getStackLocked(token);
5250            if (stack != null) {
5251                stack.activityDestroyedLocked(token);
5252            }
5253        }
5254    }
5255
5256    @Override
5257    public String getCallingPackage(IBinder token) {
5258        synchronized (this) {
5259            ActivityRecord r = getCallingRecordLocked(token);
5260            return r != null ? r.info.packageName : null;
5261        }
5262    }
5263
5264    @Override
5265    public ComponentName getCallingActivity(IBinder token) {
5266        synchronized (this) {
5267            ActivityRecord r = getCallingRecordLocked(token);
5268            return r != null ? r.intent.getComponent() : null;
5269        }
5270    }
5271
5272    private ActivityRecord getCallingRecordLocked(IBinder token) {
5273        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5274        if (r == null) {
5275            return null;
5276        }
5277        return r.resultTo;
5278    }
5279
5280    @Override
5281    public ComponentName getActivityClassForToken(IBinder token) {
5282        synchronized(this) {
5283            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5284            if (r == null) {
5285                return null;
5286            }
5287            return r.intent.getComponent();
5288        }
5289    }
5290
5291    @Override
5292    public String getPackageForToken(IBinder token) {
5293        synchronized(this) {
5294            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5295            if (r == null) {
5296                return null;
5297            }
5298            return r.packageName;
5299        }
5300    }
5301
5302    @Override
5303    public IIntentSender getIntentSender(int type,
5304            String packageName, IBinder token, String resultWho,
5305            int requestCode, Intent[] intents, String[] resolvedTypes,
5306            int flags, Bundle options, int userId) {
5307        enforceNotIsolatedCaller("getIntentSender");
5308        // Refuse possible leaked file descriptors
5309        if (intents != null) {
5310            if (intents.length < 1) {
5311                throw new IllegalArgumentException("Intents array length must be >= 1");
5312            }
5313            for (int i=0; i<intents.length; i++) {
5314                Intent intent = intents[i];
5315                if (intent != null) {
5316                    if (intent.hasFileDescriptors()) {
5317                        throw new IllegalArgumentException("File descriptors passed in Intent");
5318                    }
5319                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5320                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5321                        throw new IllegalArgumentException(
5322                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5323                    }
5324                    intents[i] = new Intent(intent);
5325                }
5326            }
5327            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5328                throw new IllegalArgumentException(
5329                        "Intent array length does not match resolvedTypes length");
5330            }
5331        }
5332        if (options != null) {
5333            if (options.hasFileDescriptors()) {
5334                throw new IllegalArgumentException("File descriptors passed in options");
5335            }
5336        }
5337
5338        synchronized(this) {
5339            int callingUid = Binder.getCallingUid();
5340            int origUserId = userId;
5341            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5342                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5343                    "getIntentSender", null);
5344            if (origUserId == UserHandle.USER_CURRENT) {
5345                // We don't want to evaluate this until the pending intent is
5346                // actually executed.  However, we do want to always do the
5347                // security checking for it above.
5348                userId = UserHandle.USER_CURRENT;
5349            }
5350            try {
5351                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5352                    int uid = AppGlobals.getPackageManager()
5353                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5354                    if (!UserHandle.isSameApp(callingUid, uid)) {
5355                        String msg = "Permission Denial: getIntentSender() from pid="
5356                            + Binder.getCallingPid()
5357                            + ", uid=" + Binder.getCallingUid()
5358                            + ", (need uid=" + uid + ")"
5359                            + " is not allowed to send as package " + packageName;
5360                        Slog.w(TAG, msg);
5361                        throw new SecurityException(msg);
5362                    }
5363                }
5364
5365                return getIntentSenderLocked(type, packageName, callingUid, userId,
5366                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5367
5368            } catch (RemoteException e) {
5369                throw new SecurityException(e);
5370            }
5371        }
5372    }
5373
5374    IIntentSender getIntentSenderLocked(int type, String packageName,
5375            int callingUid, int userId, IBinder token, String resultWho,
5376            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5377            Bundle options) {
5378        if (DEBUG_MU)
5379            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5380        ActivityRecord activity = null;
5381        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5382            activity = ActivityRecord.isInStackLocked(token);
5383            if (activity == null) {
5384                return null;
5385            }
5386            if (activity.finishing) {
5387                return null;
5388            }
5389        }
5390
5391        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5392        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5393        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5394        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5395                |PendingIntent.FLAG_UPDATE_CURRENT);
5396
5397        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5398                type, packageName, activity, resultWho,
5399                requestCode, intents, resolvedTypes, flags, options, userId);
5400        WeakReference<PendingIntentRecord> ref;
5401        ref = mIntentSenderRecords.get(key);
5402        PendingIntentRecord rec = ref != null ? ref.get() : null;
5403        if (rec != null) {
5404            if (!cancelCurrent) {
5405                if (updateCurrent) {
5406                    if (rec.key.requestIntent != null) {
5407                        rec.key.requestIntent.replaceExtras(intents != null ?
5408                                intents[intents.length - 1] : null);
5409                    }
5410                    if (intents != null) {
5411                        intents[intents.length-1] = rec.key.requestIntent;
5412                        rec.key.allIntents = intents;
5413                        rec.key.allResolvedTypes = resolvedTypes;
5414                    } else {
5415                        rec.key.allIntents = null;
5416                        rec.key.allResolvedTypes = null;
5417                    }
5418                }
5419                return rec;
5420            }
5421            rec.canceled = true;
5422            mIntentSenderRecords.remove(key);
5423        }
5424        if (noCreate) {
5425            return rec;
5426        }
5427        rec = new PendingIntentRecord(this, key, callingUid);
5428        mIntentSenderRecords.put(key, rec.ref);
5429        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5430            if (activity.pendingResults == null) {
5431                activity.pendingResults
5432                        = new HashSet<WeakReference<PendingIntentRecord>>();
5433            }
5434            activity.pendingResults.add(rec.ref);
5435        }
5436        return rec;
5437    }
5438
5439    @Override
5440    public void cancelIntentSender(IIntentSender sender) {
5441        if (!(sender instanceof PendingIntentRecord)) {
5442            return;
5443        }
5444        synchronized(this) {
5445            PendingIntentRecord rec = (PendingIntentRecord)sender;
5446            try {
5447                int uid = AppGlobals.getPackageManager()
5448                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5449                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5450                    String msg = "Permission Denial: cancelIntentSender() from pid="
5451                        + Binder.getCallingPid()
5452                        + ", uid=" + Binder.getCallingUid()
5453                        + " is not allowed to cancel packges "
5454                        + rec.key.packageName;
5455                    Slog.w(TAG, msg);
5456                    throw new SecurityException(msg);
5457                }
5458            } catch (RemoteException e) {
5459                throw new SecurityException(e);
5460            }
5461            cancelIntentSenderLocked(rec, true);
5462        }
5463    }
5464
5465    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5466        rec.canceled = true;
5467        mIntentSenderRecords.remove(rec.key);
5468        if (cleanActivity && rec.key.activity != null) {
5469            rec.key.activity.pendingResults.remove(rec.ref);
5470        }
5471    }
5472
5473    @Override
5474    public String getPackageForIntentSender(IIntentSender pendingResult) {
5475        if (!(pendingResult instanceof PendingIntentRecord)) {
5476            return null;
5477        }
5478        try {
5479            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5480            return res.key.packageName;
5481        } catch (ClassCastException e) {
5482        }
5483        return null;
5484    }
5485
5486    @Override
5487    public int getUidForIntentSender(IIntentSender sender) {
5488        if (sender instanceof PendingIntentRecord) {
5489            try {
5490                PendingIntentRecord res = (PendingIntentRecord)sender;
5491                return res.uid;
5492            } catch (ClassCastException e) {
5493            }
5494        }
5495        return -1;
5496    }
5497
5498    @Override
5499    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5500        if (!(pendingResult instanceof PendingIntentRecord)) {
5501            return false;
5502        }
5503        try {
5504            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5505            if (res.key.allIntents == null) {
5506                return false;
5507            }
5508            for (int i=0; i<res.key.allIntents.length; i++) {
5509                Intent intent = res.key.allIntents[i];
5510                if (intent.getPackage() != null && intent.getComponent() != null) {
5511                    return false;
5512                }
5513            }
5514            return true;
5515        } catch (ClassCastException e) {
5516        }
5517        return false;
5518    }
5519
5520    @Override
5521    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5522        if (!(pendingResult instanceof PendingIntentRecord)) {
5523            return false;
5524        }
5525        try {
5526            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5527            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5528                return true;
5529            }
5530            return false;
5531        } catch (ClassCastException e) {
5532        }
5533        return false;
5534    }
5535
5536    @Override
5537    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5538        if (!(pendingResult instanceof PendingIntentRecord)) {
5539            return null;
5540        }
5541        try {
5542            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5543            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5544        } catch (ClassCastException e) {
5545        }
5546        return null;
5547    }
5548
5549    @Override
5550    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5551        if (!(pendingResult instanceof PendingIntentRecord)) {
5552            return null;
5553        }
5554        try {
5555            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5556            Intent intent = res.key.requestIntent;
5557            if (intent != null) {
5558                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5559                        || res.lastTagPrefix.equals(prefix))) {
5560                    return res.lastTag;
5561                }
5562                res.lastTagPrefix = prefix;
5563                StringBuilder sb = new StringBuilder(128);
5564                if (prefix != null) {
5565                    sb.append(prefix);
5566                }
5567                if (intent.getAction() != null) {
5568                    sb.append(intent.getAction());
5569                } else if (intent.getComponent() != null) {
5570                    intent.getComponent().appendShortString(sb);
5571                } else {
5572                    sb.append("?");
5573                }
5574                return res.lastTag = sb.toString();
5575            }
5576        } catch (ClassCastException e) {
5577        }
5578        return null;
5579    }
5580
5581    @Override
5582    public void setProcessLimit(int max) {
5583        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5584                "setProcessLimit()");
5585        synchronized (this) {
5586            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5587            mProcessLimitOverride = max;
5588        }
5589        trimApplications();
5590    }
5591
5592    @Override
5593    public int getProcessLimit() {
5594        synchronized (this) {
5595            return mProcessLimitOverride;
5596        }
5597    }
5598
5599    void foregroundTokenDied(ForegroundToken token) {
5600        synchronized (ActivityManagerService.this) {
5601            synchronized (mPidsSelfLocked) {
5602                ForegroundToken cur
5603                    = mForegroundProcesses.get(token.pid);
5604                if (cur != token) {
5605                    return;
5606                }
5607                mForegroundProcesses.remove(token.pid);
5608                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5609                if (pr == null) {
5610                    return;
5611                }
5612                pr.forcingToForeground = null;
5613                updateProcessForegroundLocked(pr, false, false);
5614            }
5615            updateOomAdjLocked();
5616        }
5617    }
5618
5619    @Override
5620    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5621        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5622                "setProcessForeground()");
5623        synchronized(this) {
5624            boolean changed = false;
5625
5626            synchronized (mPidsSelfLocked) {
5627                ProcessRecord pr = mPidsSelfLocked.get(pid);
5628                if (pr == null && isForeground) {
5629                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5630                    return;
5631                }
5632                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5633                if (oldToken != null) {
5634                    oldToken.token.unlinkToDeath(oldToken, 0);
5635                    mForegroundProcesses.remove(pid);
5636                    if (pr != null) {
5637                        pr.forcingToForeground = null;
5638                    }
5639                    changed = true;
5640                }
5641                if (isForeground && token != null) {
5642                    ForegroundToken newToken = new ForegroundToken() {
5643                        @Override
5644                        public void binderDied() {
5645                            foregroundTokenDied(this);
5646                        }
5647                    };
5648                    newToken.pid = pid;
5649                    newToken.token = token;
5650                    try {
5651                        token.linkToDeath(newToken, 0);
5652                        mForegroundProcesses.put(pid, newToken);
5653                        pr.forcingToForeground = token;
5654                        changed = true;
5655                    } catch (RemoteException e) {
5656                        // If the process died while doing this, we will later
5657                        // do the cleanup with the process death link.
5658                    }
5659                }
5660            }
5661
5662            if (changed) {
5663                updateOomAdjLocked();
5664            }
5665        }
5666    }
5667
5668    // =========================================================
5669    // PERMISSIONS
5670    // =========================================================
5671
5672    static class PermissionController extends IPermissionController.Stub {
5673        ActivityManagerService mActivityManagerService;
5674        PermissionController(ActivityManagerService activityManagerService) {
5675            mActivityManagerService = activityManagerService;
5676        }
5677
5678        @Override
5679        public boolean checkPermission(String permission, int pid, int uid) {
5680            return mActivityManagerService.checkPermission(permission, pid,
5681                    uid) == PackageManager.PERMISSION_GRANTED;
5682        }
5683    }
5684
5685    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5686        @Override
5687        public int checkComponentPermission(String permission, int pid, int uid,
5688                int owningUid, boolean exported) {
5689            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5690                    owningUid, exported);
5691        }
5692
5693        @Override
5694        public Object getAMSLock() {
5695            return ActivityManagerService.this;
5696        }
5697    }
5698
5699    /**
5700     * This can be called with or without the global lock held.
5701     */
5702    int checkComponentPermission(String permission, int pid, int uid,
5703            int owningUid, boolean exported) {
5704        // We might be performing an operation on behalf of an indirect binder
5705        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5706        // client identity accordingly before proceeding.
5707        Identity tlsIdentity = sCallerIdentity.get();
5708        if (tlsIdentity != null) {
5709            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5710                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5711            uid = tlsIdentity.uid;
5712            pid = tlsIdentity.pid;
5713        }
5714
5715        if (pid == MY_PID) {
5716            return PackageManager.PERMISSION_GRANTED;
5717        }
5718
5719        return ActivityManager.checkComponentPermission(permission, uid,
5720                owningUid, exported);
5721    }
5722
5723    /**
5724     * As the only public entry point for permissions checking, this method
5725     * can enforce the semantic that requesting a check on a null global
5726     * permission is automatically denied.  (Internally a null permission
5727     * string is used when calling {@link #checkComponentPermission} in cases
5728     * when only uid-based security is needed.)
5729     *
5730     * This can be called with or without the global lock held.
5731     */
5732    @Override
5733    public int checkPermission(String permission, int pid, int uid) {
5734        if (permission == null) {
5735            return PackageManager.PERMISSION_DENIED;
5736        }
5737        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5738    }
5739
5740    /**
5741     * Binder IPC calls go through the public entry point.
5742     * This can be called with or without the global lock held.
5743     */
5744    int checkCallingPermission(String permission) {
5745        return checkPermission(permission,
5746                Binder.getCallingPid(),
5747                UserHandle.getAppId(Binder.getCallingUid()));
5748    }
5749
5750    /**
5751     * This can be called with or without the global lock held.
5752     */
5753    void enforceCallingPermission(String permission, String func) {
5754        if (checkCallingPermission(permission)
5755                == PackageManager.PERMISSION_GRANTED) {
5756            return;
5757        }
5758
5759        String msg = "Permission Denial: " + func + " from pid="
5760                + Binder.getCallingPid()
5761                + ", uid=" + Binder.getCallingUid()
5762                + " requires " + permission;
5763        Slog.w(TAG, msg);
5764        throw new SecurityException(msg);
5765    }
5766
5767    /**
5768     * Determine if UID is holding permissions required to access {@link Uri} in
5769     * the given {@link ProviderInfo}. Final permission checking is always done
5770     * in {@link ContentProvider}.
5771     */
5772    private final boolean checkHoldingPermissionsLocked(
5773            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5774        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5775                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5776
5777        if (pi.applicationInfo.uid == uid) {
5778            return true;
5779        } else if (!pi.exported) {
5780            return false;
5781        }
5782
5783        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5784        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5785        try {
5786            // check if target holds top-level <provider> permissions
5787            if (!readMet && pi.readPermission != null
5788                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5789                readMet = true;
5790            }
5791            if (!writeMet && pi.writePermission != null
5792                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5793                writeMet = true;
5794            }
5795
5796            // track if unprotected read/write is allowed; any denied
5797            // <path-permission> below removes this ability
5798            boolean allowDefaultRead = pi.readPermission == null;
5799            boolean allowDefaultWrite = pi.writePermission == null;
5800
5801            // check if target holds any <path-permission> that match uri
5802            final PathPermission[] pps = pi.pathPermissions;
5803            if (pps != null) {
5804                final String path = uri.getPath();
5805                int i = pps.length;
5806                while (i > 0 && (!readMet || !writeMet)) {
5807                    i--;
5808                    PathPermission pp = pps[i];
5809                    if (pp.match(path)) {
5810                        if (!readMet) {
5811                            final String pprperm = pp.getReadPermission();
5812                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5813                                    + pprperm + " for " + pp.getPath()
5814                                    + ": match=" + pp.match(path)
5815                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5816                            if (pprperm != null) {
5817                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5818                                    readMet = true;
5819                                } else {
5820                                    allowDefaultRead = false;
5821                                }
5822                            }
5823                        }
5824                        if (!writeMet) {
5825                            final String ppwperm = pp.getWritePermission();
5826                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5827                                    + ppwperm + " for " + pp.getPath()
5828                                    + ": match=" + pp.match(path)
5829                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5830                            if (ppwperm != null) {
5831                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5832                                    writeMet = true;
5833                                } else {
5834                                    allowDefaultWrite = false;
5835                                }
5836                            }
5837                        }
5838                    }
5839                }
5840            }
5841
5842            // grant unprotected <provider> read/write, if not blocked by
5843            // <path-permission> above
5844            if (allowDefaultRead) readMet = true;
5845            if (allowDefaultWrite) writeMet = true;
5846
5847        } catch (RemoteException e) {
5848            return false;
5849        }
5850
5851        return readMet && writeMet;
5852    }
5853
5854    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5855        ProviderInfo pi = null;
5856        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5857        if (cpr != null) {
5858            pi = cpr.info;
5859        } else {
5860            try {
5861                pi = AppGlobals.getPackageManager().resolveContentProvider(
5862                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5863            } catch (RemoteException ex) {
5864            }
5865        }
5866        return pi;
5867    }
5868
5869    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5870        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5871        if (targetUris != null) {
5872            return targetUris.get(uri);
5873        } else {
5874            return null;
5875        }
5876    }
5877
5878    private UriPermission findOrCreateUriPermissionLocked(
5879            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5880        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5881        if (targetUris == null) {
5882            targetUris = Maps.newArrayMap();
5883            mGrantedUriPermissions.put(targetUid, targetUris);
5884        }
5885
5886        UriPermission perm = targetUris.get(uri);
5887        if (perm == null) {
5888            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5889            targetUris.put(uri, perm);
5890        }
5891
5892        return perm;
5893    }
5894
5895    private final boolean checkUriPermissionLocked(
5896            Uri uri, int uid, int modeFlags, int minStrength) {
5897        // Root gets to do everything.
5898        if (uid == 0) {
5899            return true;
5900        }
5901        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5902        if (perms == null) return false;
5903        UriPermission perm = perms.get(uri);
5904        if (perm == null) return false;
5905        return perm.getStrength(modeFlags) >= minStrength;
5906    }
5907
5908    @Override
5909    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5910        enforceNotIsolatedCaller("checkUriPermission");
5911
5912        // Another redirected-binder-call permissions check as in
5913        // {@link checkComponentPermission}.
5914        Identity tlsIdentity = sCallerIdentity.get();
5915        if (tlsIdentity != null) {
5916            uid = tlsIdentity.uid;
5917            pid = tlsIdentity.pid;
5918        }
5919
5920        // Our own process gets to do everything.
5921        if (pid == MY_PID) {
5922            return PackageManager.PERMISSION_GRANTED;
5923        }
5924        synchronized(this) {
5925            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5926                    ? PackageManager.PERMISSION_GRANTED
5927                    : PackageManager.PERMISSION_DENIED;
5928        }
5929    }
5930
5931    /**
5932     * Check if the targetPkg can be granted permission to access uri by
5933     * the callingUid using the given modeFlags.  Throws a security exception
5934     * if callingUid is not allowed to do this.  Returns the uid of the target
5935     * if the URI permission grant should be performed; returns -1 if it is not
5936     * needed (for example targetPkg already has permission to access the URI).
5937     * If you already know the uid of the target, you can supply it in
5938     * lastTargetUid else set that to -1.
5939     */
5940    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5941            Uri uri, int modeFlags, int lastTargetUid) {
5942        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5943        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5944                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5945        if (modeFlags == 0) {
5946            return -1;
5947        }
5948
5949        if (targetPkg != null) {
5950            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5951                    "Checking grant " + targetPkg + " permission to " + uri);
5952        }
5953
5954        final IPackageManager pm = AppGlobals.getPackageManager();
5955
5956        // If this is not a content: uri, we can't do anything with it.
5957        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5958            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5959                    "Can't grant URI permission for non-content URI: " + uri);
5960            return -1;
5961        }
5962
5963        final String authority = uri.getAuthority();
5964        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5965        if (pi == null) {
5966            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5967            return -1;
5968        }
5969
5970        int targetUid = lastTargetUid;
5971        if (targetUid < 0 && targetPkg != null) {
5972            try {
5973                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5974                if (targetUid < 0) {
5975                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5976                            "Can't grant URI permission no uid for: " + targetPkg);
5977                    return -1;
5978                }
5979            } catch (RemoteException ex) {
5980                return -1;
5981            }
5982        }
5983
5984        if (targetUid >= 0) {
5985            // First...  does the target actually need this permission?
5986            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5987                // No need to grant the target this permission.
5988                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5989                        "Target " + targetPkg + " already has full permission to " + uri);
5990                return -1;
5991            }
5992        } else {
5993            // First...  there is no target package, so can anyone access it?
5994            boolean allowed = pi.exported;
5995            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5996                if (pi.readPermission != null) {
5997                    allowed = false;
5998                }
5999            }
6000            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6001                if (pi.writePermission != null) {
6002                    allowed = false;
6003                }
6004            }
6005            if (allowed) {
6006                return -1;
6007            }
6008        }
6009
6010        // Second...  is the provider allowing granting of URI permissions?
6011        if (!pi.grantUriPermissions) {
6012            throw new SecurityException("Provider " + pi.packageName
6013                    + "/" + pi.name
6014                    + " does not allow granting of Uri permissions (uri "
6015                    + uri + ")");
6016        }
6017        if (pi.uriPermissionPatterns != null) {
6018            final int N = pi.uriPermissionPatterns.length;
6019            boolean allowed = false;
6020            for (int i=0; i<N; i++) {
6021                if (pi.uriPermissionPatterns[i] != null
6022                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6023                    allowed = true;
6024                    break;
6025                }
6026            }
6027            if (!allowed) {
6028                throw new SecurityException("Provider " + pi.packageName
6029                        + "/" + pi.name
6030                        + " does not allow granting of permission to path of Uri "
6031                        + uri);
6032            }
6033        }
6034
6035        // Third...  does the caller itself have permission to access
6036        // this uri?
6037        if (callingUid != Process.myUid()) {
6038            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6039                // Require they hold a strong enough Uri permission
6040                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6041                        : UriPermission.STRENGTH_OWNED;
6042                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6043                    throw new SecurityException("Uid " + callingUid
6044                            + " does not have permission to uri " + uri);
6045                }
6046            }
6047        }
6048
6049        return targetUid;
6050    }
6051
6052    @Override
6053    public int checkGrantUriPermission(int callingUid, String targetPkg,
6054            Uri uri, int modeFlags) {
6055        enforceNotIsolatedCaller("checkGrantUriPermission");
6056        synchronized(this) {
6057            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6058        }
6059    }
6060
6061    void grantUriPermissionUncheckedLocked(
6062            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6063        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6064        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6065                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6066        if (modeFlags == 0) {
6067            return;
6068        }
6069
6070        // So here we are: the caller has the assumed permission
6071        // to the uri, and the target doesn't.  Let's now give this to
6072        // the target.
6073
6074        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6075                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6076
6077        final String authority = uri.getAuthority();
6078        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6079        if (pi == null) {
6080            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6081            return;
6082        }
6083
6084        final UriPermission perm = findOrCreateUriPermissionLocked(
6085                pi.packageName, targetPkg, targetUid, uri);
6086        perm.grantModes(modeFlags, persistable, owner);
6087    }
6088
6089    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6090            int modeFlags, UriPermissionOwner owner) {
6091        if (targetPkg == null) {
6092            throw new NullPointerException("targetPkg");
6093        }
6094
6095        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6096        if (targetUid < 0) {
6097            return;
6098        }
6099
6100        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6101    }
6102
6103    static class NeededUriGrants extends ArrayList<Uri> {
6104        final String targetPkg;
6105        final int targetUid;
6106        final int flags;
6107
6108        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6109            this.targetPkg = targetPkg;
6110            this.targetUid = targetUid;
6111            this.flags = flags;
6112        }
6113    }
6114
6115    /**
6116     * Like checkGrantUriPermissionLocked, but takes an Intent.
6117     */
6118    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6119            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6120        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6121                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6122                + " clip=" + (intent != null ? intent.getClipData() : null)
6123                + " from " + intent + "; flags=0x"
6124                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6125
6126        if (targetPkg == null) {
6127            throw new NullPointerException("targetPkg");
6128        }
6129
6130        if (intent == null) {
6131            return null;
6132        }
6133        Uri data = intent.getData();
6134        ClipData clip = intent.getClipData();
6135        if (data == null && clip == null) {
6136            return null;
6137        }
6138
6139        if (data != null) {
6140            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6141                mode, needed != null ? needed.targetUid : -1);
6142            if (targetUid > 0) {
6143                if (needed == null) {
6144                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6145                }
6146                needed.add(data);
6147            }
6148        }
6149        if (clip != null) {
6150            for (int i=0; i<clip.getItemCount(); i++) {
6151                Uri uri = clip.getItemAt(i).getUri();
6152                if (uri != null) {
6153                    int targetUid = -1;
6154                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6155                            mode, needed != null ? needed.targetUid : -1);
6156                    if (targetUid > 0) {
6157                        if (needed == null) {
6158                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6159                        }
6160                        needed.add(uri);
6161                    }
6162                } else {
6163                    Intent clipIntent = clip.getItemAt(i).getIntent();
6164                    if (clipIntent != null) {
6165                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6166                                callingUid, targetPkg, clipIntent, mode, needed);
6167                        if (newNeeded != null) {
6168                            needed = newNeeded;
6169                        }
6170                    }
6171                }
6172            }
6173        }
6174
6175        return needed;
6176    }
6177
6178    /**
6179     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6180     */
6181    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6182            UriPermissionOwner owner) {
6183        if (needed != null) {
6184            for (int i=0; i<needed.size(); i++) {
6185                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6186                        needed.get(i), needed.flags, owner);
6187            }
6188        }
6189    }
6190
6191    void grantUriPermissionFromIntentLocked(int callingUid,
6192            String targetPkg, Intent intent, UriPermissionOwner owner) {
6193        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6194                intent, intent != null ? intent.getFlags() : 0, null);
6195        if (needed == null) {
6196            return;
6197        }
6198
6199        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6200    }
6201
6202    @Override
6203    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6204            Uri uri, int modeFlags) {
6205        enforceNotIsolatedCaller("grantUriPermission");
6206        synchronized(this) {
6207            final ProcessRecord r = getRecordForAppLocked(caller);
6208            if (r == null) {
6209                throw new SecurityException("Unable to find app for caller "
6210                        + caller
6211                        + " when granting permission to uri " + uri);
6212            }
6213            if (targetPkg == null) {
6214                throw new IllegalArgumentException("null target");
6215            }
6216            if (uri == null) {
6217                throw new IllegalArgumentException("null uri");
6218            }
6219
6220            // Persistable only supported through Intents
6221            Preconditions.checkFlagsArgument(modeFlags,
6222                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6223
6224            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6225                    null);
6226        }
6227    }
6228
6229    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6230        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6231                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6232            ArrayMap<Uri, UriPermission> perms
6233                    = mGrantedUriPermissions.get(perm.targetUid);
6234            if (perms != null) {
6235                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6236                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6237                perms.remove(perm.uri);
6238                if (perms.size() == 0) {
6239                    mGrantedUriPermissions.remove(perm.targetUid);
6240                }
6241            }
6242        }
6243    }
6244
6245    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6246        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6247
6248        final IPackageManager pm = AppGlobals.getPackageManager();
6249        final String authority = uri.getAuthority();
6250        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6251        if (pi == null) {
6252            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6253            return;
6254        }
6255
6256        // Does the caller have this permission on the URI?
6257        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6258            // Right now, if you are not the original owner of the permission,
6259            // you are not allowed to revoke it.
6260            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6261                throw new SecurityException("Uid " + callingUid
6262                        + " does not have permission to uri " + uri);
6263            //}
6264        }
6265
6266        boolean persistChanged = false;
6267
6268        // Go through all of the permissions and remove any that match.
6269        final List<String> SEGMENTS = uri.getPathSegments();
6270        if (SEGMENTS != null) {
6271            final int NS = SEGMENTS.size();
6272            int N = mGrantedUriPermissions.size();
6273            for (int i=0; i<N; i++) {
6274                ArrayMap<Uri, UriPermission> perms
6275                        = mGrantedUriPermissions.valueAt(i);
6276                Iterator<UriPermission> it = perms.values().iterator();
6277            toploop:
6278                while (it.hasNext()) {
6279                    UriPermission perm = it.next();
6280                    Uri targetUri = perm.uri;
6281                    if (!authority.equals(targetUri.getAuthority())) {
6282                        continue;
6283                    }
6284                    List<String> targetSegments = targetUri.getPathSegments();
6285                    if (targetSegments == null) {
6286                        continue;
6287                    }
6288                    if (targetSegments.size() < NS) {
6289                        continue;
6290                    }
6291                    for (int j=0; j<NS; j++) {
6292                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6293                            continue toploop;
6294                        }
6295                    }
6296                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6297                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6298                    persistChanged |= perm.clearModes(modeFlags, true);
6299                    if (perm.modeFlags == 0) {
6300                        it.remove();
6301                    }
6302                }
6303                if (perms.size() == 0) {
6304                    mGrantedUriPermissions.remove(
6305                            mGrantedUriPermissions.keyAt(i));
6306                    N--;
6307                    i--;
6308                }
6309            }
6310        }
6311
6312        if (persistChanged) {
6313            schedulePersistUriGrants();
6314        }
6315    }
6316
6317    @Override
6318    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6319            int modeFlags) {
6320        enforceNotIsolatedCaller("revokeUriPermission");
6321        synchronized(this) {
6322            final ProcessRecord r = getRecordForAppLocked(caller);
6323            if (r == null) {
6324                throw new SecurityException("Unable to find app for caller "
6325                        + caller
6326                        + " when revoking permission to uri " + uri);
6327            }
6328            if (uri == null) {
6329                Slog.w(TAG, "revokeUriPermission: null uri");
6330                return;
6331            }
6332
6333            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6334                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6335            if (modeFlags == 0) {
6336                return;
6337            }
6338
6339            final IPackageManager pm = AppGlobals.getPackageManager();
6340            final String authority = uri.getAuthority();
6341            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6342            if (pi == null) {
6343                Slog.w(TAG, "No content provider found for permission revoke: "
6344                        + uri.toSafeString());
6345                return;
6346            }
6347
6348            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6349        }
6350    }
6351
6352    /**
6353     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6354     * given package.
6355     *
6356     * @param packageName Package name to match, or {@code null} to apply to all
6357     *            packages.
6358     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6359     *            to all users.
6360     * @param persistable If persistable grants should be removed.
6361     */
6362    private void removeUriPermissionsForPackageLocked(
6363            String packageName, int userHandle, boolean persistable) {
6364        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6365            throw new IllegalArgumentException("Must narrow by either package or user");
6366        }
6367
6368        boolean persistChanged = false;
6369
6370        final int size = mGrantedUriPermissions.size();
6371        for (int i = 0; i < size; i++) {
6372            // Only inspect grants matching user
6373            if (userHandle == UserHandle.USER_ALL
6374                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6375                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6376                        .values().iterator();
6377                while (it.hasNext()) {
6378                    final UriPermission perm = it.next();
6379
6380                    // Only inspect grants matching package
6381                    if (packageName == null || perm.sourcePkg.equals(packageName)
6382                            || perm.targetPkg.equals(packageName)) {
6383                        persistChanged |= perm.clearModes(~0, persistable);
6384
6385                        // Only remove when no modes remain; any persisted grants
6386                        // will keep this alive.
6387                        if (perm.modeFlags == 0) {
6388                            it.remove();
6389                        }
6390                    }
6391                }
6392            }
6393        }
6394
6395        if (persistChanged) {
6396            schedulePersistUriGrants();
6397        }
6398    }
6399
6400    @Override
6401    public IBinder newUriPermissionOwner(String name) {
6402        enforceNotIsolatedCaller("newUriPermissionOwner");
6403        synchronized(this) {
6404            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6405            return owner.getExternalTokenLocked();
6406        }
6407    }
6408
6409    @Override
6410    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6411            Uri uri, int modeFlags) {
6412        synchronized(this) {
6413            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6414            if (owner == null) {
6415                throw new IllegalArgumentException("Unknown owner: " + token);
6416            }
6417            if (fromUid != Binder.getCallingUid()) {
6418                if (Binder.getCallingUid() != Process.myUid()) {
6419                    // Only system code can grant URI permissions on behalf
6420                    // of other users.
6421                    throw new SecurityException("nice try");
6422                }
6423            }
6424            if (targetPkg == null) {
6425                throw new IllegalArgumentException("null target");
6426            }
6427            if (uri == null) {
6428                throw new IllegalArgumentException("null uri");
6429            }
6430
6431            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6432        }
6433    }
6434
6435    @Override
6436    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6437        synchronized(this) {
6438            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6439            if (owner == null) {
6440                throw new IllegalArgumentException("Unknown owner: " + token);
6441            }
6442
6443            if (uri == null) {
6444                owner.removeUriPermissionsLocked(mode);
6445            } else {
6446                owner.removeUriPermissionLocked(uri, mode);
6447            }
6448        }
6449    }
6450
6451    private void schedulePersistUriGrants() {
6452        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6453            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6454                    10 * DateUtils.SECOND_IN_MILLIS);
6455        }
6456    }
6457
6458    private void writeGrantedUriPermissions() {
6459        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6460
6461        // Snapshot permissions so we can persist without lock
6462        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6463        synchronized (this) {
6464            final int size = mGrantedUriPermissions.size();
6465            for (int i = 0 ; i < size; i++) {
6466                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6467                    if (perm.persistedModeFlags != 0) {
6468                        persist.add(perm.snapshot());
6469                    }
6470                }
6471            }
6472        }
6473
6474        FileOutputStream fos = null;
6475        try {
6476            fos = mGrantFile.startWrite();
6477
6478            XmlSerializer out = new FastXmlSerializer();
6479            out.setOutput(fos, "utf-8");
6480            out.startDocument(null, true);
6481            out.startTag(null, TAG_URI_GRANTS);
6482            for (UriPermission.Snapshot perm : persist) {
6483                out.startTag(null, TAG_URI_GRANT);
6484                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6485                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6486                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6487                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6488                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6489                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6490                out.endTag(null, TAG_URI_GRANT);
6491            }
6492            out.endTag(null, TAG_URI_GRANTS);
6493            out.endDocument();
6494
6495            mGrantFile.finishWrite(fos);
6496        } catch (IOException e) {
6497            if (fos != null) {
6498                mGrantFile.failWrite(fos);
6499            }
6500        }
6501    }
6502
6503    private void readGrantedUriPermissionsLocked() {
6504        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6505
6506        final long now = System.currentTimeMillis();
6507
6508        FileInputStream fis = null;
6509        try {
6510            fis = mGrantFile.openRead();
6511            final XmlPullParser in = Xml.newPullParser();
6512            in.setInput(fis, null);
6513
6514            int type;
6515            while ((type = in.next()) != END_DOCUMENT) {
6516                final String tag = in.getName();
6517                if (type == START_TAG) {
6518                    if (TAG_URI_GRANT.equals(tag)) {
6519                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6520                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6521                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6522                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6523                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6524                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6525
6526                        // Sanity check that provider still belongs to source package
6527                        final ProviderInfo pi = getProviderInfoLocked(
6528                                uri.getAuthority(), userHandle);
6529                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6530                            int targetUid = -1;
6531                            try {
6532                                targetUid = AppGlobals.getPackageManager()
6533                                        .getPackageUid(targetPkg, userHandle);
6534                            } catch (RemoteException e) {
6535                            }
6536                            if (targetUid != -1) {
6537                                final UriPermission perm = findOrCreateUriPermissionLocked(
6538                                        sourcePkg, targetPkg, targetUid, uri);
6539                                perm.initPersistedModes(modeFlags, createdTime);
6540                            }
6541                        } else {
6542                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6543                                    + " but instead found " + pi);
6544                        }
6545                    }
6546                }
6547            }
6548        } catch (FileNotFoundException e) {
6549            // Missing grants is okay
6550        } catch (IOException e) {
6551            Log.wtf(TAG, "Failed reading Uri grants", e);
6552        } catch (XmlPullParserException e) {
6553            Log.wtf(TAG, "Failed reading Uri grants", e);
6554        } finally {
6555            IoUtils.closeQuietly(fis);
6556        }
6557    }
6558
6559    @Override
6560    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6561        enforceNotIsolatedCaller("takePersistableUriPermission");
6562
6563        Preconditions.checkFlagsArgument(modeFlags,
6564                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6565
6566        synchronized (this) {
6567            final int callingUid = Binder.getCallingUid();
6568            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6569            if (perm == null) {
6570                throw new SecurityException("No permission grant found for UID " + callingUid
6571                        + " and Uri " + uri.toSafeString());
6572            }
6573
6574            boolean persistChanged = perm.takePersistableModes(modeFlags);
6575            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6576
6577            if (persistChanged) {
6578                schedulePersistUriGrants();
6579            }
6580        }
6581    }
6582
6583    @Override
6584    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6585        enforceNotIsolatedCaller("releasePersistableUriPermission");
6586
6587        Preconditions.checkFlagsArgument(modeFlags,
6588                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6589
6590        synchronized (this) {
6591            final int callingUid = Binder.getCallingUid();
6592
6593            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6594            if (perm == null) {
6595                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6596                        + uri.toSafeString());
6597                return;
6598            }
6599
6600            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6601            removeUriPermissionIfNeededLocked(perm);
6602            if (persistChanged) {
6603                schedulePersistUriGrants();
6604            }
6605        }
6606    }
6607
6608    /**
6609     * Prune any older {@link UriPermission} for the given UID until outstanding
6610     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6611     *
6612     * @return if any mutations occured that require persisting.
6613     */
6614    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6615        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6616        if (perms == null) return false;
6617        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6618
6619        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6620        for (UriPermission perm : perms.values()) {
6621            if (perm.persistedModeFlags != 0) {
6622                persisted.add(perm);
6623            }
6624        }
6625
6626        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6627        if (trimCount <= 0) return false;
6628
6629        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6630        for (int i = 0; i < trimCount; i++) {
6631            final UriPermission perm = persisted.get(i);
6632
6633            if (DEBUG_URI_PERMISSION) {
6634                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6635            }
6636
6637            perm.releasePersistableModes(~0);
6638            removeUriPermissionIfNeededLocked(perm);
6639        }
6640
6641        return true;
6642    }
6643
6644    @Override
6645    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6646            String packageName, boolean incoming) {
6647        enforceNotIsolatedCaller("getPersistedUriPermissions");
6648        Preconditions.checkNotNull(packageName, "packageName");
6649
6650        final int callingUid = Binder.getCallingUid();
6651        final IPackageManager pm = AppGlobals.getPackageManager();
6652        try {
6653            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6654            if (packageUid != callingUid) {
6655                throw new SecurityException(
6656                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6657            }
6658        } catch (RemoteException e) {
6659            throw new SecurityException("Failed to verify package name ownership");
6660        }
6661
6662        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6663        synchronized (this) {
6664            if (incoming) {
6665                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6666                if (perms == null) {
6667                    Slog.w(TAG, "No permission grants found for " + packageName);
6668                } else {
6669                    final int size = perms.size();
6670                    for (int i = 0; i < size; i++) {
6671                        final UriPermission perm = perms.valueAt(i);
6672                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6673                            result.add(perm.buildPersistedPublicApiObject());
6674                        }
6675                    }
6676                }
6677            } else {
6678                final int size = mGrantedUriPermissions.size();
6679                for (int i = 0; i < size; i++) {
6680                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6681                    final int permsSize = perms.size();
6682                    for (int j = 0; j < permsSize; j++) {
6683                        final UriPermission perm = perms.valueAt(j);
6684                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6685                            result.add(perm.buildPersistedPublicApiObject());
6686                        }
6687                    }
6688                }
6689            }
6690        }
6691        return new ParceledListSlice<android.content.UriPermission>(result);
6692    }
6693
6694    @Override
6695    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6696        synchronized (this) {
6697            ProcessRecord app =
6698                who != null ? getRecordForAppLocked(who) : null;
6699            if (app == null) return;
6700
6701            Message msg = Message.obtain();
6702            msg.what = WAIT_FOR_DEBUGGER_MSG;
6703            msg.obj = app;
6704            msg.arg1 = waiting ? 1 : 0;
6705            mHandler.sendMessage(msg);
6706        }
6707    }
6708
6709    @Override
6710    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6711        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6712        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6713        outInfo.availMem = Process.getFreeMemory();
6714        outInfo.totalMem = Process.getTotalMemory();
6715        outInfo.threshold = homeAppMem;
6716        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6717        outInfo.hiddenAppThreshold = cachedAppMem;
6718        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6719                ProcessList.SERVICE_ADJ);
6720        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6721                ProcessList.VISIBLE_APP_ADJ);
6722        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6723                ProcessList.FOREGROUND_APP_ADJ);
6724    }
6725
6726    // =========================================================
6727    // TASK MANAGEMENT
6728    // =========================================================
6729
6730    @Override
6731    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6732                         IThumbnailReceiver receiver) {
6733        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6734
6735        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6736        ActivityRecord topRecord = null;
6737
6738        synchronized(this) {
6739            if (localLOGV) Slog.v(
6740                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6741                + ", receiver=" + receiver);
6742
6743            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6744                    != PackageManager.PERMISSION_GRANTED) {
6745                if (receiver != null) {
6746                    // If the caller wants to wait for pending thumbnails,
6747                    // it ain't gonna get them.
6748                    try {
6749                        receiver.finished();
6750                    } catch (RemoteException ex) {
6751                    }
6752                }
6753                String msg = "Permission Denial: getTasks() from pid="
6754                        + Binder.getCallingPid()
6755                        + ", uid=" + Binder.getCallingUid()
6756                        + " requires " + android.Manifest.permission.GET_TASKS;
6757                Slog.w(TAG, msg);
6758                throw new SecurityException(msg);
6759            }
6760
6761            // TODO: Improve with MRU list from all ActivityStacks.
6762            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6763
6764            if (!pending.pendingRecords.isEmpty()) {
6765                mPendingThumbnails.add(pending);
6766            }
6767        }
6768
6769        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6770
6771        if (topRecord != null) {
6772            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6773            try {
6774                IApplicationThread topThumbnail = topRecord.app.thread;
6775                topThumbnail.requestThumbnail(topRecord.appToken);
6776            } catch (Exception e) {
6777                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6778                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6779            }
6780        }
6781
6782        if (pending == null && receiver != null) {
6783            // In this case all thumbnails were available and the client
6784            // is being asked to be told when the remaining ones come in...
6785            // which is unusually, since the top-most currently running
6786            // activity should never have a canned thumbnail!  Oh well.
6787            try {
6788                receiver.finished();
6789            } catch (RemoteException ex) {
6790            }
6791        }
6792
6793        return list;
6794    }
6795
6796    TaskRecord getMostRecentTask() {
6797        return mRecentTasks.get(0);
6798    }
6799
6800    @Override
6801    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6802            int flags, int userId) {
6803        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6804                false, true, "getRecentTasks", null);
6805
6806        synchronized (this) {
6807            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6808                    "getRecentTasks()");
6809            final boolean detailed = checkCallingPermission(
6810                    android.Manifest.permission.GET_DETAILED_TASKS)
6811                    == PackageManager.PERMISSION_GRANTED;
6812
6813            IPackageManager pm = AppGlobals.getPackageManager();
6814
6815            final int N = mRecentTasks.size();
6816            ArrayList<ActivityManager.RecentTaskInfo> res
6817                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6818                            maxNum < N ? maxNum : N);
6819            for (int i=0; i<N && maxNum > 0; i++) {
6820                TaskRecord tr = mRecentTasks.get(i);
6821                // Only add calling user's recent tasks
6822                if (tr.userId != userId) continue;
6823                // Return the entry if desired by the caller.  We always return
6824                // the first entry, because callers always expect this to be the
6825                // foreground app.  We may filter others if the caller has
6826                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6827                // we should exclude the entry.
6828
6829                if (i == 0
6830                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6831                        || (tr.intent == null)
6832                        || ((tr.intent.getFlags()
6833                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6834                    ActivityManager.RecentTaskInfo rti
6835                            = new ActivityManager.RecentTaskInfo();
6836                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6837                    rti.persistentId = tr.taskId;
6838                    rti.baseIntent = new Intent(
6839                            tr.intent != null ? tr.intent : tr.affinityIntent);
6840                    if (!detailed) {
6841                        rti.baseIntent.replaceExtras((Bundle)null);
6842                    }
6843                    rti.origActivity = tr.origActivity;
6844                    rti.description = tr.lastDescription;
6845                    rti.stackId = tr.stack.mStackId;
6846
6847                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6848                        // Check whether this activity is currently available.
6849                        try {
6850                            if (rti.origActivity != null) {
6851                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6852                                        == null) {
6853                                    continue;
6854                                }
6855                            } else if (rti.baseIntent != null) {
6856                                if (pm.queryIntentActivities(rti.baseIntent,
6857                                        null, 0, userId) == null) {
6858                                    continue;
6859                                }
6860                            }
6861                        } catch (RemoteException e) {
6862                            // Will never happen.
6863                        }
6864                    }
6865
6866                    res.add(rti);
6867                    maxNum--;
6868                }
6869            }
6870            return res;
6871        }
6872    }
6873
6874    private TaskRecord recentTaskForIdLocked(int id) {
6875        final int N = mRecentTasks.size();
6876            for (int i=0; i<N; i++) {
6877                TaskRecord tr = mRecentTasks.get(i);
6878                if (tr.taskId == id) {
6879                    return tr;
6880                }
6881            }
6882            return null;
6883    }
6884
6885    @Override
6886    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6887        synchronized (this) {
6888            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6889                    "getTaskThumbnails()");
6890            TaskRecord tr = recentTaskForIdLocked(id);
6891            if (tr != null) {
6892                return tr.getTaskThumbnailsLocked();
6893            }
6894        }
6895        return null;
6896    }
6897
6898    @Override
6899    public Bitmap getTaskTopThumbnail(int id) {
6900        synchronized (this) {
6901            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6902                    "getTaskTopThumbnail()");
6903            TaskRecord tr = recentTaskForIdLocked(id);
6904            if (tr != null) {
6905                return tr.getTaskTopThumbnailLocked();
6906            }
6907        }
6908        return null;
6909    }
6910
6911    @Override
6912    public boolean removeSubTask(int taskId, int subTaskIndex) {
6913        synchronized (this) {
6914            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6915                    "removeSubTask()");
6916            long ident = Binder.clearCallingIdentity();
6917            try {
6918                TaskRecord tr = recentTaskForIdLocked(taskId);
6919                if (tr != null) {
6920                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6921                }
6922                return false;
6923            } finally {
6924                Binder.restoreCallingIdentity(ident);
6925            }
6926        }
6927    }
6928
6929    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6930        if (!pr.killedByAm) {
6931            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6932            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6933                    pr.processName, pr.setAdj, reason);
6934            pr.killedByAm = true;
6935            Process.killProcessQuiet(pr.pid);
6936        }
6937    }
6938
6939    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6940        tr.disposeThumbnail();
6941        mRecentTasks.remove(tr);
6942        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6943        Intent baseIntent = new Intent(
6944                tr.intent != null ? tr.intent : tr.affinityIntent);
6945        ComponentName component = baseIntent.getComponent();
6946        if (component == null) {
6947            Slog.w(TAG, "Now component for base intent of task: " + tr);
6948            return;
6949        }
6950
6951        // Find any running services associated with this app.
6952        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6953
6954        if (killProcesses) {
6955            // Find any running processes associated with this app.
6956            final String pkg = component.getPackageName();
6957            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6958            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6959            for (int i=0; i<pmap.size(); i++) {
6960                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6961                for (int j=0; j<uids.size(); j++) {
6962                    ProcessRecord proc = uids.valueAt(j);
6963                    if (proc.userId != tr.userId) {
6964                        continue;
6965                    }
6966                    if (!proc.pkgList.containsKey(pkg)) {
6967                        continue;
6968                    }
6969                    procs.add(proc);
6970                }
6971            }
6972
6973            // Kill the running processes.
6974            for (int i=0; i<procs.size(); i++) {
6975                ProcessRecord pr = procs.get(i);
6976                if (pr == mHomeProcess) {
6977                    // Don't kill the home process along with tasks from the same package.
6978                    continue;
6979                }
6980                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6981                    killUnneededProcessLocked(pr, "remove task");
6982                } else {
6983                    pr.waitingToKill = "remove task";
6984                }
6985            }
6986        }
6987    }
6988
6989    @Override
6990    public boolean removeTask(int taskId, int flags) {
6991        synchronized (this) {
6992            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6993                    "removeTask()");
6994            long ident = Binder.clearCallingIdentity();
6995            try {
6996                TaskRecord tr = recentTaskForIdLocked(taskId);
6997                if (tr != null) {
6998                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6999                    if (r != null) {
7000                        cleanUpRemovedTaskLocked(tr, flags);
7001                        return true;
7002                    }
7003                    if (tr.mActivities.size() == 0) {
7004                        // Caller is just removing a recent task that is
7005                        // not actively running.  That is easy!
7006                        cleanUpRemovedTaskLocked(tr, flags);
7007                        return true;
7008                    }
7009                    Slog.w(TAG, "removeTask: task " + taskId
7010                            + " does not have activities to remove, "
7011                            + " but numActivities=" + tr.numActivities
7012                            + ": " + tr);
7013                }
7014            } finally {
7015                Binder.restoreCallingIdentity(ident);
7016            }
7017        }
7018        return false;
7019    }
7020
7021    /**
7022     * TODO: Add mController hook
7023     */
7024    @Override
7025    public void moveTaskToFront(int task, int flags, Bundle options) {
7026        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7027                "moveTaskToFront()");
7028
7029        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
7030        synchronized(this) {
7031            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7032                    Binder.getCallingUid(), "Task to front")) {
7033                ActivityOptions.abort(options);
7034                return;
7035            }
7036            final long origId = Binder.clearCallingIdentity();
7037            try {
7038                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7039            } finally {
7040                Binder.restoreCallingIdentity(origId);
7041            }
7042            ActivityOptions.abort(options);
7043        }
7044    }
7045
7046    @Override
7047    public void moveTaskToBack(int taskId) {
7048        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7049                "moveTaskToBack()");
7050
7051        synchronized(this) {
7052            TaskRecord tr = recentTaskForIdLocked(taskId);
7053            if (tr != null) {
7054                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7055                ActivityStack stack = tr.stack;
7056                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7057                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7058                            Binder.getCallingUid(), "Task to back")) {
7059                        return;
7060                    }
7061                }
7062                final long origId = Binder.clearCallingIdentity();
7063                try {
7064                    stack.moveTaskToBackLocked(taskId, null);
7065                } finally {
7066                    Binder.restoreCallingIdentity(origId);
7067                }
7068            }
7069        }
7070    }
7071
7072    /**
7073     * Moves an activity, and all of the other activities within the same task, to the bottom
7074     * of the history stack.  The activity's order within the task is unchanged.
7075     *
7076     * @param token A reference to the activity we wish to move
7077     * @param nonRoot If false then this only works if the activity is the root
7078     *                of a task; if true it will work for any activity in a task.
7079     * @return Returns true if the move completed, false if not.
7080     */
7081    @Override
7082    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7083        enforceNotIsolatedCaller("moveActivityTaskToBack");
7084        synchronized(this) {
7085            final long origId = Binder.clearCallingIdentity();
7086            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7087            if (taskId >= 0) {
7088                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7089            }
7090            Binder.restoreCallingIdentity(origId);
7091        }
7092        return false;
7093    }
7094
7095    @Override
7096    public void moveTaskBackwards(int task) {
7097        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7098                "moveTaskBackwards()");
7099
7100        synchronized(this) {
7101            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7102                    Binder.getCallingUid(), "Task backwards")) {
7103                return;
7104            }
7105            final long origId = Binder.clearCallingIdentity();
7106            moveTaskBackwardsLocked(task);
7107            Binder.restoreCallingIdentity(origId);
7108        }
7109    }
7110
7111    private final void moveTaskBackwardsLocked(int task) {
7112        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7113    }
7114
7115    @Override
7116    public IBinder getHomeActivityToken() throws RemoteException {
7117        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7118                "getHomeActivityToken()");
7119        synchronized (this) {
7120            return mStackSupervisor.getHomeActivityToken();
7121        }
7122    }
7123
7124    @Override
7125    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7126            IActivityContainerCallback callback) throws RemoteException {
7127        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7128                "createActivityContainer()");
7129        synchronized (this) {
7130            if (parentActivityToken == null) {
7131                throw new IllegalArgumentException("parent token must not be null");
7132            }
7133            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7134            if (r == null) {
7135                return null;
7136            }
7137            return mStackSupervisor.createActivityContainer(r, callback);
7138        }
7139    }
7140
7141    @Override
7142    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7143        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7144                "deleteActivityContainer()");
7145        synchronized (this) {
7146            mStackSupervisor.deleteActivityContainer(container);
7147        }
7148    }
7149
7150    @Override
7151    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7152            throws RemoteException {
7153        synchronized (this) {
7154            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7155            if (stack != null) {
7156                return stack.mActivityContainer;
7157            }
7158            return null;
7159        }
7160    }
7161
7162    @Override
7163    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7164        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7165                "moveTaskToStack()");
7166        if (stackId == HOME_STACK_ID) {
7167            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7168                    new RuntimeException("here").fillInStackTrace());
7169        }
7170        synchronized (this) {
7171            long ident = Binder.clearCallingIdentity();
7172            try {
7173                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7174                        + stackId + " toTop=" + toTop);
7175                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7176            } finally {
7177                Binder.restoreCallingIdentity(ident);
7178            }
7179        }
7180    }
7181
7182    @Override
7183    public void resizeStack(int stackBoxId, Rect bounds) {
7184        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7185                "resizeStackBox()");
7186        long ident = Binder.clearCallingIdentity();
7187        try {
7188            mWindowManager.resizeStack(stackBoxId, bounds);
7189        } finally {
7190            Binder.restoreCallingIdentity(ident);
7191        }
7192    }
7193
7194    @Override
7195    public List<StackInfo> getAllStackInfos() {
7196        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7197                "getAllStackInfos()");
7198        long ident = Binder.clearCallingIdentity();
7199        try {
7200            synchronized (this) {
7201                return mStackSupervisor.getAllStackInfosLocked();
7202            }
7203        } finally {
7204            Binder.restoreCallingIdentity(ident);
7205        }
7206    }
7207
7208    @Override
7209    public StackInfo getStackInfo(int stackId) {
7210        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7211                "getStackInfo()");
7212        long ident = Binder.clearCallingIdentity();
7213        try {
7214            synchronized (this) {
7215                return mStackSupervisor.getStackInfoLocked(stackId);
7216            }
7217        } finally {
7218            Binder.restoreCallingIdentity(ident);
7219        }
7220    }
7221
7222    @Override
7223    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7224        synchronized(this) {
7225            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7226        }
7227    }
7228
7229    // =========================================================
7230    // THUMBNAILS
7231    // =========================================================
7232
7233    public void reportThumbnail(IBinder token,
7234            Bitmap thumbnail, CharSequence description) {
7235        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7236        final long origId = Binder.clearCallingIdentity();
7237        sendPendingThumbnail(null, token, thumbnail, description, true);
7238        Binder.restoreCallingIdentity(origId);
7239    }
7240
7241    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7242            Bitmap thumbnail, CharSequence description, boolean always) {
7243        TaskRecord task;
7244        ArrayList<PendingThumbnailsRecord> receivers = null;
7245
7246        //System.out.println("Send pending thumbnail: " + r);
7247
7248        synchronized(this) {
7249            if (r == null) {
7250                r = ActivityRecord.isInStackLocked(token);
7251                if (r == null) {
7252                    return;
7253                }
7254            }
7255            if (thumbnail == null && r.thumbHolder != null) {
7256                thumbnail = r.thumbHolder.lastThumbnail;
7257                description = r.thumbHolder.lastDescription;
7258            }
7259            if (thumbnail == null && !always) {
7260                // If there is no thumbnail, and this entry is not actually
7261                // going away, then abort for now and pick up the next
7262                // thumbnail we get.
7263                return;
7264            }
7265            task = r.task;
7266
7267            int N = mPendingThumbnails.size();
7268            int i=0;
7269            while (i<N) {
7270                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7271                //System.out.println("Looking in " + pr.pendingRecords);
7272                if (pr.pendingRecords.remove(r)) {
7273                    if (receivers == null) {
7274                        receivers = new ArrayList<PendingThumbnailsRecord>();
7275                    }
7276                    receivers.add(pr);
7277                    if (pr.pendingRecords.size() == 0) {
7278                        pr.finished = true;
7279                        mPendingThumbnails.remove(i);
7280                        N--;
7281                        continue;
7282                    }
7283                }
7284                i++;
7285            }
7286        }
7287
7288        if (receivers != null) {
7289            final int N = receivers.size();
7290            for (int i=0; i<N; i++) {
7291                try {
7292                    PendingThumbnailsRecord pr = receivers.get(i);
7293                    pr.receiver.newThumbnail(
7294                        task != null ? task.taskId : -1, thumbnail, description);
7295                    if (pr.finished) {
7296                        pr.receiver.finished();
7297                    }
7298                } catch (Exception e) {
7299                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7300                }
7301            }
7302        }
7303    }
7304
7305    // =========================================================
7306    // CONTENT PROVIDERS
7307    // =========================================================
7308
7309    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7310        List<ProviderInfo> providers = null;
7311        try {
7312            providers = AppGlobals.getPackageManager().
7313                queryContentProviders(app.processName, app.uid,
7314                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7315        } catch (RemoteException ex) {
7316        }
7317        if (DEBUG_MU)
7318            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7319        int userId = app.userId;
7320        if (providers != null) {
7321            int N = providers.size();
7322            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7323            for (int i=0; i<N; i++) {
7324                ProviderInfo cpi =
7325                    (ProviderInfo)providers.get(i);
7326                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7327                        cpi.name, cpi.flags);
7328                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7329                    // This is a singleton provider, but a user besides the
7330                    // default user is asking to initialize a process it runs
7331                    // in...  well, no, it doesn't actually run in this process,
7332                    // it runs in the process of the default user.  Get rid of it.
7333                    providers.remove(i);
7334                    N--;
7335                    i--;
7336                    continue;
7337                }
7338
7339                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7340                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7341                if (cpr == null) {
7342                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7343                    mProviderMap.putProviderByClass(comp, cpr);
7344                }
7345                if (DEBUG_MU)
7346                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7347                app.pubProviders.put(cpi.name, cpr);
7348                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7349                    // Don't add this if it is a platform component that is marked
7350                    // to run in multiple processes, because this is actually
7351                    // part of the framework so doesn't make sense to track as a
7352                    // separate apk in the process.
7353                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7354                }
7355                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7356            }
7357        }
7358        return providers;
7359    }
7360
7361    /**
7362     * Check if {@link ProcessRecord} has a possible chance at accessing the
7363     * given {@link ProviderInfo}. Final permission checking is always done
7364     * in {@link ContentProvider}.
7365     */
7366    private final String checkContentProviderPermissionLocked(
7367            ProviderInfo cpi, ProcessRecord r) {
7368        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7369        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7370        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7371                cpi.applicationInfo.uid, cpi.exported)
7372                == PackageManager.PERMISSION_GRANTED) {
7373            return null;
7374        }
7375        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7376                cpi.applicationInfo.uid, cpi.exported)
7377                == PackageManager.PERMISSION_GRANTED) {
7378            return null;
7379        }
7380
7381        PathPermission[] pps = cpi.pathPermissions;
7382        if (pps != null) {
7383            int i = pps.length;
7384            while (i > 0) {
7385                i--;
7386                PathPermission pp = pps[i];
7387                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7388                        cpi.applicationInfo.uid, cpi.exported)
7389                        == PackageManager.PERMISSION_GRANTED) {
7390                    return null;
7391                }
7392                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7393                        cpi.applicationInfo.uid, cpi.exported)
7394                        == PackageManager.PERMISSION_GRANTED) {
7395                    return null;
7396                }
7397            }
7398        }
7399
7400        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7401        if (perms != null) {
7402            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7403                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7404                    return null;
7405                }
7406            }
7407        }
7408
7409        String msg;
7410        if (!cpi.exported) {
7411            msg = "Permission Denial: opening provider " + cpi.name
7412                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7413                    + ", uid=" + callingUid + ") that is not exported from uid "
7414                    + cpi.applicationInfo.uid;
7415        } else {
7416            msg = "Permission Denial: opening provider " + cpi.name
7417                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7418                    + ", uid=" + callingUid + ") requires "
7419                    + cpi.readPermission + " or " + cpi.writePermission;
7420        }
7421        Slog.w(TAG, msg);
7422        return msg;
7423    }
7424
7425    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7426            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7427        if (r != null) {
7428            for (int i=0; i<r.conProviders.size(); i++) {
7429                ContentProviderConnection conn = r.conProviders.get(i);
7430                if (conn.provider == cpr) {
7431                    if (DEBUG_PROVIDER) Slog.v(TAG,
7432                            "Adding provider requested by "
7433                            + r.processName + " from process "
7434                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7435                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7436                    if (stable) {
7437                        conn.stableCount++;
7438                        conn.numStableIncs++;
7439                    } else {
7440                        conn.unstableCount++;
7441                        conn.numUnstableIncs++;
7442                    }
7443                    return conn;
7444                }
7445            }
7446            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7447            if (stable) {
7448                conn.stableCount = 1;
7449                conn.numStableIncs = 1;
7450            } else {
7451                conn.unstableCount = 1;
7452                conn.numUnstableIncs = 1;
7453            }
7454            cpr.connections.add(conn);
7455            r.conProviders.add(conn);
7456            return conn;
7457        }
7458        cpr.addExternalProcessHandleLocked(externalProcessToken);
7459        return null;
7460    }
7461
7462    boolean decProviderCountLocked(ContentProviderConnection conn,
7463            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7464        if (conn != null) {
7465            cpr = conn.provider;
7466            if (DEBUG_PROVIDER) Slog.v(TAG,
7467                    "Removing provider requested by "
7468                    + conn.client.processName + " from process "
7469                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7470                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7471            if (stable) {
7472                conn.stableCount--;
7473            } else {
7474                conn.unstableCount--;
7475            }
7476            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7477                cpr.connections.remove(conn);
7478                conn.client.conProviders.remove(conn);
7479                return true;
7480            }
7481            return false;
7482        }
7483        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7484        return false;
7485    }
7486
7487    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7488            String name, IBinder token, boolean stable, int userId) {
7489        ContentProviderRecord cpr;
7490        ContentProviderConnection conn = null;
7491        ProviderInfo cpi = null;
7492
7493        synchronized(this) {
7494            ProcessRecord r = null;
7495            if (caller != null) {
7496                r = getRecordForAppLocked(caller);
7497                if (r == null) {
7498                    throw new SecurityException(
7499                            "Unable to find app for caller " + caller
7500                          + " (pid=" + Binder.getCallingPid()
7501                          + ") when getting content provider " + name);
7502                }
7503            }
7504
7505            // First check if this content provider has been published...
7506            cpr = mProviderMap.getProviderByName(name, userId);
7507            boolean providerRunning = cpr != null;
7508            if (providerRunning) {
7509                cpi = cpr.info;
7510                String msg;
7511                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7512                    throw new SecurityException(msg);
7513                }
7514
7515                if (r != null && cpr.canRunHere(r)) {
7516                    // This provider has been published or is in the process
7517                    // of being published...  but it is also allowed to run
7518                    // in the caller's process, so don't make a connection
7519                    // and just let the caller instantiate its own instance.
7520                    ContentProviderHolder holder = cpr.newHolder(null);
7521                    // don't give caller the provider object, it needs
7522                    // to make its own.
7523                    holder.provider = null;
7524                    return holder;
7525                }
7526
7527                final long origId = Binder.clearCallingIdentity();
7528
7529                // In this case the provider instance already exists, so we can
7530                // return it right away.
7531                conn = incProviderCountLocked(r, cpr, token, stable);
7532                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7533                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7534                        // If this is a perceptible app accessing the provider,
7535                        // make sure to count it as being accessed and thus
7536                        // back up on the LRU list.  This is good because
7537                        // content providers are often expensive to start.
7538                        updateLruProcessLocked(cpr.proc, false, null);
7539                    }
7540                }
7541
7542                if (cpr.proc != null) {
7543                    if (false) {
7544                        if (cpr.name.flattenToShortString().equals(
7545                                "com.android.providers.calendar/.CalendarProvider2")) {
7546                            Slog.v(TAG, "****************** KILLING "
7547                                + cpr.name.flattenToShortString());
7548                            Process.killProcess(cpr.proc.pid);
7549                        }
7550                    }
7551                    boolean success = updateOomAdjLocked(cpr.proc);
7552                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7553                    // NOTE: there is still a race here where a signal could be
7554                    // pending on the process even though we managed to update its
7555                    // adj level.  Not sure what to do about this, but at least
7556                    // the race is now smaller.
7557                    if (!success) {
7558                        // Uh oh...  it looks like the provider's process
7559                        // has been killed on us.  We need to wait for a new
7560                        // process to be started, and make sure its death
7561                        // doesn't kill our process.
7562                        Slog.i(TAG,
7563                                "Existing provider " + cpr.name.flattenToShortString()
7564                                + " is crashing; detaching " + r);
7565                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7566                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7567                        if (!lastRef) {
7568                            // This wasn't the last ref our process had on
7569                            // the provider...  we have now been killed, bail.
7570                            return null;
7571                        }
7572                        providerRunning = false;
7573                        conn = null;
7574                    }
7575                }
7576
7577                Binder.restoreCallingIdentity(origId);
7578            }
7579
7580            boolean singleton;
7581            if (!providerRunning) {
7582                try {
7583                    cpi = AppGlobals.getPackageManager().
7584                        resolveContentProvider(name,
7585                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7586                } catch (RemoteException ex) {
7587                }
7588                if (cpi == null) {
7589                    return null;
7590                }
7591                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7592                        cpi.name, cpi.flags);
7593                if (singleton) {
7594                    userId = 0;
7595                }
7596                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7597
7598                String msg;
7599                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7600                    throw new SecurityException(msg);
7601                }
7602
7603                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7604                        && !cpi.processName.equals("system")) {
7605                    // If this content provider does not run in the system
7606                    // process, and the system is not yet ready to run other
7607                    // processes, then fail fast instead of hanging.
7608                    throw new IllegalArgumentException(
7609                            "Attempt to launch content provider before system ready");
7610                }
7611
7612                // Make sure that the user who owns this provider is started.  If not,
7613                // we don't want to allow it to run.
7614                if (mStartedUsers.get(userId) == null) {
7615                    Slog.w(TAG, "Unable to launch app "
7616                            + cpi.applicationInfo.packageName + "/"
7617                            + cpi.applicationInfo.uid + " for provider "
7618                            + name + ": user " + userId + " is stopped");
7619                    return null;
7620                }
7621
7622                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7623                cpr = mProviderMap.getProviderByClass(comp, userId);
7624                final boolean firstClass = cpr == null;
7625                if (firstClass) {
7626                    try {
7627                        ApplicationInfo ai =
7628                            AppGlobals.getPackageManager().
7629                                getApplicationInfo(
7630                                        cpi.applicationInfo.packageName,
7631                                        STOCK_PM_FLAGS, userId);
7632                        if (ai == null) {
7633                            Slog.w(TAG, "No package info for content provider "
7634                                    + cpi.name);
7635                            return null;
7636                        }
7637                        ai = getAppInfoForUser(ai, userId);
7638                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7639                    } catch (RemoteException ex) {
7640                        // pm is in same process, this will never happen.
7641                    }
7642                }
7643
7644                if (r != null && cpr.canRunHere(r)) {
7645                    // If this is a multiprocess provider, then just return its
7646                    // info and allow the caller to instantiate it.  Only do
7647                    // this if the provider is the same user as the caller's
7648                    // process, or can run as root (so can be in any process).
7649                    return cpr.newHolder(null);
7650                }
7651
7652                if (DEBUG_PROVIDER) {
7653                    RuntimeException e = new RuntimeException("here");
7654                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7655                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7656                }
7657
7658                // This is single process, and our app is now connecting to it.
7659                // See if we are already in the process of launching this
7660                // provider.
7661                final int N = mLaunchingProviders.size();
7662                int i;
7663                for (i=0; i<N; i++) {
7664                    if (mLaunchingProviders.get(i) == cpr) {
7665                        break;
7666                    }
7667                }
7668
7669                // If the provider is not already being launched, then get it
7670                // started.
7671                if (i >= N) {
7672                    final long origId = Binder.clearCallingIdentity();
7673
7674                    try {
7675                        // Content provider is now in use, its package can't be stopped.
7676                        try {
7677                            AppGlobals.getPackageManager().setPackageStoppedState(
7678                                    cpr.appInfo.packageName, false, userId);
7679                        } catch (RemoteException e) {
7680                        } catch (IllegalArgumentException e) {
7681                            Slog.w(TAG, "Failed trying to unstop package "
7682                                    + cpr.appInfo.packageName + ": " + e);
7683                        }
7684
7685                        // Use existing process if already started
7686                        ProcessRecord proc = getProcessRecordLocked(
7687                                cpi.processName, cpr.appInfo.uid, false);
7688                        if (proc != null && proc.thread != null) {
7689                            if (DEBUG_PROVIDER) {
7690                                Slog.d(TAG, "Installing in existing process " + proc);
7691                            }
7692                            proc.pubProviders.put(cpi.name, cpr);
7693                            try {
7694                                proc.thread.scheduleInstallProvider(cpi);
7695                            } catch (RemoteException e) {
7696                            }
7697                        } else {
7698                            proc = startProcessLocked(cpi.processName,
7699                                    cpr.appInfo, false, 0, "content provider",
7700                                    new ComponentName(cpi.applicationInfo.packageName,
7701                                            cpi.name), false, false, false);
7702                            if (proc == null) {
7703                                Slog.w(TAG, "Unable to launch app "
7704                                        + cpi.applicationInfo.packageName + "/"
7705                                        + cpi.applicationInfo.uid + " for provider "
7706                                        + name + ": process is bad");
7707                                return null;
7708                            }
7709                        }
7710                        cpr.launchingApp = proc;
7711                        mLaunchingProviders.add(cpr);
7712                    } finally {
7713                        Binder.restoreCallingIdentity(origId);
7714                    }
7715                }
7716
7717                // Make sure the provider is published (the same provider class
7718                // may be published under multiple names).
7719                if (firstClass) {
7720                    mProviderMap.putProviderByClass(comp, cpr);
7721                }
7722
7723                mProviderMap.putProviderByName(name, cpr);
7724                conn = incProviderCountLocked(r, cpr, token, stable);
7725                if (conn != null) {
7726                    conn.waiting = true;
7727                }
7728            }
7729        }
7730
7731        // Wait for the provider to be published...
7732        synchronized (cpr) {
7733            while (cpr.provider == null) {
7734                if (cpr.launchingApp == null) {
7735                    Slog.w(TAG, "Unable to launch app "
7736                            + cpi.applicationInfo.packageName + "/"
7737                            + cpi.applicationInfo.uid + " for provider "
7738                            + name + ": launching app became null");
7739                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7740                            UserHandle.getUserId(cpi.applicationInfo.uid),
7741                            cpi.applicationInfo.packageName,
7742                            cpi.applicationInfo.uid, name);
7743                    return null;
7744                }
7745                try {
7746                    if (DEBUG_MU) {
7747                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7748                                + cpr.launchingApp);
7749                    }
7750                    if (conn != null) {
7751                        conn.waiting = true;
7752                    }
7753                    cpr.wait();
7754                } catch (InterruptedException ex) {
7755                } finally {
7756                    if (conn != null) {
7757                        conn.waiting = false;
7758                    }
7759                }
7760            }
7761        }
7762        return cpr != null ? cpr.newHolder(conn) : null;
7763    }
7764
7765    public final ContentProviderHolder getContentProvider(
7766            IApplicationThread caller, String name, int userId, boolean stable) {
7767        enforceNotIsolatedCaller("getContentProvider");
7768        if (caller == null) {
7769            String msg = "null IApplicationThread when getting content provider "
7770                    + name;
7771            Slog.w(TAG, msg);
7772            throw new SecurityException(msg);
7773        }
7774
7775        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7776                false, true, "getContentProvider", null);
7777        return getContentProviderImpl(caller, name, null, stable, userId);
7778    }
7779
7780    public ContentProviderHolder getContentProviderExternal(
7781            String name, int userId, IBinder token) {
7782        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7783            "Do not have permission in call getContentProviderExternal()");
7784        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7785                false, true, "getContentProvider", null);
7786        return getContentProviderExternalUnchecked(name, token, userId);
7787    }
7788
7789    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7790            IBinder token, int userId) {
7791        return getContentProviderImpl(null, name, token, true, userId);
7792    }
7793
7794    /**
7795     * Drop a content provider from a ProcessRecord's bookkeeping
7796     */
7797    public void removeContentProvider(IBinder connection, boolean stable) {
7798        enforceNotIsolatedCaller("removeContentProvider");
7799        long ident = Binder.clearCallingIdentity();
7800        try {
7801            synchronized (this) {
7802                ContentProviderConnection conn;
7803                try {
7804                    conn = (ContentProviderConnection)connection;
7805                } catch (ClassCastException e) {
7806                    String msg ="removeContentProvider: " + connection
7807                            + " not a ContentProviderConnection";
7808                    Slog.w(TAG, msg);
7809                    throw new IllegalArgumentException(msg);
7810                }
7811                if (conn == null) {
7812                    throw new NullPointerException("connection is null");
7813                }
7814                if (decProviderCountLocked(conn, null, null, stable)) {
7815                    updateOomAdjLocked();
7816                }
7817            }
7818        } finally {
7819            Binder.restoreCallingIdentity(ident);
7820        }
7821    }
7822
7823    public void removeContentProviderExternal(String name, IBinder token) {
7824        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7825            "Do not have permission in call removeContentProviderExternal()");
7826        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7827    }
7828
7829    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7830        synchronized (this) {
7831            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7832            if(cpr == null) {
7833                //remove from mProvidersByClass
7834                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7835                return;
7836            }
7837
7838            //update content provider record entry info
7839            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7840            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7841            if (localCpr.hasExternalProcessHandles()) {
7842                if (localCpr.removeExternalProcessHandleLocked(token)) {
7843                    updateOomAdjLocked();
7844                } else {
7845                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7846                            + " with no external reference for token: "
7847                            + token + ".");
7848                }
7849            } else {
7850                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7851                        + " with no external references.");
7852            }
7853        }
7854    }
7855
7856    public final void publishContentProviders(IApplicationThread caller,
7857            List<ContentProviderHolder> providers) {
7858        if (providers == null) {
7859            return;
7860        }
7861
7862        enforceNotIsolatedCaller("publishContentProviders");
7863        synchronized (this) {
7864            final ProcessRecord r = getRecordForAppLocked(caller);
7865            if (DEBUG_MU)
7866                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7867            if (r == null) {
7868                throw new SecurityException(
7869                        "Unable to find app for caller " + caller
7870                      + " (pid=" + Binder.getCallingPid()
7871                      + ") when publishing content providers");
7872            }
7873
7874            final long origId = Binder.clearCallingIdentity();
7875
7876            final int N = providers.size();
7877            for (int i=0; i<N; i++) {
7878                ContentProviderHolder src = providers.get(i);
7879                if (src == null || src.info == null || src.provider == null) {
7880                    continue;
7881                }
7882                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7883                if (DEBUG_MU)
7884                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7885                if (dst != null) {
7886                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7887                    mProviderMap.putProviderByClass(comp, dst);
7888                    String names[] = dst.info.authority.split(";");
7889                    for (int j = 0; j < names.length; j++) {
7890                        mProviderMap.putProviderByName(names[j], dst);
7891                    }
7892
7893                    int NL = mLaunchingProviders.size();
7894                    int j;
7895                    for (j=0; j<NL; j++) {
7896                        if (mLaunchingProviders.get(j) == dst) {
7897                            mLaunchingProviders.remove(j);
7898                            j--;
7899                            NL--;
7900                        }
7901                    }
7902                    synchronized (dst) {
7903                        dst.provider = src.provider;
7904                        dst.proc = r;
7905                        dst.notifyAll();
7906                    }
7907                    updateOomAdjLocked(r);
7908                }
7909            }
7910
7911            Binder.restoreCallingIdentity(origId);
7912        }
7913    }
7914
7915    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7916        ContentProviderConnection conn;
7917        try {
7918            conn = (ContentProviderConnection)connection;
7919        } catch (ClassCastException e) {
7920            String msg ="refContentProvider: " + connection
7921                    + " not a ContentProviderConnection";
7922            Slog.w(TAG, msg);
7923            throw new IllegalArgumentException(msg);
7924        }
7925        if (conn == null) {
7926            throw new NullPointerException("connection is null");
7927        }
7928
7929        synchronized (this) {
7930            if (stable > 0) {
7931                conn.numStableIncs += stable;
7932            }
7933            stable = conn.stableCount + stable;
7934            if (stable < 0) {
7935                throw new IllegalStateException("stableCount < 0: " + stable);
7936            }
7937
7938            if (unstable > 0) {
7939                conn.numUnstableIncs += unstable;
7940            }
7941            unstable = conn.unstableCount + unstable;
7942            if (unstable < 0) {
7943                throw new IllegalStateException("unstableCount < 0: " + unstable);
7944            }
7945
7946            if ((stable+unstable) <= 0) {
7947                throw new IllegalStateException("ref counts can't go to zero here: stable="
7948                        + stable + " unstable=" + unstable);
7949            }
7950            conn.stableCount = stable;
7951            conn.unstableCount = unstable;
7952            return !conn.dead;
7953        }
7954    }
7955
7956    public void unstableProviderDied(IBinder connection) {
7957        ContentProviderConnection conn;
7958        try {
7959            conn = (ContentProviderConnection)connection;
7960        } catch (ClassCastException e) {
7961            String msg ="refContentProvider: " + connection
7962                    + " not a ContentProviderConnection";
7963            Slog.w(TAG, msg);
7964            throw new IllegalArgumentException(msg);
7965        }
7966        if (conn == null) {
7967            throw new NullPointerException("connection is null");
7968        }
7969
7970        // Safely retrieve the content provider associated with the connection.
7971        IContentProvider provider;
7972        synchronized (this) {
7973            provider = conn.provider.provider;
7974        }
7975
7976        if (provider == null) {
7977            // Um, yeah, we're way ahead of you.
7978            return;
7979        }
7980
7981        // Make sure the caller is being honest with us.
7982        if (provider.asBinder().pingBinder()) {
7983            // Er, no, still looks good to us.
7984            synchronized (this) {
7985                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7986                        + " says " + conn + " died, but we don't agree");
7987                return;
7988            }
7989        }
7990
7991        // Well look at that!  It's dead!
7992        synchronized (this) {
7993            if (conn.provider.provider != provider) {
7994                // But something changed...  good enough.
7995                return;
7996            }
7997
7998            ProcessRecord proc = conn.provider.proc;
7999            if (proc == null || proc.thread == null) {
8000                // Seems like the process is already cleaned up.
8001                return;
8002            }
8003
8004            // As far as we're concerned, this is just like receiving a
8005            // death notification...  just a bit prematurely.
8006            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8007                    + ") early provider death");
8008            final long ident = Binder.clearCallingIdentity();
8009            try {
8010                appDiedLocked(proc, proc.pid, proc.thread);
8011            } finally {
8012                Binder.restoreCallingIdentity(ident);
8013            }
8014        }
8015    }
8016
8017    @Override
8018    public void appNotRespondingViaProvider(IBinder connection) {
8019        enforceCallingPermission(
8020                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8021
8022        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8023        if (conn == null) {
8024            Slog.w(TAG, "ContentProviderConnection is null");
8025            return;
8026        }
8027
8028        final ProcessRecord host = conn.provider.proc;
8029        if (host == null) {
8030            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8031            return;
8032        }
8033
8034        final long token = Binder.clearCallingIdentity();
8035        try {
8036            appNotResponding(host, null, null, false, "ContentProvider not responding");
8037        } finally {
8038            Binder.restoreCallingIdentity(token);
8039        }
8040    }
8041
8042    public final void installSystemProviders() {
8043        List<ProviderInfo> providers;
8044        synchronized (this) {
8045            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8046            providers = generateApplicationProvidersLocked(app);
8047            if (providers != null) {
8048                for (int i=providers.size()-1; i>=0; i--) {
8049                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8050                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8051                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8052                                + ": not system .apk");
8053                        providers.remove(i);
8054                    }
8055                }
8056            }
8057        }
8058        if (providers != null) {
8059            mSystemThread.installSystemProviders(providers);
8060        }
8061
8062        mCoreSettingsObserver = new CoreSettingsObserver(this);
8063
8064        mUsageStatsService.monitorPackages();
8065    }
8066
8067    /**
8068     * Allows app to retrieve the MIME type of a URI without having permission
8069     * to access its content provider.
8070     *
8071     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8072     *
8073     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8074     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8075     */
8076    public String getProviderMimeType(Uri uri, int userId) {
8077        enforceNotIsolatedCaller("getProviderMimeType");
8078        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8079                userId, false, true, "getProviderMimeType", null);
8080        final String name = uri.getAuthority();
8081        final long ident = Binder.clearCallingIdentity();
8082        ContentProviderHolder holder = null;
8083
8084        try {
8085            holder = getContentProviderExternalUnchecked(name, null, userId);
8086            if (holder != null) {
8087                return holder.provider.getType(uri);
8088            }
8089        } catch (RemoteException e) {
8090            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8091            return null;
8092        } finally {
8093            if (holder != null) {
8094                removeContentProviderExternalUnchecked(name, null, userId);
8095            }
8096            Binder.restoreCallingIdentity(ident);
8097        }
8098
8099        return null;
8100    }
8101
8102    // =========================================================
8103    // GLOBAL MANAGEMENT
8104    // =========================================================
8105
8106    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8107            boolean isolated) {
8108        String proc = customProcess != null ? customProcess : info.processName;
8109        BatteryStatsImpl.Uid.Proc ps = null;
8110        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8111        int uid = info.uid;
8112        if (isolated) {
8113            int userId = UserHandle.getUserId(uid);
8114            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8115            while (true) {
8116                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8117                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8118                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8119                }
8120                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8121                mNextIsolatedProcessUid++;
8122                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8123                    // No process for this uid, use it.
8124                    break;
8125                }
8126                stepsLeft--;
8127                if (stepsLeft <= 0) {
8128                    return null;
8129                }
8130            }
8131        }
8132        return new ProcessRecord(stats, info, proc, uid);
8133    }
8134
8135    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8136        ProcessRecord app;
8137        if (!isolated) {
8138            app = getProcessRecordLocked(info.processName, info.uid, true);
8139        } else {
8140            app = null;
8141        }
8142
8143        if (app == null) {
8144            app = newProcessRecordLocked(info, null, isolated);
8145            mProcessNames.put(info.processName, app.uid, app);
8146            if (isolated) {
8147                mIsolatedProcesses.put(app.uid, app);
8148            }
8149            updateLruProcessLocked(app, false, null);
8150            updateOomAdjLocked();
8151        }
8152
8153        // This package really, really can not be stopped.
8154        try {
8155            AppGlobals.getPackageManager().setPackageStoppedState(
8156                    info.packageName, false, UserHandle.getUserId(app.uid));
8157        } catch (RemoteException e) {
8158        } catch (IllegalArgumentException e) {
8159            Slog.w(TAG, "Failed trying to unstop package "
8160                    + info.packageName + ": " + e);
8161        }
8162
8163        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8164                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8165            app.persistent = true;
8166            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8167        }
8168        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8169            mPersistentStartingProcesses.add(app);
8170            startProcessLocked(app, "added application", app.processName);
8171        }
8172
8173        return app;
8174    }
8175
8176    public void unhandledBack() {
8177        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8178                "unhandledBack()");
8179
8180        synchronized(this) {
8181            final long origId = Binder.clearCallingIdentity();
8182            try {
8183                getFocusedStack().unhandledBackLocked();
8184            } finally {
8185                Binder.restoreCallingIdentity(origId);
8186            }
8187        }
8188    }
8189
8190    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8191        enforceNotIsolatedCaller("openContentUri");
8192        final int userId = UserHandle.getCallingUserId();
8193        String name = uri.getAuthority();
8194        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8195        ParcelFileDescriptor pfd = null;
8196        if (cph != null) {
8197            // We record the binder invoker's uid in thread-local storage before
8198            // going to the content provider to open the file.  Later, in the code
8199            // that handles all permissions checks, we look for this uid and use
8200            // that rather than the Activity Manager's own uid.  The effect is that
8201            // we do the check against the caller's permissions even though it looks
8202            // to the content provider like the Activity Manager itself is making
8203            // the request.
8204            sCallerIdentity.set(new Identity(
8205                    Binder.getCallingPid(), Binder.getCallingUid()));
8206            try {
8207                pfd = cph.provider.openFile(null, uri, "r", null);
8208            } catch (FileNotFoundException e) {
8209                // do nothing; pfd will be returned null
8210            } finally {
8211                // Ensure that whatever happens, we clean up the identity state
8212                sCallerIdentity.remove();
8213            }
8214
8215            // We've got the fd now, so we're done with the provider.
8216            removeContentProviderExternalUnchecked(name, null, userId);
8217        } else {
8218            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8219        }
8220        return pfd;
8221    }
8222
8223    // Actually is sleeping or shutting down or whatever else in the future
8224    // is an inactive state.
8225    public boolean isSleepingOrShuttingDown() {
8226        return mSleeping || mShuttingDown;
8227    }
8228
8229    public void goingToSleep() {
8230        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8231                != PackageManager.PERMISSION_GRANTED) {
8232            throw new SecurityException("Requires permission "
8233                    + android.Manifest.permission.DEVICE_POWER);
8234        }
8235
8236        synchronized(this) {
8237            mWentToSleep = true;
8238            updateEventDispatchingLocked();
8239
8240            if (!mSleeping) {
8241                mSleeping = true;
8242                mStackSupervisor.goingToSleepLocked();
8243
8244                // Initialize the wake times of all processes.
8245                checkExcessivePowerUsageLocked(false);
8246                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8247                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8248                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8249            }
8250        }
8251    }
8252
8253    @Override
8254    public boolean shutdown(int timeout) {
8255        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8256                != PackageManager.PERMISSION_GRANTED) {
8257            throw new SecurityException("Requires permission "
8258                    + android.Manifest.permission.SHUTDOWN);
8259        }
8260
8261        boolean timedout = false;
8262
8263        synchronized(this) {
8264            mShuttingDown = true;
8265            updateEventDispatchingLocked();
8266            timedout = mStackSupervisor.shutdownLocked(timeout);
8267        }
8268
8269        mAppOpsService.shutdown();
8270        mUsageStatsService.shutdown();
8271        mBatteryStatsService.shutdown();
8272        synchronized (this) {
8273            mProcessStats.shutdownLocked();
8274        }
8275
8276        return timedout;
8277    }
8278
8279    public final void activitySlept(IBinder token) {
8280        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8281
8282        final long origId = Binder.clearCallingIdentity();
8283
8284        synchronized (this) {
8285            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8286            if (r != null) {
8287                mStackSupervisor.activitySleptLocked(r);
8288            }
8289        }
8290
8291        Binder.restoreCallingIdentity(origId);
8292    }
8293
8294    void logLockScreen(String msg) {
8295        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8296                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8297                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8298                mStackSupervisor.mDismissKeyguardOnNextActivity);
8299    }
8300
8301    private void comeOutOfSleepIfNeededLocked() {
8302        if (!mWentToSleep && !mLockScreenShown) {
8303            if (mSleeping) {
8304                mSleeping = false;
8305                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8306            }
8307        }
8308    }
8309
8310    public void wakingUp() {
8311        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8312                != PackageManager.PERMISSION_GRANTED) {
8313            throw new SecurityException("Requires permission "
8314                    + android.Manifest.permission.DEVICE_POWER);
8315        }
8316
8317        synchronized(this) {
8318            mWentToSleep = false;
8319            updateEventDispatchingLocked();
8320            comeOutOfSleepIfNeededLocked();
8321        }
8322    }
8323
8324    private void updateEventDispatchingLocked() {
8325        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8326    }
8327
8328    public void setLockScreenShown(boolean shown) {
8329        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8330                != PackageManager.PERMISSION_GRANTED) {
8331            throw new SecurityException("Requires permission "
8332                    + android.Manifest.permission.DEVICE_POWER);
8333        }
8334
8335        synchronized(this) {
8336            long ident = Binder.clearCallingIdentity();
8337            try {
8338                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8339                mLockScreenShown = shown;
8340                comeOutOfSleepIfNeededLocked();
8341            } finally {
8342                Binder.restoreCallingIdentity(ident);
8343            }
8344        }
8345    }
8346
8347    public void stopAppSwitches() {
8348        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8349                != PackageManager.PERMISSION_GRANTED) {
8350            throw new SecurityException("Requires permission "
8351                    + android.Manifest.permission.STOP_APP_SWITCHES);
8352        }
8353
8354        synchronized(this) {
8355            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8356                    + APP_SWITCH_DELAY_TIME;
8357            mDidAppSwitch = false;
8358            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8359            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8360            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8361        }
8362    }
8363
8364    public void resumeAppSwitches() {
8365        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8366                != PackageManager.PERMISSION_GRANTED) {
8367            throw new SecurityException("Requires permission "
8368                    + android.Manifest.permission.STOP_APP_SWITCHES);
8369        }
8370
8371        synchronized(this) {
8372            // Note that we don't execute any pending app switches... we will
8373            // let those wait until either the timeout, or the next start
8374            // activity request.
8375            mAppSwitchesAllowedTime = 0;
8376        }
8377    }
8378
8379    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8380            String name) {
8381        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8382            return true;
8383        }
8384
8385        final int perm = checkComponentPermission(
8386                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8387                callingUid, -1, true);
8388        if (perm == PackageManager.PERMISSION_GRANTED) {
8389            return true;
8390        }
8391
8392        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8393        return false;
8394    }
8395
8396    public void setDebugApp(String packageName, boolean waitForDebugger,
8397            boolean persistent) {
8398        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8399                "setDebugApp()");
8400
8401        long ident = Binder.clearCallingIdentity();
8402        try {
8403            // Note that this is not really thread safe if there are multiple
8404            // callers into it at the same time, but that's not a situation we
8405            // care about.
8406            if (persistent) {
8407                final ContentResolver resolver = mContext.getContentResolver();
8408                Settings.Global.putString(
8409                    resolver, Settings.Global.DEBUG_APP,
8410                    packageName);
8411                Settings.Global.putInt(
8412                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8413                    waitForDebugger ? 1 : 0);
8414            }
8415
8416            synchronized (this) {
8417                if (!persistent) {
8418                    mOrigDebugApp = mDebugApp;
8419                    mOrigWaitForDebugger = mWaitForDebugger;
8420                }
8421                mDebugApp = packageName;
8422                mWaitForDebugger = waitForDebugger;
8423                mDebugTransient = !persistent;
8424                if (packageName != null) {
8425                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8426                            false, UserHandle.USER_ALL, "set debug app");
8427                }
8428            }
8429        } finally {
8430            Binder.restoreCallingIdentity(ident);
8431        }
8432    }
8433
8434    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8435        synchronized (this) {
8436            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8437            if (!isDebuggable) {
8438                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8439                    throw new SecurityException("Process not debuggable: " + app.packageName);
8440                }
8441            }
8442
8443            mOpenGlTraceApp = processName;
8444        }
8445    }
8446
8447    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8448            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8449        synchronized (this) {
8450            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8451            if (!isDebuggable) {
8452                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8453                    throw new SecurityException("Process not debuggable: " + app.packageName);
8454                }
8455            }
8456            mProfileApp = processName;
8457            mProfileFile = profileFile;
8458            if (mProfileFd != null) {
8459                try {
8460                    mProfileFd.close();
8461                } catch (IOException e) {
8462                }
8463                mProfileFd = null;
8464            }
8465            mProfileFd = profileFd;
8466            mProfileType = 0;
8467            mAutoStopProfiler = autoStopProfiler;
8468        }
8469    }
8470
8471    @Override
8472    public void setAlwaysFinish(boolean enabled) {
8473        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8474                "setAlwaysFinish()");
8475
8476        Settings.Global.putInt(
8477                mContext.getContentResolver(),
8478                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8479
8480        synchronized (this) {
8481            mAlwaysFinishActivities = enabled;
8482        }
8483    }
8484
8485    @Override
8486    public void setActivityController(IActivityController controller) {
8487        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8488                "setActivityController()");
8489        synchronized (this) {
8490            mController = controller;
8491            Watchdog.getInstance().setActivityController(controller);
8492        }
8493    }
8494
8495    @Override
8496    public void setUserIsMonkey(boolean userIsMonkey) {
8497        synchronized (this) {
8498            synchronized (mPidsSelfLocked) {
8499                final int callingPid = Binder.getCallingPid();
8500                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8501                if (precessRecord == null) {
8502                    throw new SecurityException("Unknown process: " + callingPid);
8503                }
8504                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8505                    throw new SecurityException("Only an instrumentation process "
8506                            + "with a UiAutomation can call setUserIsMonkey");
8507                }
8508            }
8509            mUserIsMonkey = userIsMonkey;
8510        }
8511    }
8512
8513    @Override
8514    public boolean isUserAMonkey() {
8515        synchronized (this) {
8516            // If there is a controller also implies the user is a monkey.
8517            return (mUserIsMonkey || mController != null);
8518        }
8519    }
8520
8521    public void requestBugReport() {
8522        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8523        SystemProperties.set("ctl.start", "bugreport");
8524    }
8525
8526    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8527        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8528    }
8529
8530    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8531        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8532            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8533        }
8534        return KEY_DISPATCHING_TIMEOUT;
8535    }
8536
8537    @Override
8538    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8539        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8540                != PackageManager.PERMISSION_GRANTED) {
8541            throw new SecurityException("Requires permission "
8542                    + android.Manifest.permission.FILTER_EVENTS);
8543        }
8544        ProcessRecord proc;
8545        long timeout;
8546        synchronized (this) {
8547            synchronized (mPidsSelfLocked) {
8548                proc = mPidsSelfLocked.get(pid);
8549            }
8550            timeout = getInputDispatchingTimeoutLocked(proc);
8551        }
8552
8553        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8554            return -1;
8555        }
8556
8557        return timeout;
8558    }
8559
8560    /**
8561     * Handle input dispatching timeouts.
8562     * Returns whether input dispatching should be aborted or not.
8563     */
8564    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8565            final ActivityRecord activity, final ActivityRecord parent,
8566            final boolean aboveSystem, String reason) {
8567        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8568                != PackageManager.PERMISSION_GRANTED) {
8569            throw new SecurityException("Requires permission "
8570                    + android.Manifest.permission.FILTER_EVENTS);
8571        }
8572
8573        final String annotation;
8574        if (reason == null) {
8575            annotation = "Input dispatching timed out";
8576        } else {
8577            annotation = "Input dispatching timed out (" + reason + ")";
8578        }
8579
8580        if (proc != null) {
8581            synchronized (this) {
8582                if (proc.debugging) {
8583                    return false;
8584                }
8585
8586                if (mDidDexOpt) {
8587                    // Give more time since we were dexopting.
8588                    mDidDexOpt = false;
8589                    return false;
8590                }
8591
8592                if (proc.instrumentationClass != null) {
8593                    Bundle info = new Bundle();
8594                    info.putString("shortMsg", "keyDispatchingTimedOut");
8595                    info.putString("longMsg", annotation);
8596                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8597                    return true;
8598                }
8599            }
8600            mHandler.post(new Runnable() {
8601                @Override
8602                public void run() {
8603                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8604                }
8605            });
8606        }
8607
8608        return true;
8609    }
8610
8611    public Bundle getAssistContextExtras(int requestType) {
8612        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8613                "getAssistContextExtras()");
8614        PendingAssistExtras pae;
8615        Bundle extras = new Bundle();
8616        synchronized (this) {
8617            ActivityRecord activity = getFocusedStack().mResumedActivity;
8618            if (activity == null) {
8619                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8620                return null;
8621            }
8622            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8623            if (activity.app == null || activity.app.thread == null) {
8624                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8625                return extras;
8626            }
8627            if (activity.app.pid == Binder.getCallingPid()) {
8628                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8629                return extras;
8630            }
8631            pae = new PendingAssistExtras(activity);
8632            try {
8633                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8634                        requestType);
8635                mPendingAssistExtras.add(pae);
8636                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8637            } catch (RemoteException e) {
8638                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8639                return extras;
8640            }
8641        }
8642        synchronized (pae) {
8643            while (!pae.haveResult) {
8644                try {
8645                    pae.wait();
8646                } catch (InterruptedException e) {
8647                }
8648            }
8649            if (pae.result != null) {
8650                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8651            }
8652        }
8653        synchronized (this) {
8654            mPendingAssistExtras.remove(pae);
8655            mHandler.removeCallbacks(pae);
8656        }
8657        return extras;
8658    }
8659
8660    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8661        PendingAssistExtras pae = (PendingAssistExtras)token;
8662        synchronized (pae) {
8663            pae.result = extras;
8664            pae.haveResult = true;
8665            pae.notifyAll();
8666        }
8667    }
8668
8669    public void registerProcessObserver(IProcessObserver observer) {
8670        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8671                "registerProcessObserver()");
8672        synchronized (this) {
8673            mProcessObservers.register(observer);
8674        }
8675    }
8676
8677    @Override
8678    public void unregisterProcessObserver(IProcessObserver observer) {
8679        synchronized (this) {
8680            mProcessObservers.unregister(observer);
8681        }
8682    }
8683
8684    @Override
8685    public boolean convertFromTranslucent(IBinder token) {
8686        final long origId = Binder.clearCallingIdentity();
8687        try {
8688            synchronized (this) {
8689                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8690                if (r == null) {
8691                    return false;
8692                }
8693                if (r.changeWindowTranslucency(true)) {
8694                    mWindowManager.setAppFullscreen(token, true);
8695                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8696                    return true;
8697                }
8698                return false;
8699            }
8700        } finally {
8701            Binder.restoreCallingIdentity(origId);
8702        }
8703    }
8704
8705    @Override
8706    public boolean convertToTranslucent(IBinder token) {
8707        final long origId = Binder.clearCallingIdentity();
8708        try {
8709            synchronized (this) {
8710                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8711                if (r == null) {
8712                    return false;
8713                }
8714                if (r.changeWindowTranslucency(false)) {
8715                    r.task.stack.convertToTranslucent(r);
8716                    mWindowManager.setAppFullscreen(token, false);
8717                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8718                    return true;
8719                }
8720                return false;
8721            }
8722        } finally {
8723            Binder.restoreCallingIdentity(origId);
8724        }
8725    }
8726
8727    @Override
8728    public void setImmersive(IBinder token, boolean immersive) {
8729        synchronized(this) {
8730            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8731            if (r == null) {
8732                throw new IllegalArgumentException();
8733            }
8734            r.immersive = immersive;
8735
8736            // update associated state if we're frontmost
8737            if (r == mFocusedActivity) {
8738                if (DEBUG_IMMERSIVE) {
8739                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8740                }
8741                applyUpdateLockStateLocked(r);
8742            }
8743        }
8744    }
8745
8746    @Override
8747    public boolean isImmersive(IBinder token) {
8748        synchronized (this) {
8749            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8750            if (r == null) {
8751                throw new IllegalArgumentException();
8752            }
8753            return r.immersive;
8754        }
8755    }
8756
8757    public boolean isTopActivityImmersive() {
8758        enforceNotIsolatedCaller("startActivity");
8759        synchronized (this) {
8760            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8761            return (r != null) ? r.immersive : false;
8762        }
8763    }
8764
8765    public final void enterSafeMode() {
8766        synchronized(this) {
8767            // It only makes sense to do this before the system is ready
8768            // and started launching other packages.
8769            if (!mSystemReady) {
8770                try {
8771                    AppGlobals.getPackageManager().enterSafeMode();
8772                } catch (RemoteException e) {
8773                }
8774            }
8775        }
8776    }
8777
8778    public final void showSafeModeOverlay() {
8779        View v = LayoutInflater.from(mContext).inflate(
8780                com.android.internal.R.layout.safe_mode, null);
8781        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8782        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8783        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8784        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8785        lp.gravity = Gravity.BOTTOM | Gravity.START;
8786        lp.format = v.getBackground().getOpacity();
8787        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8788                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8789        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8790        ((WindowManager)mContext.getSystemService(
8791                Context.WINDOW_SERVICE)).addView(v, lp);
8792    }
8793
8794    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8795        if (!(sender instanceof PendingIntentRecord)) {
8796            return;
8797        }
8798        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8799        synchronized (stats) {
8800            if (mBatteryStatsService.isOnBattery()) {
8801                mBatteryStatsService.enforceCallingPermission();
8802                PendingIntentRecord rec = (PendingIntentRecord)sender;
8803                int MY_UID = Binder.getCallingUid();
8804                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8805                BatteryStatsImpl.Uid.Pkg pkg =
8806                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8807                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8808                pkg.incWakeupsLocked();
8809            }
8810        }
8811    }
8812
8813    public boolean killPids(int[] pids, String pReason, boolean secure) {
8814        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8815            throw new SecurityException("killPids only available to the system");
8816        }
8817        String reason = (pReason == null) ? "Unknown" : pReason;
8818        // XXX Note: don't acquire main activity lock here, because the window
8819        // manager calls in with its locks held.
8820
8821        boolean killed = false;
8822        synchronized (mPidsSelfLocked) {
8823            int[] types = new int[pids.length];
8824            int worstType = 0;
8825            for (int i=0; i<pids.length; i++) {
8826                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8827                if (proc != null) {
8828                    int type = proc.setAdj;
8829                    types[i] = type;
8830                    if (type > worstType) {
8831                        worstType = type;
8832                    }
8833                }
8834            }
8835
8836            // If the worst oom_adj is somewhere in the cached proc LRU range,
8837            // then constrain it so we will kill all cached procs.
8838            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8839                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8840                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8841            }
8842
8843            // If this is not a secure call, don't let it kill processes that
8844            // are important.
8845            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8846                worstType = ProcessList.SERVICE_ADJ;
8847            }
8848
8849            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8850            for (int i=0; i<pids.length; i++) {
8851                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8852                if (proc == null) {
8853                    continue;
8854                }
8855                int adj = proc.setAdj;
8856                if (adj >= worstType && !proc.killedByAm) {
8857                    killUnneededProcessLocked(proc, reason);
8858                    killed = true;
8859                }
8860            }
8861        }
8862        return killed;
8863    }
8864
8865    @Override
8866    public void killUid(int uid, String reason) {
8867        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8868            throw new SecurityException("killUid only available to the system");
8869        }
8870        synchronized (this) {
8871            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8872                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8873                    reason != null ? reason : "kill uid");
8874        }
8875    }
8876
8877    @Override
8878    public boolean killProcessesBelowForeground(String reason) {
8879        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8880            throw new SecurityException("killProcessesBelowForeground() only available to system");
8881        }
8882
8883        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8884    }
8885
8886    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8887        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8888            throw new SecurityException("killProcessesBelowAdj() only available to system");
8889        }
8890
8891        boolean killed = false;
8892        synchronized (mPidsSelfLocked) {
8893            final int size = mPidsSelfLocked.size();
8894            for (int i = 0; i < size; i++) {
8895                final int pid = mPidsSelfLocked.keyAt(i);
8896                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8897                if (proc == null) continue;
8898
8899                final int adj = proc.setAdj;
8900                if (adj > belowAdj && !proc.killedByAm) {
8901                    killUnneededProcessLocked(proc, reason);
8902                    killed = true;
8903                }
8904            }
8905        }
8906        return killed;
8907    }
8908
8909    @Override
8910    public void hang(final IBinder who, boolean allowRestart) {
8911        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8912                != PackageManager.PERMISSION_GRANTED) {
8913            throw new SecurityException("Requires permission "
8914                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8915        }
8916
8917        final IBinder.DeathRecipient death = new DeathRecipient() {
8918            @Override
8919            public void binderDied() {
8920                synchronized (this) {
8921                    notifyAll();
8922                }
8923            }
8924        };
8925
8926        try {
8927            who.linkToDeath(death, 0);
8928        } catch (RemoteException e) {
8929            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8930            return;
8931        }
8932
8933        synchronized (this) {
8934            Watchdog.getInstance().setAllowRestart(allowRestart);
8935            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8936            synchronized (death) {
8937                while (who.isBinderAlive()) {
8938                    try {
8939                        death.wait();
8940                    } catch (InterruptedException e) {
8941                    }
8942                }
8943            }
8944            Watchdog.getInstance().setAllowRestart(true);
8945        }
8946    }
8947
8948    @Override
8949    public void restart() {
8950        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8951                != PackageManager.PERMISSION_GRANTED) {
8952            throw new SecurityException("Requires permission "
8953                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8954        }
8955
8956        Log.i(TAG, "Sending shutdown broadcast...");
8957
8958        BroadcastReceiver br = new BroadcastReceiver() {
8959            @Override public void onReceive(Context context, Intent intent) {
8960                // Now the broadcast is done, finish up the low-level shutdown.
8961                Log.i(TAG, "Shutting down activity manager...");
8962                shutdown(10000);
8963                Log.i(TAG, "Shutdown complete, restarting!");
8964                Process.killProcess(Process.myPid());
8965                System.exit(10);
8966            }
8967        };
8968
8969        // First send the high-level shut down broadcast.
8970        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8971        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8972        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8973        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8974        mContext.sendOrderedBroadcastAsUser(intent,
8975                UserHandle.ALL, null, br, mHandler, 0, null, null);
8976        */
8977        br.onReceive(mContext, intent);
8978    }
8979
8980    private long getLowRamTimeSinceIdle(long now) {
8981        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8982    }
8983
8984    @Override
8985    public void performIdleMaintenance() {
8986        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8987                != PackageManager.PERMISSION_GRANTED) {
8988            throw new SecurityException("Requires permission "
8989                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8990        }
8991
8992        synchronized (this) {
8993            final long now = SystemClock.uptimeMillis();
8994            final long timeSinceLastIdle = now - mLastIdleTime;
8995            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8996            mLastIdleTime = now;
8997            mLowRamTimeSinceLastIdle = 0;
8998            if (mLowRamStartTime != 0) {
8999                mLowRamStartTime = now;
9000            }
9001
9002            StringBuilder sb = new StringBuilder(128);
9003            sb.append("Idle maintenance over ");
9004            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9005            sb.append(" low RAM for ");
9006            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9007            Slog.i(TAG, sb.toString());
9008
9009            // If at least 1/3 of our time since the last idle period has been spent
9010            // with RAM low, then we want to kill processes.
9011            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9012
9013            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9014                ProcessRecord proc = mLruProcesses.get(i);
9015                if (proc.notCachedSinceIdle) {
9016                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9017                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9018                        if (doKilling && proc.initialIdlePss != 0
9019                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9020                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9021                                    + " from " + proc.initialIdlePss + ")");
9022                        }
9023                    }
9024                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9025                    proc.notCachedSinceIdle = true;
9026                    proc.initialIdlePss = 0;
9027                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9028                            mSleeping, now);
9029                }
9030            }
9031
9032            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9033            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9034        }
9035    }
9036
9037    public final void startRunning(String pkg, String cls, String action,
9038            String data) {
9039        synchronized(this) {
9040            if (mStartRunning) {
9041                return;
9042            }
9043            mStartRunning = true;
9044            mTopComponent = pkg != null && cls != null
9045                    ? new ComponentName(pkg, cls) : null;
9046            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9047            mTopData = data;
9048            if (!mSystemReady) {
9049                return;
9050            }
9051        }
9052
9053        systemReady(null);
9054    }
9055
9056    private void retrieveSettings() {
9057        final ContentResolver resolver = mContext.getContentResolver();
9058        String debugApp = Settings.Global.getString(
9059            resolver, Settings.Global.DEBUG_APP);
9060        boolean waitForDebugger = Settings.Global.getInt(
9061            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9062        boolean alwaysFinishActivities = Settings.Global.getInt(
9063            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9064        boolean forceRtl = Settings.Global.getInt(
9065                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9066        // Transfer any global setting for forcing RTL layout, into a System Property
9067        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9068
9069        Configuration configuration = new Configuration();
9070        Settings.System.getConfiguration(resolver, configuration);
9071        if (forceRtl) {
9072            // This will take care of setting the correct layout direction flags
9073            configuration.setLayoutDirection(configuration.locale);
9074        }
9075
9076        synchronized (this) {
9077            mDebugApp = mOrigDebugApp = debugApp;
9078            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9079            mAlwaysFinishActivities = alwaysFinishActivities;
9080            // This happens before any activities are started, so we can
9081            // change mConfiguration in-place.
9082            updateConfigurationLocked(configuration, null, false, true);
9083            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9084        }
9085    }
9086
9087    public boolean testIsSystemReady() {
9088        // no need to synchronize(this) just to read & return the value
9089        return mSystemReady;
9090    }
9091
9092    private static File getCalledPreBootReceiversFile() {
9093        File dataDir = Environment.getDataDirectory();
9094        File systemDir = new File(dataDir, "system");
9095        File fname = new File(systemDir, "called_pre_boots.dat");
9096        return fname;
9097    }
9098
9099    static final int LAST_DONE_VERSION = 10000;
9100
9101    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9102        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9103        File file = getCalledPreBootReceiversFile();
9104        FileInputStream fis = null;
9105        try {
9106            fis = new FileInputStream(file);
9107            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9108            int fvers = dis.readInt();
9109            if (fvers == LAST_DONE_VERSION) {
9110                String vers = dis.readUTF();
9111                String codename = dis.readUTF();
9112                String build = dis.readUTF();
9113                if (android.os.Build.VERSION.RELEASE.equals(vers)
9114                        && android.os.Build.VERSION.CODENAME.equals(codename)
9115                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9116                    int num = dis.readInt();
9117                    while (num > 0) {
9118                        num--;
9119                        String pkg = dis.readUTF();
9120                        String cls = dis.readUTF();
9121                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9122                    }
9123                }
9124            }
9125        } catch (FileNotFoundException e) {
9126        } catch (IOException e) {
9127            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9128        } finally {
9129            if (fis != null) {
9130                try {
9131                    fis.close();
9132                } catch (IOException e) {
9133                }
9134            }
9135        }
9136        return lastDoneReceivers;
9137    }
9138
9139    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9140        File file = getCalledPreBootReceiversFile();
9141        FileOutputStream fos = null;
9142        DataOutputStream dos = null;
9143        try {
9144            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9145            fos = new FileOutputStream(file);
9146            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9147            dos.writeInt(LAST_DONE_VERSION);
9148            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9149            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9150            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9151            dos.writeInt(list.size());
9152            for (int i=0; i<list.size(); i++) {
9153                dos.writeUTF(list.get(i).getPackageName());
9154                dos.writeUTF(list.get(i).getClassName());
9155            }
9156        } catch (IOException e) {
9157            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9158            file.delete();
9159        } finally {
9160            FileUtils.sync(fos);
9161            if (dos != null) {
9162                try {
9163                    dos.close();
9164                } catch (IOException e) {
9165                    // TODO Auto-generated catch block
9166                    e.printStackTrace();
9167                }
9168            }
9169        }
9170    }
9171
9172    public void systemReady(final Runnable goingCallback) {
9173        synchronized(this) {
9174            if (mSystemReady) {
9175                if (goingCallback != null) goingCallback.run();
9176                return;
9177            }
9178
9179            // Check to see if there are any update receivers to run.
9180            if (!mDidUpdate) {
9181                if (mWaitingUpdate) {
9182                    return;
9183                }
9184                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9185                List<ResolveInfo> ris = null;
9186                try {
9187                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9188                            intent, null, 0, 0);
9189                } catch (RemoteException e) {
9190                }
9191                if (ris != null) {
9192                    for (int i=ris.size()-1; i>=0; i--) {
9193                        if ((ris.get(i).activityInfo.applicationInfo.flags
9194                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9195                            ris.remove(i);
9196                        }
9197                    }
9198                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9199
9200                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9201
9202                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9203                    for (int i=0; i<ris.size(); i++) {
9204                        ActivityInfo ai = ris.get(i).activityInfo;
9205                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9206                        if (lastDoneReceivers.contains(comp)) {
9207                            ris.remove(i);
9208                            i--;
9209                        }
9210                    }
9211
9212                    final int[] users = getUsersLocked();
9213                    for (int i=0; i<ris.size(); i++) {
9214                        ActivityInfo ai = ris.get(i).activityInfo;
9215                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9216                        doneReceivers.add(comp);
9217                        intent.setComponent(comp);
9218                        for (int j=0; j<users.length; j++) {
9219                            IIntentReceiver finisher = null;
9220                            if (i == ris.size()-1 && j == users.length-1) {
9221                                finisher = new IIntentReceiver.Stub() {
9222                                    public void performReceive(Intent intent, int resultCode,
9223                                            String data, Bundle extras, boolean ordered,
9224                                            boolean sticky, int sendingUser) {
9225                                        // The raw IIntentReceiver interface is called
9226                                        // with the AM lock held, so redispatch to
9227                                        // execute our code without the lock.
9228                                        mHandler.post(new Runnable() {
9229                                            public void run() {
9230                                                synchronized (ActivityManagerService.this) {
9231                                                    mDidUpdate = true;
9232                                                }
9233                                                writeLastDonePreBootReceivers(doneReceivers);
9234                                                showBootMessage(mContext.getText(
9235                                                        R.string.android_upgrading_complete),
9236                                                        false);
9237                                                systemReady(goingCallback);
9238                                            }
9239                                        });
9240                                    }
9241                                };
9242                            }
9243                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9244                                    + " for user " + users[j]);
9245                            broadcastIntentLocked(null, null, intent, null, finisher,
9246                                    0, null, null, null, AppOpsManager.OP_NONE,
9247                                    true, false, MY_PID, Process.SYSTEM_UID,
9248                                    users[j]);
9249                            if (finisher != null) {
9250                                mWaitingUpdate = true;
9251                            }
9252                        }
9253                    }
9254                }
9255                if (mWaitingUpdate) {
9256                    return;
9257                }
9258                mDidUpdate = true;
9259            }
9260
9261            mAppOpsService.systemReady();
9262            mSystemReady = true;
9263            if (!mStartRunning) {
9264                return;
9265            }
9266        }
9267
9268        ArrayList<ProcessRecord> procsToKill = null;
9269        synchronized(mPidsSelfLocked) {
9270            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9271                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9272                if (!isAllowedWhileBooting(proc.info)){
9273                    if (procsToKill == null) {
9274                        procsToKill = new ArrayList<ProcessRecord>();
9275                    }
9276                    procsToKill.add(proc);
9277                }
9278            }
9279        }
9280
9281        synchronized(this) {
9282            if (procsToKill != null) {
9283                for (int i=procsToKill.size()-1; i>=0; i--) {
9284                    ProcessRecord proc = procsToKill.get(i);
9285                    Slog.i(TAG, "Removing system update proc: " + proc);
9286                    removeProcessLocked(proc, true, false, "system update done");
9287                }
9288            }
9289
9290            // Now that we have cleaned up any update processes, we
9291            // are ready to start launching real processes and know that
9292            // we won't trample on them any more.
9293            mProcessesReady = true;
9294        }
9295
9296        Slog.i(TAG, "System now ready");
9297        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9298            SystemClock.uptimeMillis());
9299
9300        synchronized(this) {
9301            // Make sure we have no pre-ready processes sitting around.
9302
9303            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9304                ResolveInfo ri = mContext.getPackageManager()
9305                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9306                                STOCK_PM_FLAGS);
9307                CharSequence errorMsg = null;
9308                if (ri != null) {
9309                    ActivityInfo ai = ri.activityInfo;
9310                    ApplicationInfo app = ai.applicationInfo;
9311                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9312                        mTopAction = Intent.ACTION_FACTORY_TEST;
9313                        mTopData = null;
9314                        mTopComponent = new ComponentName(app.packageName,
9315                                ai.name);
9316                    } else {
9317                        errorMsg = mContext.getResources().getText(
9318                                com.android.internal.R.string.factorytest_not_system);
9319                    }
9320                } else {
9321                    errorMsg = mContext.getResources().getText(
9322                            com.android.internal.R.string.factorytest_no_action);
9323                }
9324                if (errorMsg != null) {
9325                    mTopAction = null;
9326                    mTopData = null;
9327                    mTopComponent = null;
9328                    Message msg = Message.obtain();
9329                    msg.what = SHOW_FACTORY_ERROR_MSG;
9330                    msg.getData().putCharSequence("msg", errorMsg);
9331                    mHandler.sendMessage(msg);
9332                }
9333            }
9334        }
9335
9336        retrieveSettings();
9337
9338        synchronized (this) {
9339            readGrantedUriPermissionsLocked();
9340        }
9341
9342        if (goingCallback != null) goingCallback.run();
9343
9344        synchronized (this) {
9345            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9346                try {
9347                    List apps = AppGlobals.getPackageManager().
9348                        getPersistentApplications(STOCK_PM_FLAGS);
9349                    if (apps != null) {
9350                        int N = apps.size();
9351                        int i;
9352                        for (i=0; i<N; i++) {
9353                            ApplicationInfo info
9354                                = (ApplicationInfo)apps.get(i);
9355                            if (info != null &&
9356                                    !info.packageName.equals("android")) {
9357                                addAppLocked(info, false);
9358                            }
9359                        }
9360                    }
9361                } catch (RemoteException ex) {
9362                    // pm is in same process, this will never happen.
9363                }
9364            }
9365
9366            // Start up initial activity.
9367            mBooting = true;
9368
9369            try {
9370                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9371                    Message msg = Message.obtain();
9372                    msg.what = SHOW_UID_ERROR_MSG;
9373                    mHandler.sendMessage(msg);
9374                }
9375            } catch (RemoteException e) {
9376            }
9377
9378            long ident = Binder.clearCallingIdentity();
9379            try {
9380                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9381                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9382                        | Intent.FLAG_RECEIVER_FOREGROUND);
9383                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9384                broadcastIntentLocked(null, null, intent,
9385                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9386                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9387                intent = new Intent(Intent.ACTION_USER_STARTING);
9388                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9389                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9390                broadcastIntentLocked(null, null, intent,
9391                        null, new IIntentReceiver.Stub() {
9392                            @Override
9393                            public void performReceive(Intent intent, int resultCode, String data,
9394                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9395                                    throws RemoteException {
9396                            }
9397                        }, 0, null, null,
9398                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9399                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9400            } finally {
9401                Binder.restoreCallingIdentity(ident);
9402            }
9403            mStackSupervisor.resumeTopActivitiesLocked();
9404            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9405        }
9406    }
9407
9408    private boolean makeAppCrashingLocked(ProcessRecord app,
9409            String shortMsg, String longMsg, String stackTrace) {
9410        app.crashing = true;
9411        app.crashingReport = generateProcessError(app,
9412                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9413        startAppProblemLocked(app);
9414        app.stopFreezingAllLocked();
9415        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9416    }
9417
9418    private void makeAppNotRespondingLocked(ProcessRecord app,
9419            String activity, String shortMsg, String longMsg) {
9420        app.notResponding = true;
9421        app.notRespondingReport = generateProcessError(app,
9422                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9423                activity, shortMsg, longMsg, null);
9424        startAppProblemLocked(app);
9425        app.stopFreezingAllLocked();
9426    }
9427
9428    /**
9429     * Generate a process error record, suitable for attachment to a ProcessRecord.
9430     *
9431     * @param app The ProcessRecord in which the error occurred.
9432     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9433     *                      ActivityManager.AppErrorStateInfo
9434     * @param activity The activity associated with the crash, if known.
9435     * @param shortMsg Short message describing the crash.
9436     * @param longMsg Long message describing the crash.
9437     * @param stackTrace Full crash stack trace, may be null.
9438     *
9439     * @return Returns a fully-formed AppErrorStateInfo record.
9440     */
9441    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9442            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9443        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9444
9445        report.condition = condition;
9446        report.processName = app.processName;
9447        report.pid = app.pid;
9448        report.uid = app.info.uid;
9449        report.tag = activity;
9450        report.shortMsg = shortMsg;
9451        report.longMsg = longMsg;
9452        report.stackTrace = stackTrace;
9453
9454        return report;
9455    }
9456
9457    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9458        synchronized (this) {
9459            app.crashing = false;
9460            app.crashingReport = null;
9461            app.notResponding = false;
9462            app.notRespondingReport = null;
9463            if (app.anrDialog == fromDialog) {
9464                app.anrDialog = null;
9465            }
9466            if (app.waitDialog == fromDialog) {
9467                app.waitDialog = null;
9468            }
9469            if (app.pid > 0 && app.pid != MY_PID) {
9470                handleAppCrashLocked(app, null, null, null);
9471                killUnneededProcessLocked(app, "user request after error");
9472            }
9473        }
9474    }
9475
9476    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9477            String stackTrace) {
9478        long now = SystemClock.uptimeMillis();
9479
9480        Long crashTime;
9481        if (!app.isolated) {
9482            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9483        } else {
9484            crashTime = null;
9485        }
9486        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9487            // This process loses!
9488            Slog.w(TAG, "Process " + app.info.processName
9489                    + " has crashed too many times: killing!");
9490            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9491                    app.userId, app.info.processName, app.uid);
9492            mStackSupervisor.handleAppCrashLocked(app);
9493            if (!app.persistent) {
9494                // We don't want to start this process again until the user
9495                // explicitly does so...  but for persistent process, we really
9496                // need to keep it running.  If a persistent process is actually
9497                // repeatedly crashing, then badness for everyone.
9498                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9499                        app.info.processName);
9500                if (!app.isolated) {
9501                    // XXX We don't have a way to mark isolated processes
9502                    // as bad, since they don't have a peristent identity.
9503                    mBadProcesses.put(app.info.processName, app.uid,
9504                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9505                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9506                }
9507                app.bad = true;
9508                app.removed = true;
9509                // Don't let services in this process be restarted and potentially
9510                // annoy the user repeatedly.  Unless it is persistent, since those
9511                // processes run critical code.
9512                removeProcessLocked(app, false, false, "crash");
9513                mStackSupervisor.resumeTopActivitiesLocked();
9514                return false;
9515            }
9516            mStackSupervisor.resumeTopActivitiesLocked();
9517        } else {
9518            mStackSupervisor.finishTopRunningActivityLocked(app);
9519        }
9520
9521        // Bump up the crash count of any services currently running in the proc.
9522        for (int i=app.services.size()-1; i>=0; i--) {
9523            // Any services running in the application need to be placed
9524            // back in the pending list.
9525            ServiceRecord sr = app.services.valueAt(i);
9526            sr.crashCount++;
9527        }
9528
9529        // If the crashing process is what we consider to be the "home process" and it has been
9530        // replaced by a third-party app, clear the package preferred activities from packages
9531        // with a home activity running in the process to prevent a repeatedly crashing app
9532        // from blocking the user to manually clear the list.
9533        final ArrayList<ActivityRecord> activities = app.activities;
9534        if (app == mHomeProcess && activities.size() > 0
9535                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9536            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9537                final ActivityRecord r = activities.get(activityNdx);
9538                if (r.isHomeActivity()) {
9539                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9540                    try {
9541                        ActivityThread.getPackageManager()
9542                                .clearPackagePreferredActivities(r.packageName);
9543                    } catch (RemoteException c) {
9544                        // pm is in same process, this will never happen.
9545                    }
9546                }
9547            }
9548        }
9549
9550        if (!app.isolated) {
9551            // XXX Can't keep track of crash times for isolated processes,
9552            // because they don't have a perisistent identity.
9553            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9554        }
9555
9556        return true;
9557    }
9558
9559    void startAppProblemLocked(ProcessRecord app) {
9560        if (app.userId == mCurrentUserId) {
9561            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9562                    mContext, app.info.packageName, app.info.flags);
9563        } else {
9564            // If this app is not running under the current user, then we
9565            // can't give it a report button because that would require
9566            // launching the report UI under a different user.
9567            app.errorReportReceiver = null;
9568        }
9569        skipCurrentReceiverLocked(app);
9570    }
9571
9572    void skipCurrentReceiverLocked(ProcessRecord app) {
9573        for (BroadcastQueue queue : mBroadcastQueues) {
9574            queue.skipCurrentReceiverLocked(app);
9575        }
9576    }
9577
9578    /**
9579     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9580     * The application process will exit immediately after this call returns.
9581     * @param app object of the crashing app, null for the system server
9582     * @param crashInfo describing the exception
9583     */
9584    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9585        ProcessRecord r = findAppProcess(app, "Crash");
9586        final String processName = app == null ? "system_server"
9587                : (r == null ? "unknown" : r.processName);
9588
9589        handleApplicationCrashInner("crash", r, processName, crashInfo);
9590    }
9591
9592    /* Native crash reporting uses this inner version because it needs to be somewhat
9593     * decoupled from the AM-managed cleanup lifecycle
9594     */
9595    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9596            ApplicationErrorReport.CrashInfo crashInfo) {
9597        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9598                UserHandle.getUserId(Binder.getCallingUid()), processName,
9599                r == null ? -1 : r.info.flags,
9600                crashInfo.exceptionClassName,
9601                crashInfo.exceptionMessage,
9602                crashInfo.throwFileName,
9603                crashInfo.throwLineNumber);
9604
9605        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9606
9607        crashApplication(r, crashInfo);
9608    }
9609
9610    public void handleApplicationStrictModeViolation(
9611            IBinder app,
9612            int violationMask,
9613            StrictMode.ViolationInfo info) {
9614        ProcessRecord r = findAppProcess(app, "StrictMode");
9615        if (r == null) {
9616            return;
9617        }
9618
9619        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9620            Integer stackFingerprint = info.hashCode();
9621            boolean logIt = true;
9622            synchronized (mAlreadyLoggedViolatedStacks) {
9623                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9624                    logIt = false;
9625                    // TODO: sub-sample into EventLog for these, with
9626                    // the info.durationMillis?  Then we'd get
9627                    // the relative pain numbers, without logging all
9628                    // the stack traces repeatedly.  We'd want to do
9629                    // likewise in the client code, which also does
9630                    // dup suppression, before the Binder call.
9631                } else {
9632                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9633                        mAlreadyLoggedViolatedStacks.clear();
9634                    }
9635                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9636                }
9637            }
9638            if (logIt) {
9639                logStrictModeViolationToDropBox(r, info);
9640            }
9641        }
9642
9643        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9644            AppErrorResult result = new AppErrorResult();
9645            synchronized (this) {
9646                final long origId = Binder.clearCallingIdentity();
9647
9648                Message msg = Message.obtain();
9649                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9650                HashMap<String, Object> data = new HashMap<String, Object>();
9651                data.put("result", result);
9652                data.put("app", r);
9653                data.put("violationMask", violationMask);
9654                data.put("info", info);
9655                msg.obj = data;
9656                mHandler.sendMessage(msg);
9657
9658                Binder.restoreCallingIdentity(origId);
9659            }
9660            int res = result.get();
9661            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9662        }
9663    }
9664
9665    // Depending on the policy in effect, there could be a bunch of
9666    // these in quick succession so we try to batch these together to
9667    // minimize disk writes, number of dropbox entries, and maximize
9668    // compression, by having more fewer, larger records.
9669    private void logStrictModeViolationToDropBox(
9670            ProcessRecord process,
9671            StrictMode.ViolationInfo info) {
9672        if (info == null) {
9673            return;
9674        }
9675        final boolean isSystemApp = process == null ||
9676                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9677                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9678        final String processName = process == null ? "unknown" : process.processName;
9679        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9680        final DropBoxManager dbox = (DropBoxManager)
9681                mContext.getSystemService(Context.DROPBOX_SERVICE);
9682
9683        // Exit early if the dropbox isn't configured to accept this report type.
9684        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9685
9686        boolean bufferWasEmpty;
9687        boolean needsFlush;
9688        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9689        synchronized (sb) {
9690            bufferWasEmpty = sb.length() == 0;
9691            appendDropBoxProcessHeaders(process, processName, sb);
9692            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9693            sb.append("System-App: ").append(isSystemApp).append("\n");
9694            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9695            if (info.violationNumThisLoop != 0) {
9696                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9697            }
9698            if (info.numAnimationsRunning != 0) {
9699                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9700            }
9701            if (info.broadcastIntentAction != null) {
9702                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9703            }
9704            if (info.durationMillis != -1) {
9705                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9706            }
9707            if (info.numInstances != -1) {
9708                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9709            }
9710            if (info.tags != null) {
9711                for (String tag : info.tags) {
9712                    sb.append("Span-Tag: ").append(tag).append("\n");
9713                }
9714            }
9715            sb.append("\n");
9716            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9717                sb.append(info.crashInfo.stackTrace);
9718            }
9719            sb.append("\n");
9720
9721            // Only buffer up to ~64k.  Various logging bits truncate
9722            // things at 128k.
9723            needsFlush = (sb.length() > 64 * 1024);
9724        }
9725
9726        // Flush immediately if the buffer's grown too large, or this
9727        // is a non-system app.  Non-system apps are isolated with a
9728        // different tag & policy and not batched.
9729        //
9730        // Batching is useful during internal testing with
9731        // StrictMode settings turned up high.  Without batching,
9732        // thousands of separate files could be created on boot.
9733        if (!isSystemApp || needsFlush) {
9734            new Thread("Error dump: " + dropboxTag) {
9735                @Override
9736                public void run() {
9737                    String report;
9738                    synchronized (sb) {
9739                        report = sb.toString();
9740                        sb.delete(0, sb.length());
9741                        sb.trimToSize();
9742                    }
9743                    if (report.length() != 0) {
9744                        dbox.addText(dropboxTag, report);
9745                    }
9746                }
9747            }.start();
9748            return;
9749        }
9750
9751        // System app batching:
9752        if (!bufferWasEmpty) {
9753            // An existing dropbox-writing thread is outstanding, so
9754            // we don't need to start it up.  The existing thread will
9755            // catch the buffer appends we just did.
9756            return;
9757        }
9758
9759        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9760        // (After this point, we shouldn't access AMS internal data structures.)
9761        new Thread("Error dump: " + dropboxTag) {
9762            @Override
9763            public void run() {
9764                // 5 second sleep to let stacks arrive and be batched together
9765                try {
9766                    Thread.sleep(5000);  // 5 seconds
9767                } catch (InterruptedException e) {}
9768
9769                String errorReport;
9770                synchronized (mStrictModeBuffer) {
9771                    errorReport = mStrictModeBuffer.toString();
9772                    if (errorReport.length() == 0) {
9773                        return;
9774                    }
9775                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9776                    mStrictModeBuffer.trimToSize();
9777                }
9778                dbox.addText(dropboxTag, errorReport);
9779            }
9780        }.start();
9781    }
9782
9783    /**
9784     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9785     * @param app object of the crashing app, null for the system server
9786     * @param tag reported by the caller
9787     * @param crashInfo describing the context of the error
9788     * @return true if the process should exit immediately (WTF is fatal)
9789     */
9790    public boolean handleApplicationWtf(IBinder app, String tag,
9791            ApplicationErrorReport.CrashInfo crashInfo) {
9792        ProcessRecord r = findAppProcess(app, "WTF");
9793        final String processName = app == null ? "system_server"
9794                : (r == null ? "unknown" : r.processName);
9795
9796        EventLog.writeEvent(EventLogTags.AM_WTF,
9797                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9798                processName,
9799                r == null ? -1 : r.info.flags,
9800                tag, crashInfo.exceptionMessage);
9801
9802        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9803
9804        if (r != null && r.pid != Process.myPid() &&
9805                Settings.Global.getInt(mContext.getContentResolver(),
9806                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9807            crashApplication(r, crashInfo);
9808            return true;
9809        } else {
9810            return false;
9811        }
9812    }
9813
9814    /**
9815     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9816     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9817     */
9818    private ProcessRecord findAppProcess(IBinder app, String reason) {
9819        if (app == null) {
9820            return null;
9821        }
9822
9823        synchronized (this) {
9824            final int NP = mProcessNames.getMap().size();
9825            for (int ip=0; ip<NP; ip++) {
9826                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9827                final int NA = apps.size();
9828                for (int ia=0; ia<NA; ia++) {
9829                    ProcessRecord p = apps.valueAt(ia);
9830                    if (p.thread != null && p.thread.asBinder() == app) {
9831                        return p;
9832                    }
9833                }
9834            }
9835
9836            Slog.w(TAG, "Can't find mystery application for " + reason
9837                    + " from pid=" + Binder.getCallingPid()
9838                    + " uid=" + Binder.getCallingUid() + ": " + app);
9839            return null;
9840        }
9841    }
9842
9843    /**
9844     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9845     * to append various headers to the dropbox log text.
9846     */
9847    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9848            StringBuilder sb) {
9849        // Watchdog thread ends up invoking this function (with
9850        // a null ProcessRecord) to add the stack file to dropbox.
9851        // Do not acquire a lock on this (am) in such cases, as it
9852        // could cause a potential deadlock, if and when watchdog
9853        // is invoked due to unavailability of lock on am and it
9854        // would prevent watchdog from killing system_server.
9855        if (process == null) {
9856            sb.append("Process: ").append(processName).append("\n");
9857            return;
9858        }
9859        // Note: ProcessRecord 'process' is guarded by the service
9860        // instance.  (notably process.pkgList, which could otherwise change
9861        // concurrently during execution of this method)
9862        synchronized (this) {
9863            sb.append("Process: ").append(processName).append("\n");
9864            int flags = process.info.flags;
9865            IPackageManager pm = AppGlobals.getPackageManager();
9866            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9867            for (int ip=0; ip<process.pkgList.size(); ip++) {
9868                String pkg = process.pkgList.keyAt(ip);
9869                sb.append("Package: ").append(pkg);
9870                try {
9871                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9872                    if (pi != null) {
9873                        sb.append(" v").append(pi.versionCode);
9874                        if (pi.versionName != null) {
9875                            sb.append(" (").append(pi.versionName).append(")");
9876                        }
9877                    }
9878                } catch (RemoteException e) {
9879                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9880                }
9881                sb.append("\n");
9882            }
9883        }
9884    }
9885
9886    private static String processClass(ProcessRecord process) {
9887        if (process == null || process.pid == MY_PID) {
9888            return "system_server";
9889        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9890            return "system_app";
9891        } else {
9892            return "data_app";
9893        }
9894    }
9895
9896    /**
9897     * Write a description of an error (crash, WTF, ANR) to the drop box.
9898     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9899     * @param process which caused the error, null means the system server
9900     * @param activity which triggered the error, null if unknown
9901     * @param parent activity related to the error, null if unknown
9902     * @param subject line related to the error, null if absent
9903     * @param report in long form describing the error, null if absent
9904     * @param logFile to include in the report, null if none
9905     * @param crashInfo giving an application stack trace, null if absent
9906     */
9907    public void addErrorToDropBox(String eventType,
9908            ProcessRecord process, String processName, ActivityRecord activity,
9909            ActivityRecord parent, String subject,
9910            final String report, final File logFile,
9911            final ApplicationErrorReport.CrashInfo crashInfo) {
9912        // NOTE -- this must never acquire the ActivityManagerService lock,
9913        // otherwise the watchdog may be prevented from resetting the system.
9914
9915        final String dropboxTag = processClass(process) + "_" + eventType;
9916        final DropBoxManager dbox = (DropBoxManager)
9917                mContext.getSystemService(Context.DROPBOX_SERVICE);
9918
9919        // Exit early if the dropbox isn't configured to accept this report type.
9920        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9921
9922        final StringBuilder sb = new StringBuilder(1024);
9923        appendDropBoxProcessHeaders(process, processName, sb);
9924        if (activity != null) {
9925            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9926        }
9927        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9928            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9929        }
9930        if (parent != null && parent != activity) {
9931            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9932        }
9933        if (subject != null) {
9934            sb.append("Subject: ").append(subject).append("\n");
9935        }
9936        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9937        if (Debug.isDebuggerConnected()) {
9938            sb.append("Debugger: Connected\n");
9939        }
9940        sb.append("\n");
9941
9942        // Do the rest in a worker thread to avoid blocking the caller on I/O
9943        // (After this point, we shouldn't access AMS internal data structures.)
9944        Thread worker = new Thread("Error dump: " + dropboxTag) {
9945            @Override
9946            public void run() {
9947                if (report != null) {
9948                    sb.append(report);
9949                }
9950                if (logFile != null) {
9951                    try {
9952                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9953                                    "\n\n[[TRUNCATED]]"));
9954                    } catch (IOException e) {
9955                        Slog.e(TAG, "Error reading " + logFile, e);
9956                    }
9957                }
9958                if (crashInfo != null && crashInfo.stackTrace != null) {
9959                    sb.append(crashInfo.stackTrace);
9960                }
9961
9962                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9963                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9964                if (lines > 0) {
9965                    sb.append("\n");
9966
9967                    // Merge several logcat streams, and take the last N lines
9968                    InputStreamReader input = null;
9969                    try {
9970                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9971                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9972                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9973
9974                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9975                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9976                        input = new InputStreamReader(logcat.getInputStream());
9977
9978                        int num;
9979                        char[] buf = new char[8192];
9980                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9981                    } catch (IOException e) {
9982                        Slog.e(TAG, "Error running logcat", e);
9983                    } finally {
9984                        if (input != null) try { input.close(); } catch (IOException e) {}
9985                    }
9986                }
9987
9988                dbox.addText(dropboxTag, sb.toString());
9989            }
9990        };
9991
9992        if (process == null) {
9993            // If process is null, we are being called from some internal code
9994            // and may be about to die -- run this synchronously.
9995            worker.run();
9996        } else {
9997            worker.start();
9998        }
9999    }
10000
10001    /**
10002     * Bring up the "unexpected error" dialog box for a crashing app.
10003     * Deal with edge cases (intercepts from instrumented applications,
10004     * ActivityController, error intent receivers, that sort of thing).
10005     * @param r the application crashing
10006     * @param crashInfo describing the failure
10007     */
10008    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10009        long timeMillis = System.currentTimeMillis();
10010        String shortMsg = crashInfo.exceptionClassName;
10011        String longMsg = crashInfo.exceptionMessage;
10012        String stackTrace = crashInfo.stackTrace;
10013        if (shortMsg != null && longMsg != null) {
10014            longMsg = shortMsg + ": " + longMsg;
10015        } else if (shortMsg != null) {
10016            longMsg = shortMsg;
10017        }
10018
10019        AppErrorResult result = new AppErrorResult();
10020        synchronized (this) {
10021            if (mController != null) {
10022                try {
10023                    String name = r != null ? r.processName : null;
10024                    int pid = r != null ? r.pid : Binder.getCallingPid();
10025                    if (!mController.appCrashed(name, pid,
10026                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10027                        Slog.w(TAG, "Force-killing crashed app " + name
10028                                + " at watcher's request");
10029                        Process.killProcess(pid);
10030                        return;
10031                    }
10032                } catch (RemoteException e) {
10033                    mController = null;
10034                    Watchdog.getInstance().setActivityController(null);
10035                }
10036            }
10037
10038            final long origId = Binder.clearCallingIdentity();
10039
10040            // If this process is running instrumentation, finish it.
10041            if (r != null && r.instrumentationClass != null) {
10042                Slog.w(TAG, "Error in app " + r.processName
10043                      + " running instrumentation " + r.instrumentationClass + ":");
10044                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10045                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10046                Bundle info = new Bundle();
10047                info.putString("shortMsg", shortMsg);
10048                info.putString("longMsg", longMsg);
10049                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10050                Binder.restoreCallingIdentity(origId);
10051                return;
10052            }
10053
10054            // If we can't identify the process or it's already exceeded its crash quota,
10055            // quit right away without showing a crash dialog.
10056            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10057                Binder.restoreCallingIdentity(origId);
10058                return;
10059            }
10060
10061            Message msg = Message.obtain();
10062            msg.what = SHOW_ERROR_MSG;
10063            HashMap data = new HashMap();
10064            data.put("result", result);
10065            data.put("app", r);
10066            msg.obj = data;
10067            mHandler.sendMessage(msg);
10068
10069            Binder.restoreCallingIdentity(origId);
10070        }
10071
10072        int res = result.get();
10073
10074        Intent appErrorIntent = null;
10075        synchronized (this) {
10076            if (r != null && !r.isolated) {
10077                // XXX Can't keep track of crash time for isolated processes,
10078                // since they don't have a persistent identity.
10079                mProcessCrashTimes.put(r.info.processName, r.uid,
10080                        SystemClock.uptimeMillis());
10081            }
10082            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10083                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10084            }
10085        }
10086
10087        if (appErrorIntent != null) {
10088            try {
10089                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10090            } catch (ActivityNotFoundException e) {
10091                Slog.w(TAG, "bug report receiver dissappeared", e);
10092            }
10093        }
10094    }
10095
10096    Intent createAppErrorIntentLocked(ProcessRecord r,
10097            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10098        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10099        if (report == null) {
10100            return null;
10101        }
10102        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10103        result.setComponent(r.errorReportReceiver);
10104        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10105        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10106        return result;
10107    }
10108
10109    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10110            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10111        if (r.errorReportReceiver == null) {
10112            return null;
10113        }
10114
10115        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10116            return null;
10117        }
10118
10119        ApplicationErrorReport report = new ApplicationErrorReport();
10120        report.packageName = r.info.packageName;
10121        report.installerPackageName = r.errorReportReceiver.getPackageName();
10122        report.processName = r.processName;
10123        report.time = timeMillis;
10124        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10125
10126        if (r.crashing || r.forceCrashReport) {
10127            report.type = ApplicationErrorReport.TYPE_CRASH;
10128            report.crashInfo = crashInfo;
10129        } else if (r.notResponding) {
10130            report.type = ApplicationErrorReport.TYPE_ANR;
10131            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10132
10133            report.anrInfo.activity = r.notRespondingReport.tag;
10134            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10135            report.anrInfo.info = r.notRespondingReport.longMsg;
10136        }
10137
10138        return report;
10139    }
10140
10141    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10142        enforceNotIsolatedCaller("getProcessesInErrorState");
10143        // assume our apps are happy - lazy create the list
10144        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10145
10146        final boolean allUsers = ActivityManager.checkUidPermission(
10147                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10148                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10149        int userId = UserHandle.getUserId(Binder.getCallingUid());
10150
10151        synchronized (this) {
10152
10153            // iterate across all processes
10154            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10155                ProcessRecord app = mLruProcesses.get(i);
10156                if (!allUsers && app.userId != userId) {
10157                    continue;
10158                }
10159                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10160                    // This one's in trouble, so we'll generate a report for it
10161                    // crashes are higher priority (in case there's a crash *and* an anr)
10162                    ActivityManager.ProcessErrorStateInfo report = null;
10163                    if (app.crashing) {
10164                        report = app.crashingReport;
10165                    } else if (app.notResponding) {
10166                        report = app.notRespondingReport;
10167                    }
10168
10169                    if (report != null) {
10170                        if (errList == null) {
10171                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10172                        }
10173                        errList.add(report);
10174                    } else {
10175                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10176                                " crashing = " + app.crashing +
10177                                " notResponding = " + app.notResponding);
10178                    }
10179                }
10180            }
10181        }
10182
10183        return errList;
10184    }
10185
10186    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10187        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10188            if (currApp != null) {
10189                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10190            }
10191            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10192        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10193            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10194        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10195            if (currApp != null) {
10196                currApp.lru = 0;
10197            }
10198            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10199        } else if (adj >= ProcessList.SERVICE_ADJ) {
10200            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10201        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10202            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10203        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10204            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10205        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10206            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10207        } else {
10208            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10209        }
10210    }
10211
10212    private void fillInProcMemInfo(ProcessRecord app,
10213            ActivityManager.RunningAppProcessInfo outInfo) {
10214        outInfo.pid = app.pid;
10215        outInfo.uid = app.info.uid;
10216        if (mHeavyWeightProcess == app) {
10217            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10218        }
10219        if (app.persistent) {
10220            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10221        }
10222        if (app.activities.size() > 0) {
10223            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10224        }
10225        outInfo.lastTrimLevel = app.trimMemoryLevel;
10226        int adj = app.curAdj;
10227        outInfo.importance = oomAdjToImportance(adj, outInfo);
10228        outInfo.importanceReasonCode = app.adjTypeCode;
10229    }
10230
10231    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10232        enforceNotIsolatedCaller("getRunningAppProcesses");
10233        // Lazy instantiation of list
10234        List<ActivityManager.RunningAppProcessInfo> runList = null;
10235        final boolean allUsers = ActivityManager.checkUidPermission(
10236                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10237                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10238        int userId = UserHandle.getUserId(Binder.getCallingUid());
10239        synchronized (this) {
10240            // Iterate across all processes
10241            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10242                ProcessRecord app = mLruProcesses.get(i);
10243                if (!allUsers && app.userId != userId) {
10244                    continue;
10245                }
10246                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10247                    // Generate process state info for running application
10248                    ActivityManager.RunningAppProcessInfo currApp =
10249                        new ActivityManager.RunningAppProcessInfo(app.processName,
10250                                app.pid, app.getPackageList());
10251                    fillInProcMemInfo(app, currApp);
10252                    if (app.adjSource instanceof ProcessRecord) {
10253                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10254                        currApp.importanceReasonImportance = oomAdjToImportance(
10255                                app.adjSourceOom, null);
10256                    } else if (app.adjSource instanceof ActivityRecord) {
10257                        ActivityRecord r = (ActivityRecord)app.adjSource;
10258                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10259                    }
10260                    if (app.adjTarget instanceof ComponentName) {
10261                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10262                    }
10263                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10264                    //        + " lru=" + currApp.lru);
10265                    if (runList == null) {
10266                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10267                    }
10268                    runList.add(currApp);
10269                }
10270            }
10271        }
10272        return runList;
10273    }
10274
10275    public List<ApplicationInfo> getRunningExternalApplications() {
10276        enforceNotIsolatedCaller("getRunningExternalApplications");
10277        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10278        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10279        if (runningApps != null && runningApps.size() > 0) {
10280            Set<String> extList = new HashSet<String>();
10281            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10282                if (app.pkgList != null) {
10283                    for (String pkg : app.pkgList) {
10284                        extList.add(pkg);
10285                    }
10286                }
10287            }
10288            IPackageManager pm = AppGlobals.getPackageManager();
10289            for (String pkg : extList) {
10290                try {
10291                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10292                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10293                        retList.add(info);
10294                    }
10295                } catch (RemoteException e) {
10296                }
10297            }
10298        }
10299        return retList;
10300    }
10301
10302    @Override
10303    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10304        enforceNotIsolatedCaller("getMyMemoryState");
10305        synchronized (this) {
10306            ProcessRecord proc;
10307            synchronized (mPidsSelfLocked) {
10308                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10309            }
10310            fillInProcMemInfo(proc, outInfo);
10311        }
10312    }
10313
10314    @Override
10315    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10316        if (checkCallingPermission(android.Manifest.permission.DUMP)
10317                != PackageManager.PERMISSION_GRANTED) {
10318            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10319                    + Binder.getCallingPid()
10320                    + ", uid=" + Binder.getCallingUid()
10321                    + " without permission "
10322                    + android.Manifest.permission.DUMP);
10323            return;
10324        }
10325
10326        boolean dumpAll = false;
10327        boolean dumpClient = false;
10328        String dumpPackage = null;
10329
10330        int opti = 0;
10331        while (opti < args.length) {
10332            String opt = args[opti];
10333            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10334                break;
10335            }
10336            opti++;
10337            if ("-a".equals(opt)) {
10338                dumpAll = true;
10339            } else if ("-c".equals(opt)) {
10340                dumpClient = true;
10341            } else if ("-h".equals(opt)) {
10342                pw.println("Activity manager dump options:");
10343                pw.println("  [-a] [-c] [-h] [cmd] ...");
10344                pw.println("  cmd may be one of:");
10345                pw.println("    a[ctivities]: activity stack state");
10346                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10347                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10348                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10349                pw.println("    o[om]: out of memory management");
10350                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10351                pw.println("    provider [COMP_SPEC]: provider client-side state");
10352                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10353                pw.println("    service [COMP_SPEC]: service client-side state");
10354                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10355                pw.println("    all: dump all activities");
10356                pw.println("    top: dump the top activity");
10357                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10358                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10359                pw.println("    a partial substring in a component name, a");
10360                pw.println("    hex object identifier.");
10361                pw.println("  -a: include all available server state.");
10362                pw.println("  -c: include client state.");
10363                return;
10364            } else {
10365                pw.println("Unknown argument: " + opt + "; use -h for help");
10366            }
10367        }
10368
10369        long origId = Binder.clearCallingIdentity();
10370        boolean more = false;
10371        // Is the caller requesting to dump a particular piece of data?
10372        if (opti < args.length) {
10373            String cmd = args[opti];
10374            opti++;
10375            if ("activities".equals(cmd) || "a".equals(cmd)) {
10376                synchronized (this) {
10377                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10378                }
10379            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10380                String[] newArgs;
10381                String name;
10382                if (opti >= args.length) {
10383                    name = null;
10384                    newArgs = EMPTY_STRING_ARRAY;
10385                } else {
10386                    name = args[opti];
10387                    opti++;
10388                    newArgs = new String[args.length - opti];
10389                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10390                            args.length - opti);
10391                }
10392                synchronized (this) {
10393                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10394                }
10395            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10396                String[] newArgs;
10397                String name;
10398                if (opti >= args.length) {
10399                    name = null;
10400                    newArgs = EMPTY_STRING_ARRAY;
10401                } else {
10402                    name = args[opti];
10403                    opti++;
10404                    newArgs = new String[args.length - opti];
10405                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10406                            args.length - opti);
10407                }
10408                synchronized (this) {
10409                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10410                }
10411            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10412                String[] newArgs;
10413                String name;
10414                if (opti >= args.length) {
10415                    name = null;
10416                    newArgs = EMPTY_STRING_ARRAY;
10417                } else {
10418                    name = args[opti];
10419                    opti++;
10420                    newArgs = new String[args.length - opti];
10421                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10422                            args.length - opti);
10423                }
10424                synchronized (this) {
10425                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10426                }
10427            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10428                synchronized (this) {
10429                    dumpOomLocked(fd, pw, args, opti, true);
10430                }
10431            } else if ("provider".equals(cmd)) {
10432                String[] newArgs;
10433                String name;
10434                if (opti >= args.length) {
10435                    name = null;
10436                    newArgs = EMPTY_STRING_ARRAY;
10437                } else {
10438                    name = args[opti];
10439                    opti++;
10440                    newArgs = new String[args.length - opti];
10441                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10442                }
10443                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10444                    pw.println("No providers match: " + name);
10445                    pw.println("Use -h for help.");
10446                }
10447            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10448                synchronized (this) {
10449                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10450                }
10451            } else if ("service".equals(cmd)) {
10452                String[] newArgs;
10453                String name;
10454                if (opti >= args.length) {
10455                    name = null;
10456                    newArgs = EMPTY_STRING_ARRAY;
10457                } else {
10458                    name = args[opti];
10459                    opti++;
10460                    newArgs = new String[args.length - opti];
10461                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10462                            args.length - opti);
10463                }
10464                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10465                    pw.println("No services match: " + name);
10466                    pw.println("Use -h for help.");
10467                }
10468            } else if ("package".equals(cmd)) {
10469                String[] newArgs;
10470                if (opti >= args.length) {
10471                    pw.println("package: no package name specified");
10472                    pw.println("Use -h for help.");
10473                } else {
10474                    dumpPackage = args[opti];
10475                    opti++;
10476                    newArgs = new String[args.length - opti];
10477                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10478                            args.length - opti);
10479                    args = newArgs;
10480                    opti = 0;
10481                    more = true;
10482                }
10483            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10484                synchronized (this) {
10485                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10486                }
10487            } else {
10488                // Dumping a single activity?
10489                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10490                    pw.println("Bad activity command, or no activities match: " + cmd);
10491                    pw.println("Use -h for help.");
10492                }
10493            }
10494            if (!more) {
10495                Binder.restoreCallingIdentity(origId);
10496                return;
10497            }
10498        }
10499
10500        // No piece of data specified, dump everything.
10501        synchronized (this) {
10502            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10503            pw.println();
10504            if (dumpAll) {
10505                pw.println("-------------------------------------------------------------------------------");
10506            }
10507            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10508            pw.println();
10509            if (dumpAll) {
10510                pw.println("-------------------------------------------------------------------------------");
10511            }
10512            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10513            pw.println();
10514            if (dumpAll) {
10515                pw.println("-------------------------------------------------------------------------------");
10516            }
10517            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10518            pw.println();
10519            if (dumpAll) {
10520                pw.println("-------------------------------------------------------------------------------");
10521            }
10522            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10523            pw.println();
10524            if (dumpAll) {
10525                pw.println("-------------------------------------------------------------------------------");
10526            }
10527            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10528        }
10529        Binder.restoreCallingIdentity(origId);
10530    }
10531
10532    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10533            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10534        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10535
10536        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10537                dumpPackage);
10538        boolean needSep = printedAnything;
10539
10540        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10541                dumpPackage, needSep, "  mFocusedActivity: ");
10542        if (printed) {
10543            printedAnything = true;
10544            needSep = false;
10545        }
10546
10547        if (dumpPackage == null) {
10548            if (needSep) {
10549                pw.println();
10550            }
10551            needSep = true;
10552            printedAnything = true;
10553            mStackSupervisor.dump(pw, "  ");
10554        }
10555
10556        if (mRecentTasks.size() > 0) {
10557            boolean printedHeader = false;
10558
10559            final int N = mRecentTasks.size();
10560            for (int i=0; i<N; i++) {
10561                TaskRecord tr = mRecentTasks.get(i);
10562                if (dumpPackage != null) {
10563                    if (tr.realActivity == null ||
10564                            !dumpPackage.equals(tr.realActivity)) {
10565                        continue;
10566                    }
10567                }
10568                if (!printedHeader) {
10569                    if (needSep) {
10570                        pw.println();
10571                    }
10572                    pw.println("  Recent tasks:");
10573                    printedHeader = true;
10574                    printedAnything = true;
10575                }
10576                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10577                        pw.println(tr);
10578                if (dumpAll) {
10579                    mRecentTasks.get(i).dump(pw, "    ");
10580                }
10581            }
10582        }
10583
10584        if (!printedAnything) {
10585            pw.println("  (nothing)");
10586        }
10587    }
10588
10589    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10590            int opti, boolean dumpAll, String dumpPackage) {
10591        boolean needSep = false;
10592        boolean printedAnything = false;
10593        int numPers = 0;
10594
10595        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10596
10597        if (dumpAll) {
10598            final int NP = mProcessNames.getMap().size();
10599            for (int ip=0; ip<NP; ip++) {
10600                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10601                final int NA = procs.size();
10602                for (int ia=0; ia<NA; ia++) {
10603                    ProcessRecord r = procs.valueAt(ia);
10604                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10605                        continue;
10606                    }
10607                    if (!needSep) {
10608                        pw.println("  All known processes:");
10609                        needSep = true;
10610                        printedAnything = true;
10611                    }
10612                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10613                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10614                        pw.print(" "); pw.println(r);
10615                    r.dump(pw, "    ");
10616                    if (r.persistent) {
10617                        numPers++;
10618                    }
10619                }
10620            }
10621        }
10622
10623        if (mIsolatedProcesses.size() > 0) {
10624            boolean printed = false;
10625            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10626                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10627                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10628                    continue;
10629                }
10630                if (!printed) {
10631                    if (needSep) {
10632                        pw.println();
10633                    }
10634                    pw.println("  Isolated process list (sorted by uid):");
10635                    printedAnything = true;
10636                    printed = true;
10637                    needSep = true;
10638                }
10639                pw.println(String.format("%sIsolated #%2d: %s",
10640                        "    ", i, r.toString()));
10641            }
10642        }
10643
10644        if (mLruProcesses.size() > 0) {
10645            if (needSep) {
10646                pw.println();
10647            }
10648            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10649                    pw.print(" total, non-act at ");
10650                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10651                    pw.print(", non-svc at ");
10652                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10653                    pw.println("):");
10654            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10655            needSep = true;
10656            printedAnything = true;
10657        }
10658
10659        if (dumpAll || dumpPackage != null) {
10660            synchronized (mPidsSelfLocked) {
10661                boolean printed = false;
10662                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10663                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10664                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10665                        continue;
10666                    }
10667                    if (!printed) {
10668                        if (needSep) pw.println();
10669                        needSep = true;
10670                        pw.println("  PID mappings:");
10671                        printed = true;
10672                        printedAnything = true;
10673                    }
10674                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10675                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10676                }
10677            }
10678        }
10679
10680        if (mForegroundProcesses.size() > 0) {
10681            synchronized (mPidsSelfLocked) {
10682                boolean printed = false;
10683                for (int i=0; i<mForegroundProcesses.size(); i++) {
10684                    ProcessRecord r = mPidsSelfLocked.get(
10685                            mForegroundProcesses.valueAt(i).pid);
10686                    if (dumpPackage != null && (r == null
10687                            || !r.pkgList.containsKey(dumpPackage))) {
10688                        continue;
10689                    }
10690                    if (!printed) {
10691                        if (needSep) pw.println();
10692                        needSep = true;
10693                        pw.println("  Foreground Processes:");
10694                        printed = true;
10695                        printedAnything = true;
10696                    }
10697                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10698                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10699                }
10700            }
10701        }
10702
10703        if (mPersistentStartingProcesses.size() > 0) {
10704            if (needSep) pw.println();
10705            needSep = true;
10706            printedAnything = true;
10707            pw.println("  Persisent processes that are starting:");
10708            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10709                    "Starting Norm", "Restarting PERS", dumpPackage);
10710        }
10711
10712        if (mRemovedProcesses.size() > 0) {
10713            if (needSep) pw.println();
10714            needSep = true;
10715            printedAnything = true;
10716            pw.println("  Processes that are being removed:");
10717            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10718                    "Removed Norm", "Removed PERS", dumpPackage);
10719        }
10720
10721        if (mProcessesOnHold.size() > 0) {
10722            if (needSep) pw.println();
10723            needSep = true;
10724            printedAnything = true;
10725            pw.println("  Processes that are on old until the system is ready:");
10726            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10727                    "OnHold Norm", "OnHold PERS", dumpPackage);
10728        }
10729
10730        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10731
10732        if (mProcessCrashTimes.getMap().size() > 0) {
10733            boolean printed = false;
10734            long now = SystemClock.uptimeMillis();
10735            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10736            final int NP = pmap.size();
10737            for (int ip=0; ip<NP; ip++) {
10738                String pname = pmap.keyAt(ip);
10739                SparseArray<Long> uids = pmap.valueAt(ip);
10740                final int N = uids.size();
10741                for (int i=0; i<N; i++) {
10742                    int puid = uids.keyAt(i);
10743                    ProcessRecord r = mProcessNames.get(pname, puid);
10744                    if (dumpPackage != null && (r == null
10745                            || !r.pkgList.containsKey(dumpPackage))) {
10746                        continue;
10747                    }
10748                    if (!printed) {
10749                        if (needSep) pw.println();
10750                        needSep = true;
10751                        pw.println("  Time since processes crashed:");
10752                        printed = true;
10753                        printedAnything = true;
10754                    }
10755                    pw.print("    Process "); pw.print(pname);
10756                            pw.print(" uid "); pw.print(puid);
10757                            pw.print(": last crashed ");
10758                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10759                            pw.println(" ago");
10760                }
10761            }
10762        }
10763
10764        if (mBadProcesses.getMap().size() > 0) {
10765            boolean printed = false;
10766            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10767            final int NP = pmap.size();
10768            for (int ip=0; ip<NP; ip++) {
10769                String pname = pmap.keyAt(ip);
10770                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10771                final int N = uids.size();
10772                for (int i=0; i<N; i++) {
10773                    int puid = uids.keyAt(i);
10774                    ProcessRecord r = mProcessNames.get(pname, puid);
10775                    if (dumpPackage != null && (r == null
10776                            || !r.pkgList.containsKey(dumpPackage))) {
10777                        continue;
10778                    }
10779                    if (!printed) {
10780                        if (needSep) pw.println();
10781                        needSep = true;
10782                        pw.println("  Bad processes:");
10783                        printedAnything = true;
10784                    }
10785                    BadProcessInfo info = uids.valueAt(i);
10786                    pw.print("    Bad process "); pw.print(pname);
10787                            pw.print(" uid "); pw.print(puid);
10788                            pw.print(": crashed at time "); pw.println(info.time);
10789                    if (info.shortMsg != null) {
10790                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10791                    }
10792                    if (info.longMsg != null) {
10793                        pw.print("      Long msg: "); pw.println(info.longMsg);
10794                    }
10795                    if (info.stack != null) {
10796                        pw.println("      Stack:");
10797                        int lastPos = 0;
10798                        for (int pos=0; pos<info.stack.length(); pos++) {
10799                            if (info.stack.charAt(pos) == '\n') {
10800                                pw.print("        ");
10801                                pw.write(info.stack, lastPos, pos-lastPos);
10802                                pw.println();
10803                                lastPos = pos+1;
10804                            }
10805                        }
10806                        if (lastPos < info.stack.length()) {
10807                            pw.print("        ");
10808                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10809                            pw.println();
10810                        }
10811                    }
10812                }
10813            }
10814        }
10815
10816        if (dumpPackage == null) {
10817            pw.println();
10818            needSep = false;
10819            pw.println("  mStartedUsers:");
10820            for (int i=0; i<mStartedUsers.size(); i++) {
10821                UserStartedState uss = mStartedUsers.valueAt(i);
10822                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10823                        pw.print(": "); uss.dump("", pw);
10824            }
10825            pw.print("  mStartedUserArray: [");
10826            for (int i=0; i<mStartedUserArray.length; i++) {
10827                if (i > 0) pw.print(", ");
10828                pw.print(mStartedUserArray[i]);
10829            }
10830            pw.println("]");
10831            pw.print("  mUserLru: [");
10832            for (int i=0; i<mUserLru.size(); i++) {
10833                if (i > 0) pw.print(", ");
10834                pw.print(mUserLru.get(i));
10835            }
10836            pw.println("]");
10837            if (dumpAll) {
10838                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10839            }
10840        }
10841        if (mHomeProcess != null && (dumpPackage == null
10842                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10843            if (needSep) {
10844                pw.println();
10845                needSep = false;
10846            }
10847            pw.println("  mHomeProcess: " + mHomeProcess);
10848        }
10849        if (mPreviousProcess != null && (dumpPackage == null
10850                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10851            if (needSep) {
10852                pw.println();
10853                needSep = false;
10854            }
10855            pw.println("  mPreviousProcess: " + mPreviousProcess);
10856        }
10857        if (dumpAll) {
10858            StringBuilder sb = new StringBuilder(128);
10859            sb.append("  mPreviousProcessVisibleTime: ");
10860            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10861            pw.println(sb);
10862        }
10863        if (mHeavyWeightProcess != null && (dumpPackage == null
10864                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10865            if (needSep) {
10866                pw.println();
10867                needSep = false;
10868            }
10869            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10870        }
10871        if (dumpPackage == null) {
10872            pw.println("  mConfiguration: " + mConfiguration);
10873        }
10874        if (dumpAll) {
10875            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10876            if (mCompatModePackages.getPackages().size() > 0) {
10877                boolean printed = false;
10878                for (Map.Entry<String, Integer> entry
10879                        : mCompatModePackages.getPackages().entrySet()) {
10880                    String pkg = entry.getKey();
10881                    int mode = entry.getValue();
10882                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10883                        continue;
10884                    }
10885                    if (!printed) {
10886                        pw.println("  mScreenCompatPackages:");
10887                        printed = true;
10888                    }
10889                    pw.print("    "); pw.print(pkg); pw.print(": ");
10890                            pw.print(mode); pw.println();
10891                }
10892            }
10893        }
10894        if (dumpPackage == null) {
10895            if (mSleeping || mWentToSleep || mLockScreenShown) {
10896                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10897                        + " mLockScreenShown " + mLockScreenShown);
10898            }
10899            if (mShuttingDown) {
10900                pw.println("  mShuttingDown=" + mShuttingDown);
10901            }
10902        }
10903        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10904                || mOrigWaitForDebugger) {
10905            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10906                    || dumpPackage.equals(mOrigDebugApp)) {
10907                if (needSep) {
10908                    pw.println();
10909                    needSep = false;
10910                }
10911                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10912                        + " mDebugTransient=" + mDebugTransient
10913                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10914            }
10915        }
10916        if (mOpenGlTraceApp != null) {
10917            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10918                if (needSep) {
10919                    pw.println();
10920                    needSep = false;
10921                }
10922                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10923            }
10924        }
10925        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10926                || mProfileFd != null) {
10927            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10928                if (needSep) {
10929                    pw.println();
10930                    needSep = false;
10931                }
10932                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10933                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10934                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10935                        + mAutoStopProfiler);
10936            }
10937        }
10938        if (dumpPackage == null) {
10939            if (mAlwaysFinishActivities || mController != null) {
10940                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10941                        + " mController=" + mController);
10942            }
10943            if (dumpAll) {
10944                pw.println("  Total persistent processes: " + numPers);
10945                pw.println("  mStartRunning=" + mStartRunning
10946                        + " mProcessesReady=" + mProcessesReady
10947                        + " mSystemReady=" + mSystemReady);
10948                pw.println("  mBooting=" + mBooting
10949                        + " mBooted=" + mBooted
10950                        + " mFactoryTest=" + mFactoryTest);
10951                pw.print("  mLastPowerCheckRealtime=");
10952                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10953                        pw.println("");
10954                pw.print("  mLastPowerCheckUptime=");
10955                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10956                        pw.println("");
10957                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10958                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10959                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10960                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10961                        + " (" + mLruProcesses.size() + " total)"
10962                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10963                        + " mNumServiceProcs=" + mNumServiceProcs
10964                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10965                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10966                        + " mLastMemoryLevel" + mLastMemoryLevel
10967                        + " mLastNumProcesses" + mLastNumProcesses);
10968                long now = SystemClock.uptimeMillis();
10969                pw.print("  mLastIdleTime=");
10970                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10971                        pw.print(" mLowRamSinceLastIdle=");
10972                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10973                        pw.println();
10974            }
10975        }
10976
10977        if (!printedAnything) {
10978            pw.println("  (nothing)");
10979        }
10980    }
10981
10982    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10983            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10984        if (mProcessesToGc.size() > 0) {
10985            boolean printed = false;
10986            long now = SystemClock.uptimeMillis();
10987            for (int i=0; i<mProcessesToGc.size(); i++) {
10988                ProcessRecord proc = mProcessesToGc.get(i);
10989                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10990                    continue;
10991                }
10992                if (!printed) {
10993                    if (needSep) pw.println();
10994                    needSep = true;
10995                    pw.println("  Processes that are waiting to GC:");
10996                    printed = true;
10997                }
10998                pw.print("    Process "); pw.println(proc);
10999                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11000                        pw.print(", last gced=");
11001                        pw.print(now-proc.lastRequestedGc);
11002                        pw.print(" ms ago, last lowMem=");
11003                        pw.print(now-proc.lastLowMemory);
11004                        pw.println(" ms ago");
11005
11006            }
11007        }
11008        return needSep;
11009    }
11010
11011    void printOomLevel(PrintWriter pw, String name, int adj) {
11012        pw.print("    ");
11013        if (adj >= 0) {
11014            pw.print(' ');
11015            if (adj < 10) pw.print(' ');
11016        } else {
11017            if (adj > -10) pw.print(' ');
11018        }
11019        pw.print(adj);
11020        pw.print(": ");
11021        pw.print(name);
11022        pw.print(" (");
11023        pw.print(mProcessList.getMemLevel(adj)/1024);
11024        pw.println(" kB)");
11025    }
11026
11027    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11028            int opti, boolean dumpAll) {
11029        boolean needSep = false;
11030
11031        if (mLruProcesses.size() > 0) {
11032            if (needSep) pw.println();
11033            needSep = true;
11034            pw.println("  OOM levels:");
11035            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11036            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11037            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11038            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11039            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11040            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11041            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11042            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11043            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11044            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11045            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11046            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11047            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11048
11049            if (needSep) pw.println();
11050            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11051                    pw.print(" total, non-act at ");
11052                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11053                    pw.print(", non-svc at ");
11054                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11055                    pw.println("):");
11056            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11057            needSep = true;
11058        }
11059
11060        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11061
11062        pw.println();
11063        pw.println("  mHomeProcess: " + mHomeProcess);
11064        pw.println("  mPreviousProcess: " + mPreviousProcess);
11065        if (mHeavyWeightProcess != null) {
11066            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11067        }
11068
11069        return true;
11070    }
11071
11072    /**
11073     * There are three ways to call this:
11074     *  - no provider specified: dump all the providers
11075     *  - a flattened component name that matched an existing provider was specified as the
11076     *    first arg: dump that one provider
11077     *  - the first arg isn't the flattened component name of an existing provider:
11078     *    dump all providers whose component contains the first arg as a substring
11079     */
11080    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11081            int opti, boolean dumpAll) {
11082        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11083    }
11084
11085    static class ItemMatcher {
11086        ArrayList<ComponentName> components;
11087        ArrayList<String> strings;
11088        ArrayList<Integer> objects;
11089        boolean all;
11090
11091        ItemMatcher() {
11092            all = true;
11093        }
11094
11095        void build(String name) {
11096            ComponentName componentName = ComponentName.unflattenFromString(name);
11097            if (componentName != null) {
11098                if (components == null) {
11099                    components = new ArrayList<ComponentName>();
11100                }
11101                components.add(componentName);
11102                all = false;
11103            } else {
11104                int objectId = 0;
11105                // Not a '/' separated full component name; maybe an object ID?
11106                try {
11107                    objectId = Integer.parseInt(name, 16);
11108                    if (objects == null) {
11109                        objects = new ArrayList<Integer>();
11110                    }
11111                    objects.add(objectId);
11112                    all = false;
11113                } catch (RuntimeException e) {
11114                    // Not an integer; just do string match.
11115                    if (strings == null) {
11116                        strings = new ArrayList<String>();
11117                    }
11118                    strings.add(name);
11119                    all = false;
11120                }
11121            }
11122        }
11123
11124        int build(String[] args, int opti) {
11125            for (; opti<args.length; opti++) {
11126                String name = args[opti];
11127                if ("--".equals(name)) {
11128                    return opti+1;
11129                }
11130                build(name);
11131            }
11132            return opti;
11133        }
11134
11135        boolean match(Object object, ComponentName comp) {
11136            if (all) {
11137                return true;
11138            }
11139            if (components != null) {
11140                for (int i=0; i<components.size(); i++) {
11141                    if (components.get(i).equals(comp)) {
11142                        return true;
11143                    }
11144                }
11145            }
11146            if (objects != null) {
11147                for (int i=0; i<objects.size(); i++) {
11148                    if (System.identityHashCode(object) == objects.get(i)) {
11149                        return true;
11150                    }
11151                }
11152            }
11153            if (strings != null) {
11154                String flat = comp.flattenToString();
11155                for (int i=0; i<strings.size(); i++) {
11156                    if (flat.contains(strings.get(i))) {
11157                        return true;
11158                    }
11159                }
11160            }
11161            return false;
11162        }
11163    }
11164
11165    /**
11166     * There are three things that cmd can be:
11167     *  - a flattened component name that matches an existing activity
11168     *  - the cmd arg isn't the flattened component name of an existing activity:
11169     *    dump all activity whose component contains the cmd as a substring
11170     *  - A hex number of the ActivityRecord object instance.
11171     */
11172    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11173            int opti, boolean dumpAll) {
11174        ArrayList<ActivityRecord> activities;
11175
11176        synchronized (this) {
11177            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11178        }
11179
11180        if (activities.size() <= 0) {
11181            return false;
11182        }
11183
11184        String[] newArgs = new String[args.length - opti];
11185        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11186
11187        TaskRecord lastTask = null;
11188        boolean needSep = false;
11189        for (int i=activities.size()-1; i>=0; i--) {
11190            ActivityRecord r = activities.get(i);
11191            if (needSep) {
11192                pw.println();
11193            }
11194            needSep = true;
11195            synchronized (this) {
11196                if (lastTask != r.task) {
11197                    lastTask = r.task;
11198                    pw.print("TASK "); pw.print(lastTask.affinity);
11199                            pw.print(" id="); pw.println(lastTask.taskId);
11200                    if (dumpAll) {
11201                        lastTask.dump(pw, "  ");
11202                    }
11203                }
11204            }
11205            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11206        }
11207        return true;
11208    }
11209
11210    /**
11211     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11212     * there is a thread associated with the activity.
11213     */
11214    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11215            final ActivityRecord r, String[] args, boolean dumpAll) {
11216        String innerPrefix = prefix + "  ";
11217        synchronized (this) {
11218            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11219                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11220                    pw.print(" pid=");
11221                    if (r.app != null) pw.println(r.app.pid);
11222                    else pw.println("(not running)");
11223            if (dumpAll) {
11224                r.dump(pw, innerPrefix);
11225            }
11226        }
11227        if (r.app != null && r.app.thread != null) {
11228            // flush anything that is already in the PrintWriter since the thread is going
11229            // to write to the file descriptor directly
11230            pw.flush();
11231            try {
11232                TransferPipe tp = new TransferPipe();
11233                try {
11234                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11235                            r.appToken, innerPrefix, args);
11236                    tp.go(fd);
11237                } finally {
11238                    tp.kill();
11239                }
11240            } catch (IOException e) {
11241                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11242            } catch (RemoteException e) {
11243                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11244            }
11245        }
11246    }
11247
11248    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11249            int opti, boolean dumpAll, String dumpPackage) {
11250        boolean needSep = false;
11251        boolean onlyHistory = false;
11252        boolean printedAnything = false;
11253
11254        if ("history".equals(dumpPackage)) {
11255            if (opti < args.length && "-s".equals(args[opti])) {
11256                dumpAll = false;
11257            }
11258            onlyHistory = true;
11259            dumpPackage = null;
11260        }
11261
11262        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11263        if (!onlyHistory && dumpAll) {
11264            if (mRegisteredReceivers.size() > 0) {
11265                boolean printed = false;
11266                Iterator it = mRegisteredReceivers.values().iterator();
11267                while (it.hasNext()) {
11268                    ReceiverList r = (ReceiverList)it.next();
11269                    if (dumpPackage != null && (r.app == null ||
11270                            !dumpPackage.equals(r.app.info.packageName))) {
11271                        continue;
11272                    }
11273                    if (!printed) {
11274                        pw.println("  Registered Receivers:");
11275                        needSep = true;
11276                        printed = true;
11277                        printedAnything = true;
11278                    }
11279                    pw.print("  * "); pw.println(r);
11280                    r.dump(pw, "    ");
11281                }
11282            }
11283
11284            if (mReceiverResolver.dump(pw, needSep ?
11285                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11286                    "    ", dumpPackage, false)) {
11287                needSep = true;
11288                printedAnything = true;
11289            }
11290        }
11291
11292        for (BroadcastQueue q : mBroadcastQueues) {
11293            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11294            printedAnything |= needSep;
11295        }
11296
11297        needSep = true;
11298
11299        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11300            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11301                if (needSep) {
11302                    pw.println();
11303                }
11304                needSep = true;
11305                printedAnything = true;
11306                pw.print("  Sticky broadcasts for user ");
11307                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11308                StringBuilder sb = new StringBuilder(128);
11309                for (Map.Entry<String, ArrayList<Intent>> ent
11310                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11311                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11312                    if (dumpAll) {
11313                        pw.println(":");
11314                        ArrayList<Intent> intents = ent.getValue();
11315                        final int N = intents.size();
11316                        for (int i=0; i<N; i++) {
11317                            sb.setLength(0);
11318                            sb.append("    Intent: ");
11319                            intents.get(i).toShortString(sb, false, true, false, false);
11320                            pw.println(sb.toString());
11321                            Bundle bundle = intents.get(i).getExtras();
11322                            if (bundle != null) {
11323                                pw.print("      ");
11324                                pw.println(bundle.toString());
11325                            }
11326                        }
11327                    } else {
11328                        pw.println("");
11329                    }
11330                }
11331            }
11332        }
11333
11334        if (!onlyHistory && dumpAll) {
11335            pw.println();
11336            for (BroadcastQueue queue : mBroadcastQueues) {
11337                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11338                        + queue.mBroadcastsScheduled);
11339            }
11340            pw.println("  mHandler:");
11341            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11342            needSep = true;
11343            printedAnything = true;
11344        }
11345
11346        if (!printedAnything) {
11347            pw.println("  (nothing)");
11348        }
11349    }
11350
11351    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11352            int opti, boolean dumpAll, String dumpPackage) {
11353        boolean needSep;
11354        boolean printedAnything = false;
11355
11356        ItemMatcher matcher = new ItemMatcher();
11357        matcher.build(args, opti);
11358
11359        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11360
11361        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11362        printedAnything |= needSep;
11363
11364        if (mLaunchingProviders.size() > 0) {
11365            boolean printed = false;
11366            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11367                ContentProviderRecord r = mLaunchingProviders.get(i);
11368                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11369                    continue;
11370                }
11371                if (!printed) {
11372                    if (needSep) pw.println();
11373                    needSep = true;
11374                    pw.println("  Launching content providers:");
11375                    printed = true;
11376                    printedAnything = true;
11377                }
11378                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11379                        pw.println(r);
11380            }
11381        }
11382
11383        if (mGrantedUriPermissions.size() > 0) {
11384            boolean printed = false;
11385            int dumpUid = -2;
11386            if (dumpPackage != null) {
11387                try {
11388                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11389                } catch (NameNotFoundException e) {
11390                    dumpUid = -1;
11391                }
11392            }
11393            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11394                int uid = mGrantedUriPermissions.keyAt(i);
11395                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11396                    continue;
11397                }
11398                ArrayMap<Uri, UriPermission> perms
11399                        = mGrantedUriPermissions.valueAt(i);
11400                if (!printed) {
11401                    if (needSep) pw.println();
11402                    needSep = true;
11403                    pw.println("  Granted Uri Permissions:");
11404                    printed = true;
11405                    printedAnything = true;
11406                }
11407                pw.print("  * UID "); pw.print(uid);
11408                        pw.println(" holds:");
11409                for (UriPermission perm : perms.values()) {
11410                    pw.print("    "); pw.println(perm);
11411                    if (dumpAll) {
11412                        perm.dump(pw, "      ");
11413                    }
11414                }
11415            }
11416        }
11417
11418        if (!printedAnything) {
11419            pw.println("  (nothing)");
11420        }
11421    }
11422
11423    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11424            int opti, boolean dumpAll, String dumpPackage) {
11425        boolean printed = false;
11426
11427        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11428
11429        if (mIntentSenderRecords.size() > 0) {
11430            Iterator<WeakReference<PendingIntentRecord>> it
11431                    = mIntentSenderRecords.values().iterator();
11432            while (it.hasNext()) {
11433                WeakReference<PendingIntentRecord> ref = it.next();
11434                PendingIntentRecord rec = ref != null ? ref.get(): null;
11435                if (dumpPackage != null && (rec == null
11436                        || !dumpPackage.equals(rec.key.packageName))) {
11437                    continue;
11438                }
11439                printed = true;
11440                if (rec != null) {
11441                    pw.print("  * "); pw.println(rec);
11442                    if (dumpAll) {
11443                        rec.dump(pw, "    ");
11444                    }
11445                } else {
11446                    pw.print("  * "); pw.println(ref);
11447                }
11448            }
11449        }
11450
11451        if (!printed) {
11452            pw.println("  (nothing)");
11453        }
11454    }
11455
11456    private static final int dumpProcessList(PrintWriter pw,
11457            ActivityManagerService service, List list,
11458            String prefix, String normalLabel, String persistentLabel,
11459            String dumpPackage) {
11460        int numPers = 0;
11461        final int N = list.size()-1;
11462        for (int i=N; i>=0; i--) {
11463            ProcessRecord r = (ProcessRecord)list.get(i);
11464            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11465                continue;
11466            }
11467            pw.println(String.format("%s%s #%2d: %s",
11468                    prefix, (r.persistent ? persistentLabel : normalLabel),
11469                    i, r.toString()));
11470            if (r.persistent) {
11471                numPers++;
11472            }
11473        }
11474        return numPers;
11475    }
11476
11477    private static final boolean dumpProcessOomList(PrintWriter pw,
11478            ActivityManagerService service, List<ProcessRecord> origList,
11479            String prefix, String normalLabel, String persistentLabel,
11480            boolean inclDetails, String dumpPackage) {
11481
11482        ArrayList<Pair<ProcessRecord, Integer>> list
11483                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11484        for (int i=0; i<origList.size(); i++) {
11485            ProcessRecord r = origList.get(i);
11486            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11487                continue;
11488            }
11489            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11490        }
11491
11492        if (list.size() <= 0) {
11493            return false;
11494        }
11495
11496        Comparator<Pair<ProcessRecord, Integer>> comparator
11497                = new Comparator<Pair<ProcessRecord, Integer>>() {
11498            @Override
11499            public int compare(Pair<ProcessRecord, Integer> object1,
11500                    Pair<ProcessRecord, Integer> object2) {
11501                if (object1.first.setAdj != object2.first.setAdj) {
11502                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11503                }
11504                if (object1.second.intValue() != object2.second.intValue()) {
11505                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11506                }
11507                return 0;
11508            }
11509        };
11510
11511        Collections.sort(list, comparator);
11512
11513        final long curRealtime = SystemClock.elapsedRealtime();
11514        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11515        final long curUptime = SystemClock.uptimeMillis();
11516        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11517
11518        for (int i=list.size()-1; i>=0; i--) {
11519            ProcessRecord r = list.get(i).first;
11520            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11521            char schedGroup;
11522            switch (r.setSchedGroup) {
11523                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11524                    schedGroup = 'B';
11525                    break;
11526                case Process.THREAD_GROUP_DEFAULT:
11527                    schedGroup = 'F';
11528                    break;
11529                default:
11530                    schedGroup = '?';
11531                    break;
11532            }
11533            char foreground;
11534            if (r.foregroundActivities) {
11535                foreground = 'A';
11536            } else if (r.foregroundServices) {
11537                foreground = 'S';
11538            } else {
11539                foreground = ' ';
11540            }
11541            String procState = ProcessList.makeProcStateString(r.curProcState);
11542            pw.print(prefix);
11543            pw.print(r.persistent ? persistentLabel : normalLabel);
11544            pw.print(" #");
11545            int num = (origList.size()-1)-list.get(i).second;
11546            if (num < 10) pw.print(' ');
11547            pw.print(num);
11548            pw.print(": ");
11549            pw.print(oomAdj);
11550            pw.print(' ');
11551            pw.print(schedGroup);
11552            pw.print('/');
11553            pw.print(foreground);
11554            pw.print('/');
11555            pw.print(procState);
11556            pw.print(" trm:");
11557            if (r.trimMemoryLevel < 10) pw.print(' ');
11558            pw.print(r.trimMemoryLevel);
11559            pw.print(' ');
11560            pw.print(r.toShortString());
11561            pw.print(" (");
11562            pw.print(r.adjType);
11563            pw.println(')');
11564            if (r.adjSource != null || r.adjTarget != null) {
11565                pw.print(prefix);
11566                pw.print("    ");
11567                if (r.adjTarget instanceof ComponentName) {
11568                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11569                } else if (r.adjTarget != null) {
11570                    pw.print(r.adjTarget.toString());
11571                } else {
11572                    pw.print("{null}");
11573                }
11574                pw.print("<=");
11575                if (r.adjSource instanceof ProcessRecord) {
11576                    pw.print("Proc{");
11577                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11578                    pw.println("}");
11579                } else if (r.adjSource != null) {
11580                    pw.println(r.adjSource.toString());
11581                } else {
11582                    pw.println("{null}");
11583                }
11584            }
11585            if (inclDetails) {
11586                pw.print(prefix);
11587                pw.print("    ");
11588                pw.print("oom: max="); pw.print(r.maxAdj);
11589                pw.print(" curRaw="); pw.print(r.curRawAdj);
11590                pw.print(" setRaw="); pw.print(r.setRawAdj);
11591                pw.print(" cur="); pw.print(r.curAdj);
11592                pw.print(" set="); pw.println(r.setAdj);
11593                pw.print(prefix);
11594                pw.print("    ");
11595                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11596                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11597                pw.print(" lastPss="); pw.print(r.lastPss);
11598                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11599                pw.print(prefix);
11600                pw.print("    ");
11601                pw.print("keeping="); pw.print(r.keeping);
11602                pw.print(" cached="); pw.print(r.cached);
11603                pw.print(" empty="); pw.print(r.empty);
11604                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11605
11606                if (!r.keeping) {
11607                    if (r.lastWakeTime != 0) {
11608                        long wtime;
11609                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11610                        synchronized (stats) {
11611                            wtime = stats.getProcessWakeTime(r.info.uid,
11612                                    r.pid, curRealtime);
11613                        }
11614                        long timeUsed = wtime - r.lastWakeTime;
11615                        pw.print(prefix);
11616                        pw.print("    ");
11617                        pw.print("keep awake over ");
11618                        TimeUtils.formatDuration(realtimeSince, pw);
11619                        pw.print(" used ");
11620                        TimeUtils.formatDuration(timeUsed, pw);
11621                        pw.print(" (");
11622                        pw.print((timeUsed*100)/realtimeSince);
11623                        pw.println("%)");
11624                    }
11625                    if (r.lastCpuTime != 0) {
11626                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11627                        pw.print(prefix);
11628                        pw.print("    ");
11629                        pw.print("run cpu over ");
11630                        TimeUtils.formatDuration(uptimeSince, pw);
11631                        pw.print(" used ");
11632                        TimeUtils.formatDuration(timeUsed, pw);
11633                        pw.print(" (");
11634                        pw.print((timeUsed*100)/uptimeSince);
11635                        pw.println("%)");
11636                    }
11637                }
11638            }
11639        }
11640        return true;
11641    }
11642
11643    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11644        ArrayList<ProcessRecord> procs;
11645        synchronized (this) {
11646            if (args != null && args.length > start
11647                    && args[start].charAt(0) != '-') {
11648                procs = new ArrayList<ProcessRecord>();
11649                int pid = -1;
11650                try {
11651                    pid = Integer.parseInt(args[start]);
11652                } catch (NumberFormatException e) {
11653                }
11654                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11655                    ProcessRecord proc = mLruProcesses.get(i);
11656                    if (proc.pid == pid) {
11657                        procs.add(proc);
11658                    } else if (proc.processName.equals(args[start])) {
11659                        procs.add(proc);
11660                    }
11661                }
11662                if (procs.size() <= 0) {
11663                    return null;
11664                }
11665            } else {
11666                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11667            }
11668        }
11669        return procs;
11670    }
11671
11672    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11673            PrintWriter pw, String[] args) {
11674        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11675        if (procs == null) {
11676            pw.println("No process found for: " + args[0]);
11677            return;
11678        }
11679
11680        long uptime = SystemClock.uptimeMillis();
11681        long realtime = SystemClock.elapsedRealtime();
11682        pw.println("Applications Graphics Acceleration Info:");
11683        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11684
11685        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11686            ProcessRecord r = procs.get(i);
11687            if (r.thread != null) {
11688                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11689                pw.flush();
11690                try {
11691                    TransferPipe tp = new TransferPipe();
11692                    try {
11693                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11694                        tp.go(fd);
11695                    } finally {
11696                        tp.kill();
11697                    }
11698                } catch (IOException e) {
11699                    pw.println("Failure while dumping the app: " + r);
11700                    pw.flush();
11701                } catch (RemoteException e) {
11702                    pw.println("Got a RemoteException while dumping the app " + r);
11703                    pw.flush();
11704                }
11705            }
11706        }
11707    }
11708
11709    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11710        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11711        if (procs == null) {
11712            pw.println("No process found for: " + args[0]);
11713            return;
11714        }
11715
11716        pw.println("Applications Database Info:");
11717
11718        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11719            ProcessRecord r = procs.get(i);
11720            if (r.thread != null) {
11721                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11722                pw.flush();
11723                try {
11724                    TransferPipe tp = new TransferPipe();
11725                    try {
11726                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11727                        tp.go(fd);
11728                    } finally {
11729                        tp.kill();
11730                    }
11731                } catch (IOException e) {
11732                    pw.println("Failure while dumping the app: " + r);
11733                    pw.flush();
11734                } catch (RemoteException e) {
11735                    pw.println("Got a RemoteException while dumping the app " + r);
11736                    pw.flush();
11737                }
11738            }
11739        }
11740    }
11741
11742    final static class MemItem {
11743        final boolean isProc;
11744        final String label;
11745        final String shortLabel;
11746        final long pss;
11747        final int id;
11748        final boolean hasActivities;
11749        ArrayList<MemItem> subitems;
11750
11751        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11752                boolean _hasActivities) {
11753            isProc = true;
11754            label = _label;
11755            shortLabel = _shortLabel;
11756            pss = _pss;
11757            id = _id;
11758            hasActivities = _hasActivities;
11759        }
11760
11761        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11762            isProc = false;
11763            label = _label;
11764            shortLabel = _shortLabel;
11765            pss = _pss;
11766            id = _id;
11767            hasActivities = false;
11768        }
11769    }
11770
11771    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11772            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11773        if (sort && !isCompact) {
11774            Collections.sort(items, new Comparator<MemItem>() {
11775                @Override
11776                public int compare(MemItem lhs, MemItem rhs) {
11777                    if (lhs.pss < rhs.pss) {
11778                        return 1;
11779                    } else if (lhs.pss > rhs.pss) {
11780                        return -1;
11781                    }
11782                    return 0;
11783                }
11784            });
11785        }
11786
11787        for (int i=0; i<items.size(); i++) {
11788            MemItem mi = items.get(i);
11789            if (!isCompact) {
11790                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11791            } else if (mi.isProc) {
11792                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11793                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11794                pw.println(mi.hasActivities ? ",a" : ",e");
11795            } else {
11796                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11797                pw.println(mi.pss);
11798            }
11799            if (mi.subitems != null) {
11800                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11801                        true, isCompact);
11802            }
11803        }
11804    }
11805
11806    // These are in KB.
11807    static final long[] DUMP_MEM_BUCKETS = new long[] {
11808        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11809        120*1024, 160*1024, 200*1024,
11810        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11811        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11812    };
11813
11814    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11815            boolean stackLike) {
11816        int start = label.lastIndexOf('.');
11817        if (start >= 0) start++;
11818        else start = 0;
11819        int end = label.length();
11820        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11821            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11822                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11823                out.append(bucket);
11824                out.append(stackLike ? "MB." : "MB ");
11825                out.append(label, start, end);
11826                return;
11827            }
11828        }
11829        out.append(memKB/1024);
11830        out.append(stackLike ? "MB." : "MB ");
11831        out.append(label, start, end);
11832    }
11833
11834    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11835            ProcessList.NATIVE_ADJ,
11836            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11837            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11838            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11839            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11840            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11841    };
11842    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11843            "Native",
11844            "System", "Persistent", "Foreground",
11845            "Visible", "Perceptible",
11846            "Heavy Weight", "Backup",
11847            "A Services", "Home",
11848            "Previous", "B Services", "Cached"
11849    };
11850    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11851            "native",
11852            "sys", "pers", "fore",
11853            "vis", "percept",
11854            "heavy", "backup",
11855            "servicea", "home",
11856            "prev", "serviceb", "cached"
11857    };
11858
11859    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11860            long realtime, boolean isCheckinRequest, boolean isCompact) {
11861        if (isCheckinRequest || isCompact) {
11862            // short checkin version
11863            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11864        } else {
11865            pw.println("Applications Memory Usage (kB):");
11866            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11867        }
11868    }
11869
11870    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11871            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11872        boolean dumpDetails = false;
11873        boolean dumpFullDetails = false;
11874        boolean dumpDalvik = false;
11875        boolean oomOnly = false;
11876        boolean isCompact = false;
11877        boolean localOnly = false;
11878
11879        int opti = 0;
11880        while (opti < args.length) {
11881            String opt = args[opti];
11882            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11883                break;
11884            }
11885            opti++;
11886            if ("-a".equals(opt)) {
11887                dumpDetails = true;
11888                dumpFullDetails = true;
11889                dumpDalvik = true;
11890            } else if ("-d".equals(opt)) {
11891                dumpDalvik = true;
11892            } else if ("-c".equals(opt)) {
11893                isCompact = true;
11894            } else if ("--oom".equals(opt)) {
11895                oomOnly = true;
11896            } else if ("--local".equals(opt)) {
11897                localOnly = true;
11898            } else if ("-h".equals(opt)) {
11899                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11900                pw.println("  -a: include all available information for each process.");
11901                pw.println("  -d: include dalvik details when dumping process details.");
11902                pw.println("  -c: dump in a compact machine-parseable representation.");
11903                pw.println("  --oom: only show processes organized by oom adj.");
11904                pw.println("  --local: only collect details locally, don't call process.");
11905                pw.println("If [process] is specified it can be the name or ");
11906                pw.println("pid of a specific process to dump.");
11907                return;
11908            } else {
11909                pw.println("Unknown argument: " + opt + "; use -h for help");
11910            }
11911        }
11912
11913        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11914        long uptime = SystemClock.uptimeMillis();
11915        long realtime = SystemClock.elapsedRealtime();
11916        final long[] tmpLong = new long[1];
11917
11918        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11919        if (procs == null) {
11920            // No Java processes.  Maybe they want to print a native process.
11921            if (args != null && args.length > opti
11922                    && args[opti].charAt(0) != '-') {
11923                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11924                        = new ArrayList<ProcessCpuTracker.Stats>();
11925                updateCpuStatsNow();
11926                int findPid = -1;
11927                try {
11928                    findPid = Integer.parseInt(args[opti]);
11929                } catch (NumberFormatException e) {
11930                }
11931                synchronized (mProcessCpuThread) {
11932                    final int N = mProcessCpuTracker.countStats();
11933                    for (int i=0; i<N; i++) {
11934                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11935                        if (st.pid == findPid || (st.baseName != null
11936                                && st.baseName.equals(args[opti]))) {
11937                            nativeProcs.add(st);
11938                        }
11939                    }
11940                }
11941                if (nativeProcs.size() > 0) {
11942                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11943                            isCompact);
11944                    Debug.MemoryInfo mi = null;
11945                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11946                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11947                        final int pid = r.pid;
11948                        if (!isCheckinRequest && dumpDetails) {
11949                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11950                        }
11951                        if (mi == null) {
11952                            mi = new Debug.MemoryInfo();
11953                        }
11954                        if (dumpDetails || (!brief && !oomOnly)) {
11955                            Debug.getMemoryInfo(pid, mi);
11956                        } else {
11957                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11958                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11959                        }
11960                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11961                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11962                        if (isCheckinRequest) {
11963                            pw.println();
11964                        }
11965                    }
11966                    return;
11967                }
11968            }
11969            pw.println("No process found for: " + args[opti]);
11970            return;
11971        }
11972
11973        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11974            dumpDetails = true;
11975        }
11976
11977        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11978
11979        String[] innerArgs = new String[args.length-opti];
11980        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11981
11982        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11983        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11984        long nativePss=0, dalvikPss=0, otherPss=0;
11985        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11986
11987        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11988        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11989                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11990
11991        long totalPss = 0;
11992        long cachedPss = 0;
11993
11994        Debug.MemoryInfo mi = null;
11995        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11996            final ProcessRecord r = procs.get(i);
11997            final IApplicationThread thread;
11998            final int pid;
11999            final int oomAdj;
12000            final boolean hasActivities;
12001            synchronized (this) {
12002                thread = r.thread;
12003                pid = r.pid;
12004                oomAdj = r.getSetAdjWithServices();
12005                hasActivities = r.activities.size() > 0;
12006            }
12007            if (thread != null) {
12008                if (!isCheckinRequest && dumpDetails) {
12009                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12010                }
12011                if (mi == null) {
12012                    mi = new Debug.MemoryInfo();
12013                }
12014                if (dumpDetails || (!brief && !oomOnly)) {
12015                    Debug.getMemoryInfo(pid, mi);
12016                } else {
12017                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12018                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12019                }
12020                if (dumpDetails) {
12021                    if (localOnly) {
12022                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12023                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12024                        if (isCheckinRequest) {
12025                            pw.println();
12026                        }
12027                    } else {
12028                        try {
12029                            pw.flush();
12030                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12031                                    dumpDalvik, innerArgs);
12032                        } catch (RemoteException e) {
12033                            if (!isCheckinRequest) {
12034                                pw.println("Got RemoteException!");
12035                                pw.flush();
12036                            }
12037                        }
12038                    }
12039                }
12040
12041                final long myTotalPss = mi.getTotalPss();
12042                final long myTotalUss = mi.getTotalUss();
12043
12044                synchronized (this) {
12045                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12046                        // Record this for posterity if the process has been stable.
12047                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12048                    }
12049                }
12050
12051                if (!isCheckinRequest && mi != null) {
12052                    totalPss += myTotalPss;
12053                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12054                            (hasActivities ? " / activities)" : ")"),
12055                            r.processName, myTotalPss, pid, hasActivities);
12056                    procMems.add(pssItem);
12057                    procMemsMap.put(pid, pssItem);
12058
12059                    nativePss += mi.nativePss;
12060                    dalvikPss += mi.dalvikPss;
12061                    otherPss += mi.otherPss;
12062                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12063                        long mem = mi.getOtherPss(j);
12064                        miscPss[j] += mem;
12065                        otherPss -= mem;
12066                    }
12067
12068                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12069                        cachedPss += myTotalPss;
12070                    }
12071
12072                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12073                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12074                                || oomIndex == (oomPss.length-1)) {
12075                            oomPss[oomIndex] += myTotalPss;
12076                            if (oomProcs[oomIndex] == null) {
12077                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12078                            }
12079                            oomProcs[oomIndex].add(pssItem);
12080                            break;
12081                        }
12082                    }
12083                }
12084            }
12085        }
12086
12087        if (!isCheckinRequest && procs.size() > 1) {
12088            // If we are showing aggregations, also look for native processes to
12089            // include so that our aggregations are more accurate.
12090            updateCpuStatsNow();
12091            synchronized (mProcessCpuThread) {
12092                final int N = mProcessCpuTracker.countStats();
12093                for (int i=0; i<N; i++) {
12094                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12095                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12096                        if (mi == null) {
12097                            mi = new Debug.MemoryInfo();
12098                        }
12099                        if (!brief && !oomOnly) {
12100                            Debug.getMemoryInfo(st.pid, mi);
12101                        } else {
12102                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12103                            mi.nativePrivateDirty = (int)tmpLong[0];
12104                        }
12105
12106                        final long myTotalPss = mi.getTotalPss();
12107                        totalPss += myTotalPss;
12108
12109                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12110                                st.name, myTotalPss, st.pid, false);
12111                        procMems.add(pssItem);
12112
12113                        nativePss += mi.nativePss;
12114                        dalvikPss += mi.dalvikPss;
12115                        otherPss += mi.otherPss;
12116                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12117                            long mem = mi.getOtherPss(j);
12118                            miscPss[j] += mem;
12119                            otherPss -= mem;
12120                        }
12121                        oomPss[0] += myTotalPss;
12122                        if (oomProcs[0] == null) {
12123                            oomProcs[0] = new ArrayList<MemItem>();
12124                        }
12125                        oomProcs[0].add(pssItem);
12126                    }
12127                }
12128            }
12129
12130            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12131
12132            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12133            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12134            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12135            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12136                String label = Debug.MemoryInfo.getOtherLabel(j);
12137                catMems.add(new MemItem(label, label, miscPss[j], j));
12138            }
12139
12140            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12141            for (int j=0; j<oomPss.length; j++) {
12142                if (oomPss[j] != 0) {
12143                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12144                            : DUMP_MEM_OOM_LABEL[j];
12145                    MemItem item = new MemItem(label, label, oomPss[j],
12146                            DUMP_MEM_OOM_ADJ[j]);
12147                    item.subitems = oomProcs[j];
12148                    oomMems.add(item);
12149                }
12150            }
12151
12152            if (!brief && !oomOnly && !isCompact) {
12153                pw.println();
12154                pw.println("Total PSS by process:");
12155                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12156                pw.println();
12157            }
12158            if (!isCompact) {
12159                pw.println("Total PSS by OOM adjustment:");
12160            }
12161            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12162            if (!brief && !oomOnly) {
12163                PrintWriter out = categoryPw != null ? categoryPw : pw;
12164                if (!isCompact) {
12165                    out.println();
12166                    out.println("Total PSS by category:");
12167                }
12168                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12169            }
12170            if (!isCompact) {
12171                pw.println();
12172            }
12173            MemInfoReader memInfo = new MemInfoReader();
12174            memInfo.readMemInfo();
12175            if (!brief) {
12176                if (!isCompact) {
12177                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12178                    pw.print(" kB (status ");
12179                    switch (mLastMemoryLevel) {
12180                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12181                            pw.println("normal)");
12182                            break;
12183                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12184                            pw.println("moderate)");
12185                            break;
12186                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12187                            pw.println("low)");
12188                            break;
12189                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12190                            pw.println("critical)");
12191                            break;
12192                        default:
12193                            pw.print(mLastMemoryLevel);
12194                            pw.println(")");
12195                            break;
12196                    }
12197                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12198                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12199                            pw.print(cachedPss); pw.print(" cached pss + ");
12200                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12201                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12202                } else {
12203                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12204                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12205                            + memInfo.getFreeSizeKb()); pw.print(",");
12206                    pw.println(totalPss - cachedPss);
12207                }
12208            }
12209            if (!isCompact) {
12210                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12211                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12212                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12213                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12214                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12215                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12216                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12217                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12218                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12219                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12220                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12221            }
12222            if (!brief) {
12223                if (memInfo.getZramTotalSizeKb() != 0) {
12224                    if (!isCompact) {
12225                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12226                                pw.print(" kB physical used for ");
12227                                pw.print(memInfo.getSwapTotalSizeKb()
12228                                        - memInfo.getSwapFreeSizeKb());
12229                                pw.print(" kB in swap (");
12230                                pw.print(memInfo.getSwapTotalSizeKb());
12231                                pw.println(" kB total swap)");
12232                    } else {
12233                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12234                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12235                                pw.println(memInfo.getSwapFreeSizeKb());
12236                    }
12237                }
12238                final int[] SINGLE_LONG_FORMAT = new int[] {
12239                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12240                };
12241                long[] longOut = new long[1];
12242                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12243                        SINGLE_LONG_FORMAT, null, longOut, null);
12244                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12245                longOut[0] = 0;
12246                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12247                        SINGLE_LONG_FORMAT, null, longOut, null);
12248                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12249                longOut[0] = 0;
12250                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12251                        SINGLE_LONG_FORMAT, null, longOut, null);
12252                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12253                longOut[0] = 0;
12254                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12255                        SINGLE_LONG_FORMAT, null, longOut, null);
12256                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12257                if (!isCompact) {
12258                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12259                        pw.print("      KSM: "); pw.print(sharing);
12260                                pw.print(" kB saved from shared ");
12261                                pw.print(shared); pw.println(" kB");
12262                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12263                                pw.print(voltile); pw.println(" kB volatile");
12264                    }
12265                    pw.print("   Tuning: ");
12266                    pw.print(ActivityManager.staticGetMemoryClass());
12267                    pw.print(" (large ");
12268                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12269                    pw.print("), oom ");
12270                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12271                    pw.print(" kB");
12272                    pw.print(", restore limit ");
12273                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12274                    pw.print(" kB");
12275                    if (ActivityManager.isLowRamDeviceStatic()) {
12276                        pw.print(" (low-ram)");
12277                    }
12278                    if (ActivityManager.isHighEndGfx()) {
12279                        pw.print(" (high-end-gfx)");
12280                    }
12281                    pw.println();
12282                } else {
12283                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12284                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12285                    pw.println(voltile);
12286                    pw.print("tuning,");
12287                    pw.print(ActivityManager.staticGetMemoryClass());
12288                    pw.print(',');
12289                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12290                    pw.print(',');
12291                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12292                    if (ActivityManager.isLowRamDeviceStatic()) {
12293                        pw.print(",low-ram");
12294                    }
12295                    if (ActivityManager.isHighEndGfx()) {
12296                        pw.print(",high-end-gfx");
12297                    }
12298                    pw.println();
12299                }
12300            }
12301        }
12302    }
12303
12304    /**
12305     * Searches array of arguments for the specified string
12306     * @param args array of argument strings
12307     * @param value value to search for
12308     * @return true if the value is contained in the array
12309     */
12310    private static boolean scanArgs(String[] args, String value) {
12311        if (args != null) {
12312            for (String arg : args) {
12313                if (value.equals(arg)) {
12314                    return true;
12315                }
12316            }
12317        }
12318        return false;
12319    }
12320
12321    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12322            ContentProviderRecord cpr, boolean always) {
12323        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12324
12325        if (!inLaunching || always) {
12326            synchronized (cpr) {
12327                cpr.launchingApp = null;
12328                cpr.notifyAll();
12329            }
12330            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12331            String names[] = cpr.info.authority.split(";");
12332            for (int j = 0; j < names.length; j++) {
12333                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12334            }
12335        }
12336
12337        for (int i=0; i<cpr.connections.size(); i++) {
12338            ContentProviderConnection conn = cpr.connections.get(i);
12339            if (conn.waiting) {
12340                // If this connection is waiting for the provider, then we don't
12341                // need to mess with its process unless we are always removing
12342                // or for some reason the provider is not currently launching.
12343                if (inLaunching && !always) {
12344                    continue;
12345                }
12346            }
12347            ProcessRecord capp = conn.client;
12348            conn.dead = true;
12349            if (conn.stableCount > 0) {
12350                if (!capp.persistent && capp.thread != null
12351                        && capp.pid != 0
12352                        && capp.pid != MY_PID) {
12353                    killUnneededProcessLocked(capp, "depends on provider "
12354                            + cpr.name.flattenToShortString()
12355                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12356                }
12357            } else if (capp.thread != null && conn.provider.provider != null) {
12358                try {
12359                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12360                } catch (RemoteException e) {
12361                }
12362                // In the protocol here, we don't expect the client to correctly
12363                // clean up this connection, we'll just remove it.
12364                cpr.connections.remove(i);
12365                conn.client.conProviders.remove(conn);
12366            }
12367        }
12368
12369        if (inLaunching && always) {
12370            mLaunchingProviders.remove(cpr);
12371        }
12372        return inLaunching;
12373    }
12374
12375    /**
12376     * Main code for cleaning up a process when it has gone away.  This is
12377     * called both as a result of the process dying, or directly when stopping
12378     * a process when running in single process mode.
12379     */
12380    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12381            boolean restarting, boolean allowRestart, int index) {
12382        if (index >= 0) {
12383            removeLruProcessLocked(app);
12384            ProcessList.remove(app.pid);
12385        }
12386
12387        mProcessesToGc.remove(app);
12388        mPendingPssProcesses.remove(app);
12389
12390        // Dismiss any open dialogs.
12391        if (app.crashDialog != null && !app.forceCrashReport) {
12392            app.crashDialog.dismiss();
12393            app.crashDialog = null;
12394        }
12395        if (app.anrDialog != null) {
12396            app.anrDialog.dismiss();
12397            app.anrDialog = null;
12398        }
12399        if (app.waitDialog != null) {
12400            app.waitDialog.dismiss();
12401            app.waitDialog = null;
12402        }
12403
12404        app.crashing = false;
12405        app.notResponding = false;
12406
12407        app.resetPackageList(mProcessStats);
12408        app.unlinkDeathRecipient();
12409        app.makeInactive(mProcessStats);
12410        app.forcingToForeground = null;
12411        updateProcessForegroundLocked(app, false, false);
12412        app.foregroundActivities = false;
12413        app.hasShownUi = false;
12414        app.hasAboveClient = false;
12415
12416        mServices.killServicesLocked(app, allowRestart);
12417
12418        boolean restart = false;
12419
12420        // Remove published content providers.
12421        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12422            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12423            final boolean always = app.bad || !allowRestart;
12424            if (removeDyingProviderLocked(app, cpr, always) || always) {
12425                // We left the provider in the launching list, need to
12426                // restart it.
12427                restart = true;
12428            }
12429
12430            cpr.provider = null;
12431            cpr.proc = null;
12432        }
12433        app.pubProviders.clear();
12434
12435        // Take care of any launching providers waiting for this process.
12436        if (checkAppInLaunchingProvidersLocked(app, false)) {
12437            restart = true;
12438        }
12439
12440        // Unregister from connected content providers.
12441        if (!app.conProviders.isEmpty()) {
12442            for (int i=0; i<app.conProviders.size(); i++) {
12443                ContentProviderConnection conn = app.conProviders.get(i);
12444                conn.provider.connections.remove(conn);
12445            }
12446            app.conProviders.clear();
12447        }
12448
12449        // At this point there may be remaining entries in mLaunchingProviders
12450        // where we were the only one waiting, so they are no longer of use.
12451        // Look for these and clean up if found.
12452        // XXX Commented out for now.  Trying to figure out a way to reproduce
12453        // the actual situation to identify what is actually going on.
12454        if (false) {
12455            for (int i=0; i<mLaunchingProviders.size(); i++) {
12456                ContentProviderRecord cpr = (ContentProviderRecord)
12457                        mLaunchingProviders.get(i);
12458                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12459                    synchronized (cpr) {
12460                        cpr.launchingApp = null;
12461                        cpr.notifyAll();
12462                    }
12463                }
12464            }
12465        }
12466
12467        skipCurrentReceiverLocked(app);
12468
12469        // Unregister any receivers.
12470        for (int i=app.receivers.size()-1; i>=0; i--) {
12471            removeReceiverLocked(app.receivers.valueAt(i));
12472        }
12473        app.receivers.clear();
12474
12475        // If the app is undergoing backup, tell the backup manager about it
12476        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12477            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12478                    + mBackupTarget.appInfo + " died during backup");
12479            try {
12480                IBackupManager bm = IBackupManager.Stub.asInterface(
12481                        ServiceManager.getService(Context.BACKUP_SERVICE));
12482                bm.agentDisconnected(app.info.packageName);
12483            } catch (RemoteException e) {
12484                // can't happen; backup manager is local
12485            }
12486        }
12487
12488        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12489            ProcessChangeItem item = mPendingProcessChanges.get(i);
12490            if (item.pid == app.pid) {
12491                mPendingProcessChanges.remove(i);
12492                mAvailProcessChanges.add(item);
12493            }
12494        }
12495        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12496
12497        // If the caller is restarting this app, then leave it in its
12498        // current lists and let the caller take care of it.
12499        if (restarting) {
12500            return;
12501        }
12502
12503        if (!app.persistent || app.isolated) {
12504            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12505                    "Removing non-persistent process during cleanup: " + app);
12506            mProcessNames.remove(app.processName, app.uid);
12507            mIsolatedProcesses.remove(app.uid);
12508            if (mHeavyWeightProcess == app) {
12509                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12510                        mHeavyWeightProcess.userId, 0));
12511                mHeavyWeightProcess = null;
12512            }
12513        } else if (!app.removed) {
12514            // This app is persistent, so we need to keep its record around.
12515            // If it is not already on the pending app list, add it there
12516            // and start a new process for it.
12517            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12518                mPersistentStartingProcesses.add(app);
12519                restart = true;
12520            }
12521        }
12522        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12523                "Clean-up removing on hold: " + app);
12524        mProcessesOnHold.remove(app);
12525
12526        if (app == mHomeProcess) {
12527            mHomeProcess = null;
12528        }
12529        if (app == mPreviousProcess) {
12530            mPreviousProcess = null;
12531        }
12532
12533        if (restart && !app.isolated) {
12534            // We have components that still need to be running in the
12535            // process, so re-launch it.
12536            mProcessNames.put(app.processName, app.uid, app);
12537            startProcessLocked(app, "restart", app.processName);
12538        } else if (app.pid > 0 && app.pid != MY_PID) {
12539            // Goodbye!
12540            boolean removed;
12541            synchronized (mPidsSelfLocked) {
12542                mPidsSelfLocked.remove(app.pid);
12543                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12544            }
12545            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12546                    app.processName, app.info.uid);
12547            if (app.isolated) {
12548                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12549            }
12550            app.setPid(0);
12551        }
12552    }
12553
12554    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12555        // Look through the content providers we are waiting to have launched,
12556        // and if any run in this process then either schedule a restart of
12557        // the process or kill the client waiting for it if this process has
12558        // gone bad.
12559        int NL = mLaunchingProviders.size();
12560        boolean restart = false;
12561        for (int i=0; i<NL; i++) {
12562            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12563            if (cpr.launchingApp == app) {
12564                if (!alwaysBad && !app.bad) {
12565                    restart = true;
12566                } else {
12567                    removeDyingProviderLocked(app, cpr, true);
12568                    // cpr should have been removed from mLaunchingProviders
12569                    NL = mLaunchingProviders.size();
12570                    i--;
12571                }
12572            }
12573        }
12574        return restart;
12575    }
12576
12577    // =========================================================
12578    // SERVICES
12579    // =========================================================
12580
12581    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12582            int flags) {
12583        enforceNotIsolatedCaller("getServices");
12584        synchronized (this) {
12585            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12586        }
12587    }
12588
12589    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12590        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12591        synchronized (this) {
12592            return mServices.getRunningServiceControlPanelLocked(name);
12593        }
12594    }
12595
12596    public ComponentName startService(IApplicationThread caller, Intent service,
12597            String resolvedType, int userId) {
12598        enforceNotIsolatedCaller("startService");
12599        // Refuse possible leaked file descriptors
12600        if (service != null && service.hasFileDescriptors() == true) {
12601            throw new IllegalArgumentException("File descriptors passed in Intent");
12602        }
12603
12604        if (DEBUG_SERVICE)
12605            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12606        synchronized(this) {
12607            final int callingPid = Binder.getCallingPid();
12608            final int callingUid = Binder.getCallingUid();
12609            final long origId = Binder.clearCallingIdentity();
12610            ComponentName res = mServices.startServiceLocked(caller, service,
12611                    resolvedType, callingPid, callingUid, userId);
12612            Binder.restoreCallingIdentity(origId);
12613            return res;
12614        }
12615    }
12616
12617    ComponentName startServiceInPackage(int uid,
12618            Intent service, String resolvedType, int userId) {
12619        synchronized(this) {
12620            if (DEBUG_SERVICE)
12621                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12622            final long origId = Binder.clearCallingIdentity();
12623            ComponentName res = mServices.startServiceLocked(null, service,
12624                    resolvedType, -1, uid, userId);
12625            Binder.restoreCallingIdentity(origId);
12626            return res;
12627        }
12628    }
12629
12630    public int stopService(IApplicationThread caller, Intent service,
12631            String resolvedType, int userId) {
12632        enforceNotIsolatedCaller("stopService");
12633        // Refuse possible leaked file descriptors
12634        if (service != null && service.hasFileDescriptors() == true) {
12635            throw new IllegalArgumentException("File descriptors passed in Intent");
12636        }
12637
12638        synchronized(this) {
12639            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12640        }
12641    }
12642
12643    public IBinder peekService(Intent service, String resolvedType) {
12644        enforceNotIsolatedCaller("peekService");
12645        // Refuse possible leaked file descriptors
12646        if (service != null && service.hasFileDescriptors() == true) {
12647            throw new IllegalArgumentException("File descriptors passed in Intent");
12648        }
12649        synchronized(this) {
12650            return mServices.peekServiceLocked(service, resolvedType);
12651        }
12652    }
12653
12654    public boolean stopServiceToken(ComponentName className, IBinder token,
12655            int startId) {
12656        synchronized(this) {
12657            return mServices.stopServiceTokenLocked(className, token, startId);
12658        }
12659    }
12660
12661    public void setServiceForeground(ComponentName className, IBinder token,
12662            int id, Notification notification, boolean removeNotification) {
12663        synchronized(this) {
12664            mServices.setServiceForegroundLocked(className, token, id, notification,
12665                    removeNotification);
12666        }
12667    }
12668
12669    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12670            boolean requireFull, String name, String callerPackage) {
12671        final int callingUserId = UserHandle.getUserId(callingUid);
12672        if (callingUserId != userId) {
12673            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12674                if ((requireFull || checkComponentPermission(
12675                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12676                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12677                        && checkComponentPermission(
12678                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12679                                callingPid, callingUid, -1, true)
12680                                != PackageManager.PERMISSION_GRANTED) {
12681                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12682                        // In this case, they would like to just execute as their
12683                        // owner user instead of failing.
12684                        userId = callingUserId;
12685                    } else {
12686                        StringBuilder builder = new StringBuilder(128);
12687                        builder.append("Permission Denial: ");
12688                        builder.append(name);
12689                        if (callerPackage != null) {
12690                            builder.append(" from ");
12691                            builder.append(callerPackage);
12692                        }
12693                        builder.append(" asks to run as user ");
12694                        builder.append(userId);
12695                        builder.append(" but is calling from user ");
12696                        builder.append(UserHandle.getUserId(callingUid));
12697                        builder.append("; this requires ");
12698                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12699                        if (!requireFull) {
12700                            builder.append(" or ");
12701                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12702                        }
12703                        String msg = builder.toString();
12704                        Slog.w(TAG, msg);
12705                        throw new SecurityException(msg);
12706                    }
12707                }
12708            }
12709            if (userId == UserHandle.USER_CURRENT
12710                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12711                // Note that we may be accessing this outside of a lock...
12712                // shouldn't be a big deal, if this is being called outside
12713                // of a locked context there is intrinsically a race with
12714                // the value the caller will receive and someone else changing it.
12715                userId = mCurrentUserId;
12716            }
12717            if (!allowAll && userId < 0) {
12718                throw new IllegalArgumentException(
12719                        "Call does not support special user #" + userId);
12720            }
12721        }
12722        return userId;
12723    }
12724
12725    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12726            String className, int flags) {
12727        boolean result = false;
12728        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12729            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12730                if (ActivityManager.checkUidPermission(
12731                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12732                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12733                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12734                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12735                            + " requests FLAG_SINGLE_USER, but app does not hold "
12736                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12737                    Slog.w(TAG, msg);
12738                    throw new SecurityException(msg);
12739                }
12740                result = true;
12741            }
12742        } else if (componentProcessName == aInfo.packageName) {
12743            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12744        } else if ("system".equals(componentProcessName)) {
12745            result = true;
12746        }
12747        if (DEBUG_MU) {
12748            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12749                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12750        }
12751        return result;
12752    }
12753
12754    public int bindService(IApplicationThread caller, IBinder token,
12755            Intent service, String resolvedType,
12756            IServiceConnection connection, int flags, int userId) {
12757        enforceNotIsolatedCaller("bindService");
12758        // Refuse possible leaked file descriptors
12759        if (service != null && service.hasFileDescriptors() == true) {
12760            throw new IllegalArgumentException("File descriptors passed in Intent");
12761        }
12762
12763        synchronized(this) {
12764            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12765                    connection, flags, userId);
12766        }
12767    }
12768
12769    public boolean unbindService(IServiceConnection connection) {
12770        synchronized (this) {
12771            return mServices.unbindServiceLocked(connection);
12772        }
12773    }
12774
12775    public void publishService(IBinder token, Intent intent, IBinder service) {
12776        // Refuse possible leaked file descriptors
12777        if (intent != null && intent.hasFileDescriptors() == true) {
12778            throw new IllegalArgumentException("File descriptors passed in Intent");
12779        }
12780
12781        synchronized(this) {
12782            if (!(token instanceof ServiceRecord)) {
12783                throw new IllegalArgumentException("Invalid service token");
12784            }
12785            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12786        }
12787    }
12788
12789    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12790        // Refuse possible leaked file descriptors
12791        if (intent != null && intent.hasFileDescriptors() == true) {
12792            throw new IllegalArgumentException("File descriptors passed in Intent");
12793        }
12794
12795        synchronized(this) {
12796            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12797        }
12798    }
12799
12800    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12801        synchronized(this) {
12802            if (!(token instanceof ServiceRecord)) {
12803                throw new IllegalArgumentException("Invalid service token");
12804            }
12805            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12806        }
12807    }
12808
12809    // =========================================================
12810    // BACKUP AND RESTORE
12811    // =========================================================
12812
12813    // Cause the target app to be launched if necessary and its backup agent
12814    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12815    // activity manager to announce its creation.
12816    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12817        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12818        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12819
12820        synchronized(this) {
12821            // !!! TODO: currently no check here that we're already bound
12822            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12823            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12824            synchronized (stats) {
12825                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12826            }
12827
12828            // Backup agent is now in use, its package can't be stopped.
12829            try {
12830                AppGlobals.getPackageManager().setPackageStoppedState(
12831                        app.packageName, false, UserHandle.getUserId(app.uid));
12832            } catch (RemoteException e) {
12833            } catch (IllegalArgumentException e) {
12834                Slog.w(TAG, "Failed trying to unstop package "
12835                        + app.packageName + ": " + e);
12836            }
12837
12838            BackupRecord r = new BackupRecord(ss, app, backupMode);
12839            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12840                    ? new ComponentName(app.packageName, app.backupAgentName)
12841                    : new ComponentName("android", "FullBackupAgent");
12842            // startProcessLocked() returns existing proc's record if it's already running
12843            ProcessRecord proc = startProcessLocked(app.processName, app,
12844                    false, 0, "backup", hostingName, false, false, false);
12845            if (proc == null) {
12846                Slog.e(TAG, "Unable to start backup agent process " + r);
12847                return false;
12848            }
12849
12850            r.app = proc;
12851            mBackupTarget = r;
12852            mBackupAppName = app.packageName;
12853
12854            // Try not to kill the process during backup
12855            updateOomAdjLocked(proc);
12856
12857            // If the process is already attached, schedule the creation of the backup agent now.
12858            // If it is not yet live, this will be done when it attaches to the framework.
12859            if (proc.thread != null) {
12860                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12861                try {
12862                    proc.thread.scheduleCreateBackupAgent(app,
12863                            compatibilityInfoForPackageLocked(app), backupMode);
12864                } catch (RemoteException e) {
12865                    // Will time out on the backup manager side
12866                }
12867            } else {
12868                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12869            }
12870            // Invariants: at this point, the target app process exists and the application
12871            // is either already running or in the process of coming up.  mBackupTarget and
12872            // mBackupAppName describe the app, so that when it binds back to the AM we
12873            // know that it's scheduled for a backup-agent operation.
12874        }
12875
12876        return true;
12877    }
12878
12879    @Override
12880    public void clearPendingBackup() {
12881        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12882        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12883
12884        synchronized (this) {
12885            mBackupTarget = null;
12886            mBackupAppName = null;
12887        }
12888    }
12889
12890    // A backup agent has just come up
12891    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12892        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12893                + " = " + agent);
12894
12895        synchronized(this) {
12896            if (!agentPackageName.equals(mBackupAppName)) {
12897                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12898                return;
12899            }
12900        }
12901
12902        long oldIdent = Binder.clearCallingIdentity();
12903        try {
12904            IBackupManager bm = IBackupManager.Stub.asInterface(
12905                    ServiceManager.getService(Context.BACKUP_SERVICE));
12906            bm.agentConnected(agentPackageName, agent);
12907        } catch (RemoteException e) {
12908            // can't happen; the backup manager service is local
12909        } catch (Exception e) {
12910            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12911            e.printStackTrace();
12912        } finally {
12913            Binder.restoreCallingIdentity(oldIdent);
12914        }
12915    }
12916
12917    // done with this agent
12918    public void unbindBackupAgent(ApplicationInfo appInfo) {
12919        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12920        if (appInfo == null) {
12921            Slog.w(TAG, "unbind backup agent for null app");
12922            return;
12923        }
12924
12925        synchronized(this) {
12926            try {
12927                if (mBackupAppName == null) {
12928                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12929                    return;
12930                }
12931
12932                if (!mBackupAppName.equals(appInfo.packageName)) {
12933                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12934                    return;
12935                }
12936
12937                // Not backing this app up any more; reset its OOM adjustment
12938                final ProcessRecord proc = mBackupTarget.app;
12939                updateOomAdjLocked(proc);
12940
12941                // If the app crashed during backup, 'thread' will be null here
12942                if (proc.thread != null) {
12943                    try {
12944                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12945                                compatibilityInfoForPackageLocked(appInfo));
12946                    } catch (Exception e) {
12947                        Slog.e(TAG, "Exception when unbinding backup agent:");
12948                        e.printStackTrace();
12949                    }
12950                }
12951            } finally {
12952                mBackupTarget = null;
12953                mBackupAppName = null;
12954            }
12955        }
12956    }
12957    // =========================================================
12958    // BROADCASTS
12959    // =========================================================
12960
12961    private final List getStickiesLocked(String action, IntentFilter filter,
12962            List cur, int userId) {
12963        final ContentResolver resolver = mContext.getContentResolver();
12964        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12965        if (stickies == null) {
12966            return cur;
12967        }
12968        final ArrayList<Intent> list = stickies.get(action);
12969        if (list == null) {
12970            return cur;
12971        }
12972        int N = list.size();
12973        for (int i=0; i<N; i++) {
12974            Intent intent = list.get(i);
12975            if (filter.match(resolver, intent, true, TAG) >= 0) {
12976                if (cur == null) {
12977                    cur = new ArrayList<Intent>();
12978                }
12979                cur.add(intent);
12980            }
12981        }
12982        return cur;
12983    }
12984
12985    boolean isPendingBroadcastProcessLocked(int pid) {
12986        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12987                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12988    }
12989
12990    void skipPendingBroadcastLocked(int pid) {
12991            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12992            for (BroadcastQueue queue : mBroadcastQueues) {
12993                queue.skipPendingBroadcastLocked(pid);
12994            }
12995    }
12996
12997    // The app just attached; send any pending broadcasts that it should receive
12998    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12999        boolean didSomething = false;
13000        for (BroadcastQueue queue : mBroadcastQueues) {
13001            didSomething |= queue.sendPendingBroadcastsLocked(app);
13002        }
13003        return didSomething;
13004    }
13005
13006    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13007            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13008        enforceNotIsolatedCaller("registerReceiver");
13009        int callingUid;
13010        int callingPid;
13011        synchronized(this) {
13012            ProcessRecord callerApp = null;
13013            if (caller != null) {
13014                callerApp = getRecordForAppLocked(caller);
13015                if (callerApp == null) {
13016                    throw new SecurityException(
13017                            "Unable to find app for caller " + caller
13018                            + " (pid=" + Binder.getCallingPid()
13019                            + ") when registering receiver " + receiver);
13020                }
13021                if (callerApp.info.uid != Process.SYSTEM_UID &&
13022                        !callerApp.pkgList.containsKey(callerPackage) &&
13023                        !"android".equals(callerPackage)) {
13024                    throw new SecurityException("Given caller package " + callerPackage
13025                            + " is not running in process " + callerApp);
13026                }
13027                callingUid = callerApp.info.uid;
13028                callingPid = callerApp.pid;
13029            } else {
13030                callerPackage = null;
13031                callingUid = Binder.getCallingUid();
13032                callingPid = Binder.getCallingPid();
13033            }
13034
13035            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13036                    true, true, "registerReceiver", callerPackage);
13037
13038            List allSticky = null;
13039
13040            // Look for any matching sticky broadcasts...
13041            Iterator actions = filter.actionsIterator();
13042            if (actions != null) {
13043                while (actions.hasNext()) {
13044                    String action = (String)actions.next();
13045                    allSticky = getStickiesLocked(action, filter, allSticky,
13046                            UserHandle.USER_ALL);
13047                    allSticky = getStickiesLocked(action, filter, allSticky,
13048                            UserHandle.getUserId(callingUid));
13049                }
13050            } else {
13051                allSticky = getStickiesLocked(null, filter, allSticky,
13052                        UserHandle.USER_ALL);
13053                allSticky = getStickiesLocked(null, filter, allSticky,
13054                        UserHandle.getUserId(callingUid));
13055            }
13056
13057            // The first sticky in the list is returned directly back to
13058            // the client.
13059            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13060
13061            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13062                    + ": " + sticky);
13063
13064            if (receiver == null) {
13065                return sticky;
13066            }
13067
13068            ReceiverList rl
13069                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13070            if (rl == null) {
13071                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13072                        userId, receiver);
13073                if (rl.app != null) {
13074                    rl.app.receivers.add(rl);
13075                } else {
13076                    try {
13077                        receiver.asBinder().linkToDeath(rl, 0);
13078                    } catch (RemoteException e) {
13079                        return sticky;
13080                    }
13081                    rl.linkedToDeath = true;
13082                }
13083                mRegisteredReceivers.put(receiver.asBinder(), rl);
13084            } else if (rl.uid != callingUid) {
13085                throw new IllegalArgumentException(
13086                        "Receiver requested to register for uid " + callingUid
13087                        + " was previously registered for uid " + rl.uid);
13088            } else if (rl.pid != callingPid) {
13089                throw new IllegalArgumentException(
13090                        "Receiver requested to register for pid " + callingPid
13091                        + " was previously registered for pid " + rl.pid);
13092            } else if (rl.userId != userId) {
13093                throw new IllegalArgumentException(
13094                        "Receiver requested to register for user " + userId
13095                        + " was previously registered for user " + rl.userId);
13096            }
13097            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13098                    permission, callingUid, userId);
13099            rl.add(bf);
13100            if (!bf.debugCheck()) {
13101                Slog.w(TAG, "==> For Dynamic broadast");
13102            }
13103            mReceiverResolver.addFilter(bf);
13104
13105            // Enqueue broadcasts for all existing stickies that match
13106            // this filter.
13107            if (allSticky != null) {
13108                ArrayList receivers = new ArrayList();
13109                receivers.add(bf);
13110
13111                int N = allSticky.size();
13112                for (int i=0; i<N; i++) {
13113                    Intent intent = (Intent)allSticky.get(i);
13114                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13115                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13116                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13117                            null, null, false, true, true, -1);
13118                    queue.enqueueParallelBroadcastLocked(r);
13119                    queue.scheduleBroadcastsLocked();
13120                }
13121            }
13122
13123            return sticky;
13124        }
13125    }
13126
13127    public void unregisterReceiver(IIntentReceiver receiver) {
13128        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13129
13130        final long origId = Binder.clearCallingIdentity();
13131        try {
13132            boolean doTrim = false;
13133
13134            synchronized(this) {
13135                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13136                if (rl != null) {
13137                    if (rl.curBroadcast != null) {
13138                        BroadcastRecord r = rl.curBroadcast;
13139                        final boolean doNext = finishReceiverLocked(
13140                                receiver.asBinder(), r.resultCode, r.resultData,
13141                                r.resultExtras, r.resultAbort);
13142                        if (doNext) {
13143                            doTrim = true;
13144                            r.queue.processNextBroadcast(false);
13145                        }
13146                    }
13147
13148                    if (rl.app != null) {
13149                        rl.app.receivers.remove(rl);
13150                    }
13151                    removeReceiverLocked(rl);
13152                    if (rl.linkedToDeath) {
13153                        rl.linkedToDeath = false;
13154                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13155                    }
13156                }
13157            }
13158
13159            // If we actually concluded any broadcasts, we might now be able
13160            // to trim the recipients' apps from our working set
13161            if (doTrim) {
13162                trimApplications();
13163                return;
13164            }
13165
13166        } finally {
13167            Binder.restoreCallingIdentity(origId);
13168        }
13169    }
13170
13171    void removeReceiverLocked(ReceiverList rl) {
13172        mRegisteredReceivers.remove(rl.receiver.asBinder());
13173        int N = rl.size();
13174        for (int i=0; i<N; i++) {
13175            mReceiverResolver.removeFilter(rl.get(i));
13176        }
13177    }
13178
13179    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13180        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13181            ProcessRecord r = mLruProcesses.get(i);
13182            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13183                try {
13184                    r.thread.dispatchPackageBroadcast(cmd, packages);
13185                } catch (RemoteException ex) {
13186                }
13187            }
13188        }
13189    }
13190
13191    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13192            int[] users) {
13193        List<ResolveInfo> receivers = null;
13194        try {
13195            HashSet<ComponentName> singleUserReceivers = null;
13196            boolean scannedFirstReceivers = false;
13197            for (int user : users) {
13198                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13199                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13200                if (user != 0 && newReceivers != null) {
13201                    // If this is not the primary user, we need to check for
13202                    // any receivers that should be filtered out.
13203                    for (int i=0; i<newReceivers.size(); i++) {
13204                        ResolveInfo ri = newReceivers.get(i);
13205                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13206                            newReceivers.remove(i);
13207                            i--;
13208                        }
13209                    }
13210                }
13211                if (newReceivers != null && newReceivers.size() == 0) {
13212                    newReceivers = null;
13213                }
13214                if (receivers == null) {
13215                    receivers = newReceivers;
13216                } else if (newReceivers != null) {
13217                    // We need to concatenate the additional receivers
13218                    // found with what we have do far.  This would be easy,
13219                    // but we also need to de-dup any receivers that are
13220                    // singleUser.
13221                    if (!scannedFirstReceivers) {
13222                        // Collect any single user receivers we had already retrieved.
13223                        scannedFirstReceivers = true;
13224                        for (int i=0; i<receivers.size(); i++) {
13225                            ResolveInfo ri = receivers.get(i);
13226                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13227                                ComponentName cn = new ComponentName(
13228                                        ri.activityInfo.packageName, ri.activityInfo.name);
13229                                if (singleUserReceivers == null) {
13230                                    singleUserReceivers = new HashSet<ComponentName>();
13231                                }
13232                                singleUserReceivers.add(cn);
13233                            }
13234                        }
13235                    }
13236                    // Add the new results to the existing results, tracking
13237                    // and de-dupping single user receivers.
13238                    for (int i=0; i<newReceivers.size(); i++) {
13239                        ResolveInfo ri = newReceivers.get(i);
13240                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13241                            ComponentName cn = new ComponentName(
13242                                    ri.activityInfo.packageName, ri.activityInfo.name);
13243                            if (singleUserReceivers == null) {
13244                                singleUserReceivers = new HashSet<ComponentName>();
13245                            }
13246                            if (!singleUserReceivers.contains(cn)) {
13247                                singleUserReceivers.add(cn);
13248                                receivers.add(ri);
13249                            }
13250                        } else {
13251                            receivers.add(ri);
13252                        }
13253                    }
13254                }
13255            }
13256        } catch (RemoteException ex) {
13257            // pm is in same process, this will never happen.
13258        }
13259        return receivers;
13260    }
13261
13262    private final int broadcastIntentLocked(ProcessRecord callerApp,
13263            String callerPackage, Intent intent, String resolvedType,
13264            IIntentReceiver resultTo, int resultCode, String resultData,
13265            Bundle map, String requiredPermission, int appOp,
13266            boolean ordered, boolean sticky, int callingPid, int callingUid,
13267            int userId) {
13268        intent = new Intent(intent);
13269
13270        // By default broadcasts do not go to stopped apps.
13271        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13272
13273        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13274            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13275            + " ordered=" + ordered + " userid=" + userId);
13276        if ((resultTo != null) && !ordered) {
13277            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13278        }
13279
13280        userId = handleIncomingUser(callingPid, callingUid, userId,
13281                true, false, "broadcast", callerPackage);
13282
13283        // Make sure that the user who is receiving this broadcast is started.
13284        // If not, we will just skip it.
13285        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13286            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13287                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13288                Slog.w(TAG, "Skipping broadcast of " + intent
13289                        + ": user " + userId + " is stopped");
13290                return ActivityManager.BROADCAST_SUCCESS;
13291            }
13292        }
13293
13294        /*
13295         * Prevent non-system code (defined here to be non-persistent
13296         * processes) from sending protected broadcasts.
13297         */
13298        int callingAppId = UserHandle.getAppId(callingUid);
13299        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13300            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13301            callingUid == 0) {
13302            // Always okay.
13303        } else if (callerApp == null || !callerApp.persistent) {
13304            try {
13305                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13306                        intent.getAction())) {
13307                    String msg = "Permission Denial: not allowed to send broadcast "
13308                            + intent.getAction() + " from pid="
13309                            + callingPid + ", uid=" + callingUid;
13310                    Slog.w(TAG, msg);
13311                    throw new SecurityException(msg);
13312                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13313                    // Special case for compatibility: we don't want apps to send this,
13314                    // but historically it has not been protected and apps may be using it
13315                    // to poke their own app widget.  So, instead of making it protected,
13316                    // just limit it to the caller.
13317                    if (callerApp == null) {
13318                        String msg = "Permission Denial: not allowed to send broadcast "
13319                                + intent.getAction() + " from unknown caller.";
13320                        Slog.w(TAG, msg);
13321                        throw new SecurityException(msg);
13322                    } else if (intent.getComponent() != null) {
13323                        // They are good enough to send to an explicit component...  verify
13324                        // it is being sent to the calling app.
13325                        if (!intent.getComponent().getPackageName().equals(
13326                                callerApp.info.packageName)) {
13327                            String msg = "Permission Denial: not allowed to send broadcast "
13328                                    + intent.getAction() + " to "
13329                                    + intent.getComponent().getPackageName() + " from "
13330                                    + callerApp.info.packageName;
13331                            Slog.w(TAG, msg);
13332                            throw new SecurityException(msg);
13333                        }
13334                    } else {
13335                        // Limit broadcast to their own package.
13336                        intent.setPackage(callerApp.info.packageName);
13337                    }
13338                }
13339            } catch (RemoteException e) {
13340                Slog.w(TAG, "Remote exception", e);
13341                return ActivityManager.BROADCAST_SUCCESS;
13342            }
13343        }
13344
13345        // Handle special intents: if this broadcast is from the package
13346        // manager about a package being removed, we need to remove all of
13347        // its activities from the history stack.
13348        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13349                intent.getAction());
13350        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13351                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13352                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13353                || uidRemoved) {
13354            if (checkComponentPermission(
13355                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13356                    callingPid, callingUid, -1, true)
13357                    == PackageManager.PERMISSION_GRANTED) {
13358                if (uidRemoved) {
13359                    final Bundle intentExtras = intent.getExtras();
13360                    final int uid = intentExtras != null
13361                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13362                    if (uid >= 0) {
13363                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13364                        synchronized (bs) {
13365                            bs.removeUidStatsLocked(uid);
13366                        }
13367                        mAppOpsService.uidRemoved(uid);
13368                    }
13369                } else {
13370                    // If resources are unavailable just force stop all
13371                    // those packages and flush the attribute cache as well.
13372                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13373                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13374                        if (list != null && (list.length > 0)) {
13375                            for (String pkg : list) {
13376                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13377                                        "storage unmount");
13378                            }
13379                            sendPackageBroadcastLocked(
13380                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13381                        }
13382                    } else {
13383                        Uri data = intent.getData();
13384                        String ssp;
13385                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13386                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13387                                    intent.getAction());
13388                            boolean fullUninstall = removed &&
13389                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13390                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13391                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13392                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13393                                        false, fullUninstall, userId,
13394                                        removed ? "pkg removed" : "pkg changed");
13395                            }
13396                            if (removed) {
13397                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13398                                        new String[] {ssp}, userId);
13399                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13400                                    mAppOpsService.packageRemoved(
13401                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13402
13403                                    // Remove all permissions granted from/to this package
13404                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13405                                }
13406                            }
13407                        }
13408                    }
13409                }
13410            } else {
13411                String msg = "Permission Denial: " + intent.getAction()
13412                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13413                        + ", uid=" + callingUid + ")"
13414                        + " requires "
13415                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13416                Slog.w(TAG, msg);
13417                throw new SecurityException(msg);
13418            }
13419
13420        // Special case for adding a package: by default turn on compatibility
13421        // mode.
13422        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13423            Uri data = intent.getData();
13424            String ssp;
13425            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13426                mCompatModePackages.handlePackageAddedLocked(ssp,
13427                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13428            }
13429        }
13430
13431        /*
13432         * If this is the time zone changed action, queue up a message that will reset the timezone
13433         * of all currently running processes. This message will get queued up before the broadcast
13434         * happens.
13435         */
13436        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13437            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13438        }
13439
13440        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13441            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13442        }
13443
13444        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13445            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13446            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13447        }
13448
13449        // Add to the sticky list if requested.
13450        if (sticky) {
13451            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13452                    callingPid, callingUid)
13453                    != PackageManager.PERMISSION_GRANTED) {
13454                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13455                        + callingPid + ", uid=" + callingUid
13456                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13457                Slog.w(TAG, msg);
13458                throw new SecurityException(msg);
13459            }
13460            if (requiredPermission != null) {
13461                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13462                        + " and enforce permission " + requiredPermission);
13463                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13464            }
13465            if (intent.getComponent() != null) {
13466                throw new SecurityException(
13467                        "Sticky broadcasts can't target a specific component");
13468            }
13469            // We use userId directly here, since the "all" target is maintained
13470            // as a separate set of sticky broadcasts.
13471            if (userId != UserHandle.USER_ALL) {
13472                // But first, if this is not a broadcast to all users, then
13473                // make sure it doesn't conflict with an existing broadcast to
13474                // all users.
13475                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13476                        UserHandle.USER_ALL);
13477                if (stickies != null) {
13478                    ArrayList<Intent> list = stickies.get(intent.getAction());
13479                    if (list != null) {
13480                        int N = list.size();
13481                        int i;
13482                        for (i=0; i<N; i++) {
13483                            if (intent.filterEquals(list.get(i))) {
13484                                throw new IllegalArgumentException(
13485                                        "Sticky broadcast " + intent + " for user "
13486                                        + userId + " conflicts with existing global broadcast");
13487                            }
13488                        }
13489                    }
13490                }
13491            }
13492            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13493            if (stickies == null) {
13494                stickies = new ArrayMap<String, ArrayList<Intent>>();
13495                mStickyBroadcasts.put(userId, stickies);
13496            }
13497            ArrayList<Intent> list = stickies.get(intent.getAction());
13498            if (list == null) {
13499                list = new ArrayList<Intent>();
13500                stickies.put(intent.getAction(), list);
13501            }
13502            int N = list.size();
13503            int i;
13504            for (i=0; i<N; i++) {
13505                if (intent.filterEquals(list.get(i))) {
13506                    // This sticky already exists, replace it.
13507                    list.set(i, new Intent(intent));
13508                    break;
13509                }
13510            }
13511            if (i >= N) {
13512                list.add(new Intent(intent));
13513            }
13514        }
13515
13516        int[] users;
13517        if (userId == UserHandle.USER_ALL) {
13518            // Caller wants broadcast to go to all started users.
13519            users = mStartedUserArray;
13520        } else {
13521            // Caller wants broadcast to go to one specific user.
13522            users = new int[] {userId};
13523        }
13524
13525        // Figure out who all will receive this broadcast.
13526        List receivers = null;
13527        List<BroadcastFilter> registeredReceivers = null;
13528        // Need to resolve the intent to interested receivers...
13529        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13530                 == 0) {
13531            receivers = collectReceiverComponents(intent, resolvedType, users);
13532        }
13533        if (intent.getComponent() == null) {
13534            registeredReceivers = mReceiverResolver.queryIntent(intent,
13535                    resolvedType, false, userId);
13536        }
13537
13538        final boolean replacePending =
13539                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13540
13541        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13542                + " replacePending=" + replacePending);
13543
13544        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13545        if (!ordered && NR > 0) {
13546            // If we are not serializing this broadcast, then send the
13547            // registered receivers separately so they don't wait for the
13548            // components to be launched.
13549            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13550            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13551                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13552                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13553                    ordered, sticky, false, userId);
13554            if (DEBUG_BROADCAST) Slog.v(
13555                    TAG, "Enqueueing parallel broadcast " + r);
13556            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13557            if (!replaced) {
13558                queue.enqueueParallelBroadcastLocked(r);
13559                queue.scheduleBroadcastsLocked();
13560            }
13561            registeredReceivers = null;
13562            NR = 0;
13563        }
13564
13565        // Merge into one list.
13566        int ir = 0;
13567        if (receivers != null) {
13568            // A special case for PACKAGE_ADDED: do not allow the package
13569            // being added to see this broadcast.  This prevents them from
13570            // using this as a back door to get run as soon as they are
13571            // installed.  Maybe in the future we want to have a special install
13572            // broadcast or such for apps, but we'd like to deliberately make
13573            // this decision.
13574            String skipPackages[] = null;
13575            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13576                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13577                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13578                Uri data = intent.getData();
13579                if (data != null) {
13580                    String pkgName = data.getSchemeSpecificPart();
13581                    if (pkgName != null) {
13582                        skipPackages = new String[] { pkgName };
13583                    }
13584                }
13585            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13586                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13587            }
13588            if (skipPackages != null && (skipPackages.length > 0)) {
13589                for (String skipPackage : skipPackages) {
13590                    if (skipPackage != null) {
13591                        int NT = receivers.size();
13592                        for (int it=0; it<NT; it++) {
13593                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13594                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13595                                receivers.remove(it);
13596                                it--;
13597                                NT--;
13598                            }
13599                        }
13600                    }
13601                }
13602            }
13603
13604            int NT = receivers != null ? receivers.size() : 0;
13605            int it = 0;
13606            ResolveInfo curt = null;
13607            BroadcastFilter curr = null;
13608            while (it < NT && ir < NR) {
13609                if (curt == null) {
13610                    curt = (ResolveInfo)receivers.get(it);
13611                }
13612                if (curr == null) {
13613                    curr = registeredReceivers.get(ir);
13614                }
13615                if (curr.getPriority() >= curt.priority) {
13616                    // Insert this broadcast record into the final list.
13617                    receivers.add(it, curr);
13618                    ir++;
13619                    curr = null;
13620                    it++;
13621                    NT++;
13622                } else {
13623                    // Skip to the next ResolveInfo in the final list.
13624                    it++;
13625                    curt = null;
13626                }
13627            }
13628        }
13629        while (ir < NR) {
13630            if (receivers == null) {
13631                receivers = new ArrayList();
13632            }
13633            receivers.add(registeredReceivers.get(ir));
13634            ir++;
13635        }
13636
13637        if ((receivers != null && receivers.size() > 0)
13638                || resultTo != null) {
13639            BroadcastQueue queue = broadcastQueueForIntent(intent);
13640            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13641                    callerPackage, callingPid, callingUid, resolvedType,
13642                    requiredPermission, appOp, receivers, resultTo, resultCode,
13643                    resultData, map, ordered, sticky, false, userId);
13644            if (DEBUG_BROADCAST) Slog.v(
13645                    TAG, "Enqueueing ordered broadcast " + r
13646                    + ": prev had " + queue.mOrderedBroadcasts.size());
13647            if (DEBUG_BROADCAST) {
13648                int seq = r.intent.getIntExtra("seq", -1);
13649                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13650            }
13651            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13652            if (!replaced) {
13653                queue.enqueueOrderedBroadcastLocked(r);
13654                queue.scheduleBroadcastsLocked();
13655            }
13656        }
13657
13658        return ActivityManager.BROADCAST_SUCCESS;
13659    }
13660
13661    final Intent verifyBroadcastLocked(Intent intent) {
13662        // Refuse possible leaked file descriptors
13663        if (intent != null && intent.hasFileDescriptors() == true) {
13664            throw new IllegalArgumentException("File descriptors passed in Intent");
13665        }
13666
13667        int flags = intent.getFlags();
13668
13669        if (!mProcessesReady) {
13670            // if the caller really truly claims to know what they're doing, go
13671            // ahead and allow the broadcast without launching any receivers
13672            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13673                intent = new Intent(intent);
13674                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13675            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13676                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13677                        + " before boot completion");
13678                throw new IllegalStateException("Cannot broadcast before boot completed");
13679            }
13680        }
13681
13682        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13683            throw new IllegalArgumentException(
13684                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13685        }
13686
13687        return intent;
13688    }
13689
13690    public final int broadcastIntent(IApplicationThread caller,
13691            Intent intent, String resolvedType, IIntentReceiver resultTo,
13692            int resultCode, String resultData, Bundle map,
13693            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13694        enforceNotIsolatedCaller("broadcastIntent");
13695        synchronized(this) {
13696            intent = verifyBroadcastLocked(intent);
13697
13698            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13699            final int callingPid = Binder.getCallingPid();
13700            final int callingUid = Binder.getCallingUid();
13701            final long origId = Binder.clearCallingIdentity();
13702            int res = broadcastIntentLocked(callerApp,
13703                    callerApp != null ? callerApp.info.packageName : null,
13704                    intent, resolvedType, resultTo,
13705                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13706                    callingPid, callingUid, userId);
13707            Binder.restoreCallingIdentity(origId);
13708            return res;
13709        }
13710    }
13711
13712    int broadcastIntentInPackage(String packageName, int uid,
13713            Intent intent, String resolvedType, IIntentReceiver resultTo,
13714            int resultCode, String resultData, Bundle map,
13715            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13716        synchronized(this) {
13717            intent = verifyBroadcastLocked(intent);
13718
13719            final long origId = Binder.clearCallingIdentity();
13720            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13721                    resultTo, resultCode, resultData, map, requiredPermission,
13722                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13723            Binder.restoreCallingIdentity(origId);
13724            return res;
13725        }
13726    }
13727
13728    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13729        // Refuse possible leaked file descriptors
13730        if (intent != null && intent.hasFileDescriptors() == true) {
13731            throw new IllegalArgumentException("File descriptors passed in Intent");
13732        }
13733
13734        userId = handleIncomingUser(Binder.getCallingPid(),
13735                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13736
13737        synchronized(this) {
13738            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13739                    != PackageManager.PERMISSION_GRANTED) {
13740                String msg = "Permission Denial: unbroadcastIntent() from pid="
13741                        + Binder.getCallingPid()
13742                        + ", uid=" + Binder.getCallingUid()
13743                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13744                Slog.w(TAG, msg);
13745                throw new SecurityException(msg);
13746            }
13747            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13748            if (stickies != null) {
13749                ArrayList<Intent> list = stickies.get(intent.getAction());
13750                if (list != null) {
13751                    int N = list.size();
13752                    int i;
13753                    for (i=0; i<N; i++) {
13754                        if (intent.filterEquals(list.get(i))) {
13755                            list.remove(i);
13756                            break;
13757                        }
13758                    }
13759                    if (list.size() <= 0) {
13760                        stickies.remove(intent.getAction());
13761                    }
13762                }
13763                if (stickies.size() <= 0) {
13764                    mStickyBroadcasts.remove(userId);
13765                }
13766            }
13767        }
13768    }
13769
13770    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13771            String resultData, Bundle resultExtras, boolean resultAbort) {
13772        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13773        if (r == null) {
13774            Slog.w(TAG, "finishReceiver called but not found on queue");
13775            return false;
13776        }
13777
13778        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13779    }
13780
13781    void backgroundServicesFinishedLocked(int userId) {
13782        for (BroadcastQueue queue : mBroadcastQueues) {
13783            queue.backgroundServicesFinishedLocked(userId);
13784        }
13785    }
13786
13787    public void finishReceiver(IBinder who, int resultCode, String resultData,
13788            Bundle resultExtras, boolean resultAbort) {
13789        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13790
13791        // Refuse possible leaked file descriptors
13792        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13793            throw new IllegalArgumentException("File descriptors passed in Bundle");
13794        }
13795
13796        final long origId = Binder.clearCallingIdentity();
13797        try {
13798            boolean doNext = false;
13799            BroadcastRecord r;
13800
13801            synchronized(this) {
13802                r = broadcastRecordForReceiverLocked(who);
13803                if (r != null) {
13804                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13805                        resultData, resultExtras, resultAbort, true);
13806                }
13807            }
13808
13809            if (doNext) {
13810                r.queue.processNextBroadcast(false);
13811            }
13812            trimApplications();
13813        } finally {
13814            Binder.restoreCallingIdentity(origId);
13815        }
13816    }
13817
13818    // =========================================================
13819    // INSTRUMENTATION
13820    // =========================================================
13821
13822    public boolean startInstrumentation(ComponentName className,
13823            String profileFile, int flags, Bundle arguments,
13824            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13825            int userId) {
13826        enforceNotIsolatedCaller("startInstrumentation");
13827        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13828                userId, false, true, "startInstrumentation", null);
13829        // Refuse possible leaked file descriptors
13830        if (arguments != null && arguments.hasFileDescriptors()) {
13831            throw new IllegalArgumentException("File descriptors passed in Bundle");
13832        }
13833
13834        synchronized(this) {
13835            InstrumentationInfo ii = null;
13836            ApplicationInfo ai = null;
13837            try {
13838                ii = mContext.getPackageManager().getInstrumentationInfo(
13839                    className, STOCK_PM_FLAGS);
13840                ai = AppGlobals.getPackageManager().getApplicationInfo(
13841                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13842            } catch (PackageManager.NameNotFoundException e) {
13843            } catch (RemoteException e) {
13844            }
13845            if (ii == null) {
13846                reportStartInstrumentationFailure(watcher, className,
13847                        "Unable to find instrumentation info for: " + className);
13848                return false;
13849            }
13850            if (ai == null) {
13851                reportStartInstrumentationFailure(watcher, className,
13852                        "Unable to find instrumentation target package: " + ii.targetPackage);
13853                return false;
13854            }
13855
13856            int match = mContext.getPackageManager().checkSignatures(
13857                    ii.targetPackage, ii.packageName);
13858            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13859                String msg = "Permission Denial: starting instrumentation "
13860                        + className + " from pid="
13861                        + Binder.getCallingPid()
13862                        + ", uid=" + Binder.getCallingPid()
13863                        + " not allowed because package " + ii.packageName
13864                        + " does not have a signature matching the target "
13865                        + ii.targetPackage;
13866                reportStartInstrumentationFailure(watcher, className, msg);
13867                throw new SecurityException(msg);
13868            }
13869
13870            final long origId = Binder.clearCallingIdentity();
13871            // Instrumentation can kill and relaunch even persistent processes
13872            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
13873                    "start instr");
13874            ProcessRecord app = addAppLocked(ai, false);
13875            app.instrumentationClass = className;
13876            app.instrumentationInfo = ai;
13877            app.instrumentationProfileFile = profileFile;
13878            app.instrumentationArguments = arguments;
13879            app.instrumentationWatcher = watcher;
13880            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13881            app.instrumentationResultClass = className;
13882            Binder.restoreCallingIdentity(origId);
13883        }
13884
13885        return true;
13886    }
13887
13888    /**
13889     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13890     * error to the logs, but if somebody is watching, send the report there too.  This enables
13891     * the "am" command to report errors with more information.
13892     *
13893     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13894     * @param cn The component name of the instrumentation.
13895     * @param report The error report.
13896     */
13897    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13898            ComponentName cn, String report) {
13899        Slog.w(TAG, report);
13900        try {
13901            if (watcher != null) {
13902                Bundle results = new Bundle();
13903                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13904                results.putString("Error", report);
13905                watcher.instrumentationStatus(cn, -1, results);
13906            }
13907        } catch (RemoteException e) {
13908            Slog.w(TAG, e);
13909        }
13910    }
13911
13912    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13913        if (app.instrumentationWatcher != null) {
13914            try {
13915                // NOTE:  IInstrumentationWatcher *must* be oneway here
13916                app.instrumentationWatcher.instrumentationFinished(
13917                    app.instrumentationClass,
13918                    resultCode,
13919                    results);
13920            } catch (RemoteException e) {
13921            }
13922        }
13923        if (app.instrumentationUiAutomationConnection != null) {
13924            try {
13925                app.instrumentationUiAutomationConnection.shutdown();
13926            } catch (RemoteException re) {
13927                /* ignore */
13928            }
13929            // Only a UiAutomation can set this flag and now that
13930            // it is finished we make sure it is reset to its default.
13931            mUserIsMonkey = false;
13932        }
13933        app.instrumentationWatcher = null;
13934        app.instrumentationUiAutomationConnection = null;
13935        app.instrumentationClass = null;
13936        app.instrumentationInfo = null;
13937        app.instrumentationProfileFile = null;
13938        app.instrumentationArguments = null;
13939
13940        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
13941                "finished inst");
13942    }
13943
13944    public void finishInstrumentation(IApplicationThread target,
13945            int resultCode, Bundle results) {
13946        int userId = UserHandle.getCallingUserId();
13947        // Refuse possible leaked file descriptors
13948        if (results != null && results.hasFileDescriptors()) {
13949            throw new IllegalArgumentException("File descriptors passed in Intent");
13950        }
13951
13952        synchronized(this) {
13953            ProcessRecord app = getRecordForAppLocked(target);
13954            if (app == null) {
13955                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13956                return;
13957            }
13958            final long origId = Binder.clearCallingIdentity();
13959            finishInstrumentationLocked(app, resultCode, results);
13960            Binder.restoreCallingIdentity(origId);
13961        }
13962    }
13963
13964    // =========================================================
13965    // CONFIGURATION
13966    // =========================================================
13967
13968    public ConfigurationInfo getDeviceConfigurationInfo() {
13969        ConfigurationInfo config = new ConfigurationInfo();
13970        synchronized (this) {
13971            config.reqTouchScreen = mConfiguration.touchscreen;
13972            config.reqKeyboardType = mConfiguration.keyboard;
13973            config.reqNavigation = mConfiguration.navigation;
13974            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13975                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13976                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13977            }
13978            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13979                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13980                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13981            }
13982            config.reqGlEsVersion = GL_ES_VERSION;
13983        }
13984        return config;
13985    }
13986
13987    ActivityStack getFocusedStack() {
13988        return mStackSupervisor.getFocusedStack();
13989    }
13990
13991    public Configuration getConfiguration() {
13992        Configuration ci;
13993        synchronized(this) {
13994            ci = new Configuration(mConfiguration);
13995        }
13996        return ci;
13997    }
13998
13999    public void updatePersistentConfiguration(Configuration values) {
14000        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14001                "updateConfiguration()");
14002        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14003                "updateConfiguration()");
14004        if (values == null) {
14005            throw new NullPointerException("Configuration must not be null");
14006        }
14007
14008        synchronized(this) {
14009            final long origId = Binder.clearCallingIdentity();
14010            updateConfigurationLocked(values, null, true, false);
14011            Binder.restoreCallingIdentity(origId);
14012        }
14013    }
14014
14015    public void updateConfiguration(Configuration values) {
14016        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14017                "updateConfiguration()");
14018
14019        synchronized(this) {
14020            if (values == null && mWindowManager != null) {
14021                // sentinel: fetch the current configuration from the window manager
14022                values = mWindowManager.computeNewConfiguration();
14023            }
14024
14025            if (mWindowManager != null) {
14026                mProcessList.applyDisplaySize(mWindowManager);
14027            }
14028
14029            final long origId = Binder.clearCallingIdentity();
14030            if (values != null) {
14031                Settings.System.clearConfiguration(values);
14032            }
14033            updateConfigurationLocked(values, null, false, false);
14034            Binder.restoreCallingIdentity(origId);
14035        }
14036    }
14037
14038    /**
14039     * Do either or both things: (1) change the current configuration, and (2)
14040     * make sure the given activity is running with the (now) current
14041     * configuration.  Returns true if the activity has been left running, or
14042     * false if <var>starting</var> is being destroyed to match the new
14043     * configuration.
14044     * @param persistent TODO
14045     */
14046    boolean updateConfigurationLocked(Configuration values,
14047            ActivityRecord starting, boolean persistent, boolean initLocale) {
14048        int changes = 0;
14049
14050        if (values != null) {
14051            Configuration newConfig = new Configuration(mConfiguration);
14052            changes = newConfig.updateFrom(values);
14053            if (changes != 0) {
14054                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14055                    Slog.i(TAG, "Updating configuration to: " + values);
14056                }
14057
14058                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14059
14060                if (values.locale != null && !initLocale) {
14061                    saveLocaleLocked(values.locale,
14062                                     !values.locale.equals(mConfiguration.locale),
14063                                     values.userSetLocale);
14064                }
14065
14066                mConfigurationSeq++;
14067                if (mConfigurationSeq <= 0) {
14068                    mConfigurationSeq = 1;
14069                }
14070                newConfig.seq = mConfigurationSeq;
14071                mConfiguration = newConfig;
14072                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14073
14074                final Configuration configCopy = new Configuration(mConfiguration);
14075
14076                // TODO: If our config changes, should we auto dismiss any currently
14077                // showing dialogs?
14078                mShowDialogs = shouldShowDialogs(newConfig);
14079
14080                AttributeCache ac = AttributeCache.instance();
14081                if (ac != null) {
14082                    ac.updateConfiguration(configCopy);
14083                }
14084
14085                // Make sure all resources in our process are updated
14086                // right now, so that anyone who is going to retrieve
14087                // resource values after we return will be sure to get
14088                // the new ones.  This is especially important during
14089                // boot, where the first config change needs to guarantee
14090                // all resources have that config before following boot
14091                // code is executed.
14092                mSystemThread.applyConfigurationToResources(configCopy);
14093
14094                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14095                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14096                    msg.obj = new Configuration(configCopy);
14097                    mHandler.sendMessage(msg);
14098                }
14099
14100                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14101                    ProcessRecord app = mLruProcesses.get(i);
14102                    try {
14103                        if (app.thread != null) {
14104                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14105                                    + app.processName + " new config " + mConfiguration);
14106                            app.thread.scheduleConfigurationChanged(configCopy);
14107                        }
14108                    } catch (Exception e) {
14109                    }
14110                }
14111                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14112                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14113                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14114                        | Intent.FLAG_RECEIVER_FOREGROUND);
14115                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14116                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14117                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14118                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14119                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14120                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14121                    broadcastIntentLocked(null, null, intent,
14122                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14123                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14124                }
14125            }
14126        }
14127
14128        boolean kept = true;
14129        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14130        // mainStack is null during startup.
14131        if (mainStack != null) {
14132            if (changes != 0 && starting == null) {
14133                // If the configuration changed, and the caller is not already
14134                // in the process of starting an activity, then find the top
14135                // activity to check if its configuration needs to change.
14136                starting = mainStack.topRunningActivityLocked(null);
14137            }
14138
14139            if (starting != null) {
14140                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14141                // And we need to make sure at this point that all other activities
14142                // are made visible with the correct configuration.
14143                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14144            }
14145        }
14146
14147        if (values != null && mWindowManager != null) {
14148            mWindowManager.setNewConfiguration(mConfiguration);
14149        }
14150
14151        return kept;
14152    }
14153
14154    /**
14155     * Decide based on the configuration whether we should shouw the ANR,
14156     * crash, etc dialogs.  The idea is that if there is no affordnace to
14157     * press the on-screen buttons, we shouldn't show the dialog.
14158     *
14159     * A thought: SystemUI might also want to get told about this, the Power
14160     * dialog / global actions also might want different behaviors.
14161     */
14162    private static final boolean shouldShowDialogs(Configuration config) {
14163        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14164                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14165    }
14166
14167    /**
14168     * Save the locale.  You must be inside a synchronized (this) block.
14169     */
14170    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14171        if(isDiff) {
14172            SystemProperties.set("user.language", l.getLanguage());
14173            SystemProperties.set("user.region", l.getCountry());
14174        }
14175
14176        if(isPersist) {
14177            SystemProperties.set("persist.sys.language", l.getLanguage());
14178            SystemProperties.set("persist.sys.country", l.getCountry());
14179            SystemProperties.set("persist.sys.localevar", l.getVariant());
14180        }
14181    }
14182
14183    @Override
14184    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14185        ActivityRecord srec = ActivityRecord.forToken(token);
14186        return srec != null && srec.task.affinity != null &&
14187                srec.task.affinity.equals(destAffinity);
14188    }
14189
14190    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14191            Intent resultData) {
14192
14193        synchronized (this) {
14194            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14195            if (stack != null) {
14196                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14197            }
14198            return false;
14199        }
14200    }
14201
14202    public int getLaunchedFromUid(IBinder activityToken) {
14203        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14204        if (srec == null) {
14205            return -1;
14206        }
14207        return srec.launchedFromUid;
14208    }
14209
14210    public String getLaunchedFromPackage(IBinder activityToken) {
14211        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14212        if (srec == null) {
14213            return null;
14214        }
14215        return srec.launchedFromPackage;
14216    }
14217
14218    // =========================================================
14219    // LIFETIME MANAGEMENT
14220    // =========================================================
14221
14222    // Returns which broadcast queue the app is the current [or imminent] receiver
14223    // on, or 'null' if the app is not an active broadcast recipient.
14224    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14225        BroadcastRecord r = app.curReceiver;
14226        if (r != null) {
14227            return r.queue;
14228        }
14229
14230        // It's not the current receiver, but it might be starting up to become one
14231        synchronized (this) {
14232            for (BroadcastQueue queue : mBroadcastQueues) {
14233                r = queue.mPendingBroadcast;
14234                if (r != null && r.curApp == app) {
14235                    // found it; report which queue it's in
14236                    return queue;
14237                }
14238            }
14239        }
14240
14241        return null;
14242    }
14243
14244    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14245            boolean doingAll, long now) {
14246        if (mAdjSeq == app.adjSeq) {
14247            // This adjustment has already been computed.
14248            return app.curRawAdj;
14249        }
14250
14251        if (app.thread == null) {
14252            app.adjSeq = mAdjSeq;
14253            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14254            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14255            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14256        }
14257
14258        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14259        app.adjSource = null;
14260        app.adjTarget = null;
14261        app.empty = false;
14262        app.cached = false;
14263
14264        final int activitiesSize = app.activities.size();
14265
14266        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14267            // The max adjustment doesn't allow this app to be anything
14268            // below foreground, so it is not worth doing work for it.
14269            app.adjType = "fixed";
14270            app.adjSeq = mAdjSeq;
14271            app.curRawAdj = app.maxAdj;
14272            app.foregroundActivities = false;
14273            app.keeping = true;
14274            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14275            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14276            // System process can do UI, and when they do we want to have
14277            // them trim their memory after the user leaves the UI.  To
14278            // facilitate this, here we need to determine whether or not it
14279            // is currently showing UI.
14280            app.systemNoUi = true;
14281            if (app == TOP_APP) {
14282                app.systemNoUi = false;
14283            } else if (activitiesSize > 0) {
14284                for (int j = 0; j < activitiesSize; j++) {
14285                    final ActivityRecord r = app.activities.get(j);
14286                    if (r.visible) {
14287                        app.systemNoUi = false;
14288                    }
14289                }
14290            }
14291            if (!app.systemNoUi) {
14292                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14293            }
14294            return (app.curAdj=app.maxAdj);
14295        }
14296
14297        app.keeping = false;
14298        app.systemNoUi = false;
14299
14300        // Determine the importance of the process, starting with most
14301        // important to least, and assign an appropriate OOM adjustment.
14302        int adj;
14303        int schedGroup;
14304        int procState;
14305        boolean foregroundActivities = false;
14306        boolean interesting = false;
14307        BroadcastQueue queue;
14308        if (app == TOP_APP) {
14309            // The last app on the list is the foreground app.
14310            adj = ProcessList.FOREGROUND_APP_ADJ;
14311            schedGroup = Process.THREAD_GROUP_DEFAULT;
14312            app.adjType = "top-activity";
14313            foregroundActivities = true;
14314            interesting = true;
14315            procState = ActivityManager.PROCESS_STATE_TOP;
14316        } else if (app.instrumentationClass != null) {
14317            // Don't want to kill running instrumentation.
14318            adj = ProcessList.FOREGROUND_APP_ADJ;
14319            schedGroup = Process.THREAD_GROUP_DEFAULT;
14320            app.adjType = "instrumentation";
14321            interesting = true;
14322            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14323        } else if ((queue = isReceivingBroadcast(app)) != null) {
14324            // An app that is currently receiving a broadcast also
14325            // counts as being in the foreground for OOM killer purposes.
14326            // It's placed in a sched group based on the nature of the
14327            // broadcast as reflected by which queue it's active in.
14328            adj = ProcessList.FOREGROUND_APP_ADJ;
14329            schedGroup = (queue == mFgBroadcastQueue)
14330                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14331            app.adjType = "broadcast";
14332            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14333        } else if (app.executingServices.size() > 0) {
14334            // An app that is currently executing a service callback also
14335            // counts as being in the foreground.
14336            adj = ProcessList.FOREGROUND_APP_ADJ;
14337            schedGroup = app.execServicesFg ?
14338                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14339            app.adjType = "exec-service";
14340            procState = ActivityManager.PROCESS_STATE_SERVICE;
14341            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14342        } else {
14343            // As far as we know the process is empty.  We may change our mind later.
14344            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14345            // At this point we don't actually know the adjustment.  Use the cached adj
14346            // value that the caller wants us to.
14347            adj = cachedAdj;
14348            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14349            app.cached = true;
14350            app.empty = true;
14351            app.adjType = "cch-empty";
14352        }
14353
14354        // Examine all activities if not already foreground.
14355        if (!foregroundActivities && activitiesSize > 0) {
14356            for (int j = 0; j < activitiesSize; j++) {
14357                final ActivityRecord r = app.activities.get(j);
14358                if (r.app != app) {
14359                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14360                            + app + "?!?");
14361                    continue;
14362                }
14363                if (r.visible) {
14364                    // App has a visible activity; only upgrade adjustment.
14365                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14366                        adj = ProcessList.VISIBLE_APP_ADJ;
14367                        app.adjType = "visible";
14368                    }
14369                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14370                        procState = ActivityManager.PROCESS_STATE_TOP;
14371                    }
14372                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14373                    app.cached = false;
14374                    app.empty = false;
14375                    foregroundActivities = true;
14376                    break;
14377                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14378                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14379                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14380                        app.adjType = "pausing";
14381                    }
14382                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14383                        procState = ActivityManager.PROCESS_STATE_TOP;
14384                    }
14385                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14386                    app.cached = false;
14387                    app.empty = false;
14388                    foregroundActivities = true;
14389                } else if (r.state == ActivityState.STOPPING) {
14390                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14391                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14392                        app.adjType = "stopping";
14393                    }
14394                    // For the process state, we will at this point consider the
14395                    // process to be cached.  It will be cached either as an activity
14396                    // or empty depending on whether the activity is finishing.  We do
14397                    // this so that we can treat the process as cached for purposes of
14398                    // memory trimming (determing current memory level, trim command to
14399                    // send to process) since there can be an arbitrary number of stopping
14400                    // processes and they should soon all go into the cached state.
14401                    if (!r.finishing) {
14402                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14403                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14404                        }
14405                    }
14406                    app.cached = false;
14407                    app.empty = false;
14408                    foregroundActivities = true;
14409                } else {
14410                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14411                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14412                        app.adjType = "cch-act";
14413                    }
14414                }
14415            }
14416        }
14417
14418        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14419            if (app.foregroundServices) {
14420                // The user is aware of this app, so make it visible.
14421                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14422                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14423                app.cached = false;
14424                app.adjType = "fg-service";
14425                schedGroup = Process.THREAD_GROUP_DEFAULT;
14426            } else if (app.forcingToForeground != null) {
14427                // The user is aware of this app, so make it visible.
14428                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14429                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14430                app.cached = false;
14431                app.adjType = "force-fg";
14432                app.adjSource = app.forcingToForeground;
14433                schedGroup = Process.THREAD_GROUP_DEFAULT;
14434            }
14435        }
14436
14437        if (app.foregroundServices) {
14438            interesting = true;
14439        }
14440
14441        if (app == mHeavyWeightProcess) {
14442            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14443                // We don't want to kill the current heavy-weight process.
14444                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14445                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14446                app.cached = false;
14447                app.adjType = "heavy";
14448            }
14449            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14450                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14451            }
14452        }
14453
14454        if (app == mHomeProcess) {
14455            if (adj > ProcessList.HOME_APP_ADJ) {
14456                // This process is hosting what we currently consider to be the
14457                // home app, so we don't want to let it go into the background.
14458                adj = ProcessList.HOME_APP_ADJ;
14459                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14460                app.cached = false;
14461                app.adjType = "home";
14462            }
14463            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14464                procState = ActivityManager.PROCESS_STATE_HOME;
14465            }
14466        }
14467
14468        if (app == mPreviousProcess && app.activities.size() > 0) {
14469            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14470                // This was the previous process that showed UI to the user.
14471                // We want to try to keep it around more aggressively, to give
14472                // a good experience around switching between two apps.
14473                adj = ProcessList.PREVIOUS_APP_ADJ;
14474                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14475                app.cached = false;
14476                app.adjType = "previous";
14477            }
14478            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14479                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14480            }
14481        }
14482
14483        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14484                + " reason=" + app.adjType);
14485
14486        // By default, we use the computed adjustment.  It may be changed if
14487        // there are applications dependent on our services or providers, but
14488        // this gives us a baseline and makes sure we don't get into an
14489        // infinite recursion.
14490        app.adjSeq = mAdjSeq;
14491        app.curRawAdj = adj;
14492        app.hasStartedServices = false;
14493
14494        if (mBackupTarget != null && app == mBackupTarget.app) {
14495            // If possible we want to avoid killing apps while they're being backed up
14496            if (adj > ProcessList.BACKUP_APP_ADJ) {
14497                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14498                adj = ProcessList.BACKUP_APP_ADJ;
14499                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14500                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14501                }
14502                app.adjType = "backup";
14503                app.cached = false;
14504            }
14505            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14506                procState = ActivityManager.PROCESS_STATE_BACKUP;
14507            }
14508        }
14509
14510        boolean mayBeTop = false;
14511
14512        for (int is = app.services.size()-1;
14513                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14514                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14515                        || procState > ActivityManager.PROCESS_STATE_TOP);
14516                is--) {
14517            ServiceRecord s = app.services.valueAt(is);
14518            if (s.startRequested) {
14519                app.hasStartedServices = true;
14520                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14521                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14522                }
14523                if (app.hasShownUi && app != mHomeProcess) {
14524                    // If this process has shown some UI, let it immediately
14525                    // go to the LRU list because it may be pretty heavy with
14526                    // UI stuff.  We'll tag it with a label just to help
14527                    // debug and understand what is going on.
14528                    if (adj > ProcessList.SERVICE_ADJ) {
14529                        app.adjType = "cch-started-ui-services";
14530                    }
14531                } else {
14532                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14533                        // This service has seen some activity within
14534                        // recent memory, so we will keep its process ahead
14535                        // of the background processes.
14536                        if (adj > ProcessList.SERVICE_ADJ) {
14537                            adj = ProcessList.SERVICE_ADJ;
14538                            app.adjType = "started-services";
14539                            app.cached = false;
14540                        }
14541                    }
14542                    // If we have let the service slide into the background
14543                    // state, still have some text describing what it is doing
14544                    // even though the service no longer has an impact.
14545                    if (adj > ProcessList.SERVICE_ADJ) {
14546                        app.adjType = "cch-started-services";
14547                    }
14548                }
14549                // Don't kill this process because it is doing work; it
14550                // has said it is doing work.
14551                app.keeping = true;
14552            }
14553            for (int conni = s.connections.size()-1;
14554                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14555                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14556                            || procState > ActivityManager.PROCESS_STATE_TOP);
14557                    conni--) {
14558                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14559                for (int i = 0;
14560                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14561                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14562                                || procState > ActivityManager.PROCESS_STATE_TOP);
14563                        i++) {
14564                    // XXX should compute this based on the max of
14565                    // all connected clients.
14566                    ConnectionRecord cr = clist.get(i);
14567                    if (cr.binding.client == app) {
14568                        // Binding to ourself is not interesting.
14569                        continue;
14570                    }
14571                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14572                        ProcessRecord client = cr.binding.client;
14573                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14574                                TOP_APP, doingAll, now);
14575                        int clientProcState = client.curProcState;
14576                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14577                            // If the other app is cached for any reason, for purposes here
14578                            // we are going to consider it empty.  The specific cached state
14579                            // doesn't propagate except under certain conditions.
14580                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14581                        }
14582                        String adjType = null;
14583                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14584                            // Not doing bind OOM management, so treat
14585                            // this guy more like a started service.
14586                            if (app.hasShownUi && app != mHomeProcess) {
14587                                // If this process has shown some UI, let it immediately
14588                                // go to the LRU list because it may be pretty heavy with
14589                                // UI stuff.  We'll tag it with a label just to help
14590                                // debug and understand what is going on.
14591                                if (adj > clientAdj) {
14592                                    adjType = "cch-bound-ui-services";
14593                                }
14594                                app.cached = false;
14595                                clientAdj = adj;
14596                                clientProcState = procState;
14597                            } else {
14598                                if (now >= (s.lastActivity
14599                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14600                                    // This service has not seen activity within
14601                                    // recent memory, so allow it to drop to the
14602                                    // LRU list if there is no other reason to keep
14603                                    // it around.  We'll also tag it with a label just
14604                                    // to help debug and undertand what is going on.
14605                                    if (adj > clientAdj) {
14606                                        adjType = "cch-bound-services";
14607                                    }
14608                                    clientAdj = adj;
14609                                }
14610                            }
14611                        }
14612                        if (adj > clientAdj) {
14613                            // If this process has recently shown UI, and
14614                            // the process that is binding to it is less
14615                            // important than being visible, then we don't
14616                            // care about the binding as much as we care
14617                            // about letting this process get into the LRU
14618                            // list to be killed and restarted if needed for
14619                            // memory.
14620                            if (app.hasShownUi && app != mHomeProcess
14621                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14622                                adjType = "cch-bound-ui-services";
14623                            } else {
14624                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14625                                        |Context.BIND_IMPORTANT)) != 0) {
14626                                    adj = clientAdj;
14627                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14628                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14629                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14630                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14631                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14632                                    adj = clientAdj;
14633                                } else {
14634                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14635                                        adj = ProcessList.VISIBLE_APP_ADJ;
14636                                    }
14637                                }
14638                                if (!client.cached) {
14639                                    app.cached = false;
14640                                }
14641                                if (client.keeping) {
14642                                    app.keeping = true;
14643                                }
14644                                adjType = "service";
14645                            }
14646                        }
14647                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14648                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14649                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14650                            }
14651                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14652                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14653                                    // Special handling of clients who are in the top state.
14654                                    // We *may* want to consider this process to be in the
14655                                    // top state as well, but only if there is not another
14656                                    // reason for it to be running.  Being on the top is a
14657                                    // special state, meaning you are specifically running
14658                                    // for the current top app.  If the process is already
14659                                    // running in the background for some other reason, it
14660                                    // is more important to continue considering it to be
14661                                    // in the background state.
14662                                    mayBeTop = true;
14663                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14664                                } else {
14665                                    // Special handling for above-top states (persistent
14666                                    // processes).  These should not bring the current process
14667                                    // into the top state, since they are not on top.  Instead
14668                                    // give them the best state after that.
14669                                    clientProcState =
14670                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14671                                }
14672                            }
14673                        } else {
14674                            if (clientProcState <
14675                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14676                                clientProcState =
14677                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14678                            }
14679                        }
14680                        if (procState > clientProcState) {
14681                            procState = clientProcState;
14682                        }
14683                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14684                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14685                            app.pendingUiClean = true;
14686                        }
14687                        if (adjType != null) {
14688                            app.adjType = adjType;
14689                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14690                                    .REASON_SERVICE_IN_USE;
14691                            app.adjSource = cr.binding.client;
14692                            app.adjSourceOom = clientAdj;
14693                            app.adjTarget = s.name;
14694                        }
14695                    }
14696                    final ActivityRecord a = cr.activity;
14697                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14698                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14699                                (a.visible || a.state == ActivityState.RESUMED
14700                                 || a.state == ActivityState.PAUSING)) {
14701                            adj = ProcessList.FOREGROUND_APP_ADJ;
14702                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14703                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14704                            }
14705                            app.cached = false;
14706                            app.adjType = "service";
14707                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14708                                    .REASON_SERVICE_IN_USE;
14709                            app.adjSource = a;
14710                            app.adjSourceOom = adj;
14711                            app.adjTarget = s.name;
14712                        }
14713                    }
14714                }
14715            }
14716        }
14717
14718        for (int provi = app.pubProviders.size()-1;
14719                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14720                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14721                        || procState > ActivityManager.PROCESS_STATE_TOP);
14722                provi--) {
14723            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14724            for (int i = cpr.connections.size()-1;
14725                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14726                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14727                            || procState > ActivityManager.PROCESS_STATE_TOP);
14728                    i--) {
14729                ContentProviderConnection conn = cpr.connections.get(i);
14730                ProcessRecord client = conn.client;
14731                if (client == app) {
14732                    // Being our own client is not interesting.
14733                    continue;
14734                }
14735                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14736                int clientProcState = client.curProcState;
14737                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14738                    // If the other app is cached for any reason, for purposes here
14739                    // we are going to consider it empty.
14740                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14741                }
14742                if (adj > clientAdj) {
14743                    if (app.hasShownUi && app != mHomeProcess
14744                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14745                        app.adjType = "cch-ui-provider";
14746                    } else {
14747                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14748                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14749                        app.adjType = "provider";
14750                    }
14751                    app.cached &= client.cached;
14752                    app.keeping |= client.keeping;
14753                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14754                            .REASON_PROVIDER_IN_USE;
14755                    app.adjSource = client;
14756                    app.adjSourceOom = clientAdj;
14757                    app.adjTarget = cpr.name;
14758                }
14759                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14760                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14761                        // Special handling of clients who are in the top state.
14762                        // We *may* want to consider this process to be in the
14763                        // top state as well, but only if there is not another
14764                        // reason for it to be running.  Being on the top is a
14765                        // special state, meaning you are specifically running
14766                        // for the current top app.  If the process is already
14767                        // running in the background for some other reason, it
14768                        // is more important to continue considering it to be
14769                        // in the background state.
14770                        mayBeTop = true;
14771                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14772                    } else {
14773                        // Special handling for above-top states (persistent
14774                        // processes).  These should not bring the current process
14775                        // into the top state, since they are not on top.  Instead
14776                        // give them the best state after that.
14777                        clientProcState =
14778                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14779                    }
14780                }
14781                if (procState > clientProcState) {
14782                    procState = clientProcState;
14783                }
14784                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14785                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14786                }
14787            }
14788            // If the provider has external (non-framework) process
14789            // dependencies, ensure that its adjustment is at least
14790            // FOREGROUND_APP_ADJ.
14791            if (cpr.hasExternalProcessHandles()) {
14792                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14793                    adj = ProcessList.FOREGROUND_APP_ADJ;
14794                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14795                    app.cached = false;
14796                    app.keeping = true;
14797                    app.adjType = "provider";
14798                    app.adjTarget = cpr.name;
14799                }
14800                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14801                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14802                }
14803            }
14804        }
14805
14806        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14807            // A client of one of our services or providers is in the top state.  We
14808            // *may* want to be in the top state, but not if we are already running in
14809            // the background for some other reason.  For the decision here, we are going
14810            // to pick out a few specific states that we want to remain in when a client
14811            // is top (states that tend to be longer-term) and otherwise allow it to go
14812            // to the top state.
14813            switch (procState) {
14814                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14815                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14816                case ActivityManager.PROCESS_STATE_SERVICE:
14817                    // These all are longer-term states, so pull them up to the top
14818                    // of the background states, but not all the way to the top state.
14819                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14820                    break;
14821                default:
14822                    // Otherwise, top is a better choice, so take it.
14823                    procState = ActivityManager.PROCESS_STATE_TOP;
14824                    break;
14825            }
14826        }
14827
14828        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14829            // This is a cached process, but with client activities.  Mark it so.
14830            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14831            app.adjType = "cch-client-act";
14832        }
14833
14834        if (adj == ProcessList.SERVICE_ADJ) {
14835            if (doingAll) {
14836                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14837                mNewNumServiceProcs++;
14838                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14839                if (!app.serviceb) {
14840                    // This service isn't far enough down on the LRU list to
14841                    // normally be a B service, but if we are low on RAM and it
14842                    // is large we want to force it down since we would prefer to
14843                    // keep launcher over it.
14844                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14845                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14846                        app.serviceHighRam = true;
14847                        app.serviceb = true;
14848                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14849                    } else {
14850                        mNewNumAServiceProcs++;
14851                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14852                    }
14853                } else {
14854                    app.serviceHighRam = false;
14855                }
14856            }
14857            if (app.serviceb) {
14858                adj = ProcessList.SERVICE_B_ADJ;
14859            }
14860        }
14861
14862        app.curRawAdj = adj;
14863
14864        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14865        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14866        if (adj > app.maxAdj) {
14867            adj = app.maxAdj;
14868            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14869                schedGroup = Process.THREAD_GROUP_DEFAULT;
14870            }
14871        }
14872        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14873            app.keeping = true;
14874        }
14875
14876        // Do final modification to adj.  Everything we do between here and applying
14877        // the final setAdj must be done in this function, because we will also use
14878        // it when computing the final cached adj later.  Note that we don't need to
14879        // worry about this for max adj above, since max adj will always be used to
14880        // keep it out of the cached vaues.
14881        adj = app.modifyRawOomAdj(adj);
14882
14883        app.curProcState = procState;
14884
14885        int importance = app.memImportance;
14886        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14887            app.curAdj = adj;
14888            app.curSchedGroup = schedGroup;
14889            if (!interesting) {
14890                // For this reporting, if there is not something explicitly
14891                // interesting in this process then we will push it to the
14892                // background importance.
14893                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14894            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14895                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14896            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14897                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14898            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14899                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14900            } else if (adj >= ProcessList.SERVICE_ADJ) {
14901                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14902            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14903                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14904            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14905                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14906            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14907                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14908            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14909                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14910            } else {
14911                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14912            }
14913        }
14914
14915        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14916        if (foregroundActivities != app.foregroundActivities) {
14917            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14918        }
14919        if (changes != 0) {
14920            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14921            app.memImportance = importance;
14922            app.foregroundActivities = foregroundActivities;
14923            int i = mPendingProcessChanges.size()-1;
14924            ProcessChangeItem item = null;
14925            while (i >= 0) {
14926                item = mPendingProcessChanges.get(i);
14927                if (item.pid == app.pid) {
14928                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14929                    break;
14930                }
14931                i--;
14932            }
14933            if (i < 0) {
14934                // No existing item in pending changes; need a new one.
14935                final int NA = mAvailProcessChanges.size();
14936                if (NA > 0) {
14937                    item = mAvailProcessChanges.remove(NA-1);
14938                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14939                } else {
14940                    item = new ProcessChangeItem();
14941                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14942                }
14943                item.changes = 0;
14944                item.pid = app.pid;
14945                item.uid = app.info.uid;
14946                if (mPendingProcessChanges.size() == 0) {
14947                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14948                            "*** Enqueueing dispatch processes changed!");
14949                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14950                }
14951                mPendingProcessChanges.add(item);
14952            }
14953            item.changes |= changes;
14954            item.importance = importance;
14955            item.foregroundActivities = foregroundActivities;
14956            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14957                    + Integer.toHexString(System.identityHashCode(item))
14958                    + " " + app.toShortString() + ": changes=" + item.changes
14959                    + " importance=" + item.importance
14960                    + " foreground=" + item.foregroundActivities
14961                    + " type=" + app.adjType + " source=" + app.adjSource
14962                    + " target=" + app.adjTarget);
14963        }
14964
14965        return app.curRawAdj;
14966    }
14967
14968    /**
14969     * Schedule PSS collection of a process.
14970     */
14971    void requestPssLocked(ProcessRecord proc, int procState) {
14972        if (mPendingPssProcesses.contains(proc)) {
14973            return;
14974        }
14975        if (mPendingPssProcesses.size() == 0) {
14976            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14977        }
14978        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14979        proc.pssProcState = procState;
14980        mPendingPssProcesses.add(proc);
14981    }
14982
14983    /**
14984     * Schedule PSS collection of all processes.
14985     */
14986    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14987        if (!always) {
14988            if (now < (mLastFullPssTime +
14989                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14990                return;
14991            }
14992        }
14993        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14994        mLastFullPssTime = now;
14995        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14996        mPendingPssProcesses.clear();
14997        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14998            ProcessRecord app = mLruProcesses.get(i);
14999            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15000                app.pssProcState = app.setProcState;
15001                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15002                        mSleeping, now);
15003                mPendingPssProcesses.add(app);
15004            }
15005        }
15006        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15007    }
15008
15009    /**
15010     * Ask a given process to GC right now.
15011     */
15012    final void performAppGcLocked(ProcessRecord app) {
15013        try {
15014            app.lastRequestedGc = SystemClock.uptimeMillis();
15015            if (app.thread != null) {
15016                if (app.reportLowMemory) {
15017                    app.reportLowMemory = false;
15018                    app.thread.scheduleLowMemory();
15019                } else {
15020                    app.thread.processInBackground();
15021                }
15022            }
15023        } catch (Exception e) {
15024            // whatever.
15025        }
15026    }
15027
15028    /**
15029     * Returns true if things are idle enough to perform GCs.
15030     */
15031    private final boolean canGcNowLocked() {
15032        boolean processingBroadcasts = false;
15033        for (BroadcastQueue q : mBroadcastQueues) {
15034            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15035                processingBroadcasts = true;
15036            }
15037        }
15038        return !processingBroadcasts
15039                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15040    }
15041
15042    /**
15043     * Perform GCs on all processes that are waiting for it, but only
15044     * if things are idle.
15045     */
15046    final void performAppGcsLocked() {
15047        final int N = mProcessesToGc.size();
15048        if (N <= 0) {
15049            return;
15050        }
15051        if (canGcNowLocked()) {
15052            while (mProcessesToGc.size() > 0) {
15053                ProcessRecord proc = mProcessesToGc.remove(0);
15054                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15055                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15056                            <= SystemClock.uptimeMillis()) {
15057                        // To avoid spamming the system, we will GC processes one
15058                        // at a time, waiting a few seconds between each.
15059                        performAppGcLocked(proc);
15060                        scheduleAppGcsLocked();
15061                        return;
15062                    } else {
15063                        // It hasn't been long enough since we last GCed this
15064                        // process...  put it in the list to wait for its time.
15065                        addProcessToGcListLocked(proc);
15066                        break;
15067                    }
15068                }
15069            }
15070
15071            scheduleAppGcsLocked();
15072        }
15073    }
15074
15075    /**
15076     * If all looks good, perform GCs on all processes waiting for them.
15077     */
15078    final void performAppGcsIfAppropriateLocked() {
15079        if (canGcNowLocked()) {
15080            performAppGcsLocked();
15081            return;
15082        }
15083        // Still not idle, wait some more.
15084        scheduleAppGcsLocked();
15085    }
15086
15087    /**
15088     * Schedule the execution of all pending app GCs.
15089     */
15090    final void scheduleAppGcsLocked() {
15091        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15092
15093        if (mProcessesToGc.size() > 0) {
15094            // Schedule a GC for the time to the next process.
15095            ProcessRecord proc = mProcessesToGc.get(0);
15096            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15097
15098            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15099            long now = SystemClock.uptimeMillis();
15100            if (when < (now+GC_TIMEOUT)) {
15101                when = now + GC_TIMEOUT;
15102            }
15103            mHandler.sendMessageAtTime(msg, when);
15104        }
15105    }
15106
15107    /**
15108     * Add a process to the array of processes waiting to be GCed.  Keeps the
15109     * list in sorted order by the last GC time.  The process can't already be
15110     * on the list.
15111     */
15112    final void addProcessToGcListLocked(ProcessRecord proc) {
15113        boolean added = false;
15114        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15115            if (mProcessesToGc.get(i).lastRequestedGc <
15116                    proc.lastRequestedGc) {
15117                added = true;
15118                mProcessesToGc.add(i+1, proc);
15119                break;
15120            }
15121        }
15122        if (!added) {
15123            mProcessesToGc.add(0, proc);
15124        }
15125    }
15126
15127    /**
15128     * Set up to ask a process to GC itself.  This will either do it
15129     * immediately, or put it on the list of processes to gc the next
15130     * time things are idle.
15131     */
15132    final void scheduleAppGcLocked(ProcessRecord app) {
15133        long now = SystemClock.uptimeMillis();
15134        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15135            return;
15136        }
15137        if (!mProcessesToGc.contains(app)) {
15138            addProcessToGcListLocked(app);
15139            scheduleAppGcsLocked();
15140        }
15141    }
15142
15143    final void checkExcessivePowerUsageLocked(boolean doKills) {
15144        updateCpuStatsNow();
15145
15146        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15147        boolean doWakeKills = doKills;
15148        boolean doCpuKills = doKills;
15149        if (mLastPowerCheckRealtime == 0) {
15150            doWakeKills = false;
15151        }
15152        if (mLastPowerCheckUptime == 0) {
15153            doCpuKills = false;
15154        }
15155        if (stats.isScreenOn()) {
15156            doWakeKills = false;
15157        }
15158        final long curRealtime = SystemClock.elapsedRealtime();
15159        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15160        final long curUptime = SystemClock.uptimeMillis();
15161        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15162        mLastPowerCheckRealtime = curRealtime;
15163        mLastPowerCheckUptime = curUptime;
15164        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15165            doWakeKills = false;
15166        }
15167        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15168            doCpuKills = false;
15169        }
15170        int i = mLruProcesses.size();
15171        while (i > 0) {
15172            i--;
15173            ProcessRecord app = mLruProcesses.get(i);
15174            if (!app.keeping) {
15175                long wtime;
15176                synchronized (stats) {
15177                    wtime = stats.getProcessWakeTime(app.info.uid,
15178                            app.pid, curRealtime);
15179                }
15180                long wtimeUsed = wtime - app.lastWakeTime;
15181                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15182                if (DEBUG_POWER) {
15183                    StringBuilder sb = new StringBuilder(128);
15184                    sb.append("Wake for ");
15185                    app.toShortString(sb);
15186                    sb.append(": over ");
15187                    TimeUtils.formatDuration(realtimeSince, sb);
15188                    sb.append(" used ");
15189                    TimeUtils.formatDuration(wtimeUsed, sb);
15190                    sb.append(" (");
15191                    sb.append((wtimeUsed*100)/realtimeSince);
15192                    sb.append("%)");
15193                    Slog.i(TAG, sb.toString());
15194                    sb.setLength(0);
15195                    sb.append("CPU for ");
15196                    app.toShortString(sb);
15197                    sb.append(": over ");
15198                    TimeUtils.formatDuration(uptimeSince, sb);
15199                    sb.append(" used ");
15200                    TimeUtils.formatDuration(cputimeUsed, sb);
15201                    sb.append(" (");
15202                    sb.append((cputimeUsed*100)/uptimeSince);
15203                    sb.append("%)");
15204                    Slog.i(TAG, sb.toString());
15205                }
15206                // If a process has held a wake lock for more
15207                // than 50% of the time during this period,
15208                // that sounds bad.  Kill!
15209                if (doWakeKills && realtimeSince > 0
15210                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15211                    synchronized (stats) {
15212                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15213                                realtimeSince, wtimeUsed);
15214                    }
15215                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15216                            + " during " + realtimeSince);
15217                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15218                } else if (doCpuKills && uptimeSince > 0
15219                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15220                    synchronized (stats) {
15221                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15222                                uptimeSince, cputimeUsed);
15223                    }
15224                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15225                            + " during " + uptimeSince);
15226                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15227                } else {
15228                    app.lastWakeTime = wtime;
15229                    app.lastCpuTime = app.curCpuTime;
15230                }
15231            }
15232        }
15233    }
15234
15235    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15236            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15237        boolean success = true;
15238
15239        if (app.curRawAdj != app.setRawAdj) {
15240            if (wasKeeping && !app.keeping) {
15241                // This app is no longer something we want to keep.  Note
15242                // its current wake lock time to later know to kill it if
15243                // it is not behaving well.
15244                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15245                synchronized (stats) {
15246                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15247                            app.pid, SystemClock.elapsedRealtime());
15248                }
15249                app.lastCpuTime = app.curCpuTime;
15250            }
15251
15252            app.setRawAdj = app.curRawAdj;
15253        }
15254
15255        if (app.curAdj != app.setAdj) {
15256            ProcessList.setOomAdj(app.pid, app.curAdj);
15257            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15258                TAG, "Set " + app.pid + " " + app.processName +
15259                " adj " + app.curAdj + ": " + app.adjType);
15260            app.setAdj = app.curAdj;
15261        }
15262
15263        if (app.setSchedGroup != app.curSchedGroup) {
15264            app.setSchedGroup = app.curSchedGroup;
15265            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15266                    "Setting process group of " + app.processName
15267                    + " to " + app.curSchedGroup);
15268            if (app.waitingToKill != null &&
15269                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15270                killUnneededProcessLocked(app, app.waitingToKill);
15271                success = false;
15272            } else {
15273                if (true) {
15274                    long oldId = Binder.clearCallingIdentity();
15275                    try {
15276                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15277                    } catch (Exception e) {
15278                        Slog.w(TAG, "Failed setting process group of " + app.pid
15279                                + " to " + app.curSchedGroup);
15280                        e.printStackTrace();
15281                    } finally {
15282                        Binder.restoreCallingIdentity(oldId);
15283                    }
15284                } else {
15285                    if (app.thread != null) {
15286                        try {
15287                            app.thread.setSchedulingGroup(app.curSchedGroup);
15288                        } catch (RemoteException e) {
15289                        }
15290                    }
15291                }
15292                Process.setSwappiness(app.pid,
15293                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15294            }
15295        }
15296        if (app.repProcState != app.curProcState) {
15297            app.repProcState = app.curProcState;
15298            if (!reportingProcessState && app.thread != null) {
15299                try {
15300                    if (false) {
15301                        //RuntimeException h = new RuntimeException("here");
15302                        Slog.i(TAG, "Sending new process state " + app.repProcState
15303                                + " to " + app /*, h*/);
15304                    }
15305                    app.thread.setProcessState(app.repProcState);
15306                } catch (RemoteException e) {
15307                }
15308            }
15309        }
15310        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15311                app.setProcState)) {
15312            app.lastStateTime = now;
15313            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15314                    mSleeping, now);
15315            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15316                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15317                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15318                    + (app.nextPssTime-now) + ": " + app);
15319        } else {
15320            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15321                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15322                requestPssLocked(app, app.setProcState);
15323                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15324                        mSleeping, now);
15325            } else if (false && DEBUG_PSS) {
15326                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15327            }
15328        }
15329        if (app.setProcState != app.curProcState) {
15330            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15331                    "Proc state change of " + app.processName
15332                    + " to " + app.curProcState);
15333            app.setProcState = app.curProcState;
15334            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15335                app.notCachedSinceIdle = false;
15336            }
15337            if (!doingAll) {
15338                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15339            } else {
15340                app.procStateChanged = true;
15341            }
15342        }
15343        return success;
15344    }
15345
15346    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15347        if (proc.thread != null && proc.baseProcessTracker != null) {
15348            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15349        }
15350    }
15351
15352    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15353            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15354        if (app.thread == null) {
15355            return false;
15356        }
15357
15358        final boolean wasKeeping = app.keeping;
15359
15360        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15361
15362        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15363                reportingProcessState, now);
15364    }
15365
15366    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15367            boolean oomAdj) {
15368        if (isForeground != proc.foregroundServices) {
15369            proc.foregroundServices = isForeground;
15370            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15371                    proc.info.uid);
15372            if (isForeground) {
15373                if (curProcs == null) {
15374                    curProcs = new ArrayList<ProcessRecord>();
15375                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15376                }
15377                if (!curProcs.contains(proc)) {
15378                    curProcs.add(proc);
15379                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15380                            proc.info.packageName, proc.info.uid);
15381                }
15382            } else {
15383                if (curProcs != null) {
15384                    if (curProcs.remove(proc)) {
15385                        mBatteryStatsService.noteEvent(
15386                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15387                                proc.info.packageName, proc.info.uid);
15388                        if (curProcs.size() <= 0) {
15389                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15390                        }
15391                    }
15392                }
15393            }
15394            if (oomAdj) {
15395                updateOomAdjLocked();
15396            }
15397        }
15398    }
15399
15400    private final ActivityRecord resumedAppLocked() {
15401        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15402        String pkg;
15403        int uid;
15404        if (act != null) {
15405            pkg = act.packageName;
15406            uid = act.info.applicationInfo.uid;
15407        } else {
15408            pkg = null;
15409            uid = -1;
15410        }
15411        // Has the UID or resumed package name changed?
15412        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15413                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15414            if (mCurResumedPackage != null) {
15415                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15416                        mCurResumedPackage, mCurResumedUid);
15417            }
15418            mCurResumedPackage = pkg;
15419            mCurResumedUid = uid;
15420            if (mCurResumedPackage != null) {
15421                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15422                        mCurResumedPackage, mCurResumedUid);
15423            }
15424        }
15425        return act;
15426    }
15427
15428    final boolean updateOomAdjLocked(ProcessRecord app) {
15429        return updateOomAdjLocked(app, false);
15430    }
15431
15432    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15433        final ActivityRecord TOP_ACT = resumedAppLocked();
15434        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15435        final boolean wasCached = app.cached;
15436
15437        mAdjSeq++;
15438
15439        // This is the desired cached adjusment we want to tell it to use.
15440        // If our app is currently cached, we know it, and that is it.  Otherwise,
15441        // we don't know it yet, and it needs to now be cached we will then
15442        // need to do a complete oom adj.
15443        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15444                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15445        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15446                SystemClock.uptimeMillis());
15447        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15448            // Changed to/from cached state, so apps after it in the LRU
15449            // list may also be changed.
15450            updateOomAdjLocked();
15451        }
15452        return success;
15453    }
15454
15455    final void updateOomAdjLocked() {
15456        final ActivityRecord TOP_ACT = resumedAppLocked();
15457        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15458        final long now = SystemClock.uptimeMillis();
15459        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15460        final int N = mLruProcesses.size();
15461
15462        if (false) {
15463            RuntimeException e = new RuntimeException();
15464            e.fillInStackTrace();
15465            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15466        }
15467
15468        mAdjSeq++;
15469        mNewNumServiceProcs = 0;
15470        mNewNumAServiceProcs = 0;
15471
15472        final int emptyProcessLimit;
15473        final int cachedProcessLimit;
15474        if (mProcessLimit <= 0) {
15475            emptyProcessLimit = cachedProcessLimit = 0;
15476        } else if (mProcessLimit == 1) {
15477            emptyProcessLimit = 1;
15478            cachedProcessLimit = 0;
15479        } else {
15480            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15481            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15482        }
15483
15484        // Let's determine how many processes we have running vs.
15485        // how many slots we have for background processes; we may want
15486        // to put multiple processes in a slot of there are enough of
15487        // them.
15488        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15489                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15490        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15491        if (numEmptyProcs > cachedProcessLimit) {
15492            // If there are more empty processes than our limit on cached
15493            // processes, then use the cached process limit for the factor.
15494            // This ensures that the really old empty processes get pushed
15495            // down to the bottom, so if we are running low on memory we will
15496            // have a better chance at keeping around more cached processes
15497            // instead of a gazillion empty processes.
15498            numEmptyProcs = cachedProcessLimit;
15499        }
15500        int emptyFactor = numEmptyProcs/numSlots;
15501        if (emptyFactor < 1) emptyFactor = 1;
15502        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15503        if (cachedFactor < 1) cachedFactor = 1;
15504        int stepCached = 0;
15505        int stepEmpty = 0;
15506        int numCached = 0;
15507        int numEmpty = 0;
15508        int numTrimming = 0;
15509
15510        mNumNonCachedProcs = 0;
15511        mNumCachedHiddenProcs = 0;
15512
15513        // First update the OOM adjustment for each of the
15514        // application processes based on their current state.
15515        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15516        int nextCachedAdj = curCachedAdj+1;
15517        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15518        int nextEmptyAdj = curEmptyAdj+2;
15519        for (int i=N-1; i>=0; i--) {
15520            ProcessRecord app = mLruProcesses.get(i);
15521            if (!app.killedByAm && app.thread != null) {
15522                app.procStateChanged = false;
15523                final boolean wasKeeping = app.keeping;
15524                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15525
15526                // If we haven't yet assigned the final cached adj
15527                // to the process, do that now.
15528                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15529                    switch (app.curProcState) {
15530                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15531                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15532                            // This process is a cached process holding activities...
15533                            // assign it the next cached value for that type, and then
15534                            // step that cached level.
15535                            app.curRawAdj = curCachedAdj;
15536                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15537                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15538                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15539                                    + ")");
15540                            if (curCachedAdj != nextCachedAdj) {
15541                                stepCached++;
15542                                if (stepCached >= cachedFactor) {
15543                                    stepCached = 0;
15544                                    curCachedAdj = nextCachedAdj;
15545                                    nextCachedAdj += 2;
15546                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15547                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15548                                    }
15549                                }
15550                            }
15551                            break;
15552                        default:
15553                            // For everything else, assign next empty cached process
15554                            // level and bump that up.  Note that this means that
15555                            // long-running services that have dropped down to the
15556                            // cached level will be treated as empty (since their process
15557                            // state is still as a service), which is what we want.
15558                            app.curRawAdj = curEmptyAdj;
15559                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15560                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15561                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15562                                    + ")");
15563                            if (curEmptyAdj != nextEmptyAdj) {
15564                                stepEmpty++;
15565                                if (stepEmpty >= emptyFactor) {
15566                                    stepEmpty = 0;
15567                                    curEmptyAdj = nextEmptyAdj;
15568                                    nextEmptyAdj += 2;
15569                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15570                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15571                                    }
15572                                }
15573                            }
15574                            break;
15575                    }
15576                }
15577
15578                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15579
15580                // Count the number of process types.
15581                switch (app.curProcState) {
15582                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15583                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15584                        mNumCachedHiddenProcs++;
15585                        numCached++;
15586                        if (numCached > cachedProcessLimit) {
15587                            killUnneededProcessLocked(app, "cached #" + numCached);
15588                        }
15589                        break;
15590                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15591                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15592                                && app.lastActivityTime < oldTime) {
15593                            killUnneededProcessLocked(app, "empty for "
15594                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15595                                    / 1000) + "s");
15596                        } else {
15597                            numEmpty++;
15598                            if (numEmpty > emptyProcessLimit) {
15599                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15600                            }
15601                        }
15602                        break;
15603                    default:
15604                        mNumNonCachedProcs++;
15605                        break;
15606                }
15607
15608                if (app.isolated && app.services.size() <= 0) {
15609                    // If this is an isolated process, and there are no
15610                    // services running in it, then the process is no longer
15611                    // needed.  We agressively kill these because we can by
15612                    // definition not re-use the same process again, and it is
15613                    // good to avoid having whatever code was running in them
15614                    // left sitting around after no longer needed.
15615                    killUnneededProcessLocked(app, "isolated not needed");
15616                }
15617
15618                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15619                        && !app.killedByAm) {
15620                    numTrimming++;
15621                }
15622            }
15623        }
15624
15625        mNumServiceProcs = mNewNumServiceProcs;
15626
15627        // Now determine the memory trimming level of background processes.
15628        // Unfortunately we need to start at the back of the list to do this
15629        // properly.  We only do this if the number of background apps we
15630        // are managing to keep around is less than half the maximum we desire;
15631        // if we are keeping a good number around, we'll let them use whatever
15632        // memory they want.
15633        final int numCachedAndEmpty = numCached + numEmpty;
15634        int memFactor;
15635        if (numCached <= ProcessList.TRIM_CACHED_APPS
15636                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15637            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15638                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15639            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15640                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15641            } else {
15642                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15643            }
15644        } else {
15645            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15646        }
15647        // We always allow the memory level to go up (better).  We only allow it to go
15648        // down if we are in a state where that is allowed, *and* the total number of processes
15649        // has gone down since last time.
15650        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15651                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15652                + " last=" + mLastNumProcesses);
15653        if (memFactor > mLastMemoryLevel) {
15654            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15655                memFactor = mLastMemoryLevel;
15656                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15657            }
15658        }
15659        mLastMemoryLevel = memFactor;
15660        mLastNumProcesses = mLruProcesses.size();
15661        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15662        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15663        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15664            if (mLowRamStartTime == 0) {
15665                mLowRamStartTime = now;
15666            }
15667            int step = 0;
15668            int fgTrimLevel;
15669            switch (memFactor) {
15670                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15671                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15672                    break;
15673                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15674                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15675                    break;
15676                default:
15677                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15678                    break;
15679            }
15680            int factor = numTrimming/3;
15681            int minFactor = 2;
15682            if (mHomeProcess != null) minFactor++;
15683            if (mPreviousProcess != null) minFactor++;
15684            if (factor < minFactor) factor = minFactor;
15685            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15686            for (int i=N-1; i>=0; i--) {
15687                ProcessRecord app = mLruProcesses.get(i);
15688                if (allChanged || app.procStateChanged) {
15689                    setProcessTrackerState(app, trackerMemFactor, now);
15690                    app.procStateChanged = false;
15691                }
15692                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15693                        && !app.killedByAm) {
15694                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15695                        try {
15696                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15697                                    "Trimming memory of " + app.processName
15698                                    + " to " + curLevel);
15699                            app.thread.scheduleTrimMemory(curLevel);
15700                        } catch (RemoteException e) {
15701                        }
15702                        if (false) {
15703                            // For now we won't do this; our memory trimming seems
15704                            // to be good enough at this point that destroying
15705                            // activities causes more harm than good.
15706                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15707                                    && app != mHomeProcess && app != mPreviousProcess) {
15708                                // Need to do this on its own message because the stack may not
15709                                // be in a consistent state at this point.
15710                                // For these apps we will also finish their activities
15711                                // to help them free memory.
15712                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15713                            }
15714                        }
15715                    }
15716                    app.trimMemoryLevel = curLevel;
15717                    step++;
15718                    if (step >= factor) {
15719                        step = 0;
15720                        switch (curLevel) {
15721                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15722                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15723                                break;
15724                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15725                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15726                                break;
15727                        }
15728                    }
15729                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15730                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15731                            && app.thread != null) {
15732                        try {
15733                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15734                                    "Trimming memory of heavy-weight " + app.processName
15735                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15736                            app.thread.scheduleTrimMemory(
15737                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15738                        } catch (RemoteException e) {
15739                        }
15740                    }
15741                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15742                } else {
15743                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15744                            || app.systemNoUi) && app.pendingUiClean) {
15745                        // If this application is now in the background and it
15746                        // had done UI, then give it the special trim level to
15747                        // have it free UI resources.
15748                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15749                        if (app.trimMemoryLevel < level && app.thread != null) {
15750                            try {
15751                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15752                                        "Trimming memory of bg-ui " + app.processName
15753                                        + " to " + level);
15754                                app.thread.scheduleTrimMemory(level);
15755                            } catch (RemoteException e) {
15756                            }
15757                        }
15758                        app.pendingUiClean = false;
15759                    }
15760                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15761                        try {
15762                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15763                                    "Trimming memory of fg " + app.processName
15764                                    + " to " + fgTrimLevel);
15765                            app.thread.scheduleTrimMemory(fgTrimLevel);
15766                        } catch (RemoteException e) {
15767                        }
15768                    }
15769                    app.trimMemoryLevel = fgTrimLevel;
15770                }
15771            }
15772        } else {
15773            if (mLowRamStartTime != 0) {
15774                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15775                mLowRamStartTime = 0;
15776            }
15777            for (int i=N-1; i>=0; i--) {
15778                ProcessRecord app = mLruProcesses.get(i);
15779                if (allChanged || app.procStateChanged) {
15780                    setProcessTrackerState(app, trackerMemFactor, now);
15781                    app.procStateChanged = false;
15782                }
15783                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15784                        || app.systemNoUi) && app.pendingUiClean) {
15785                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15786                            && app.thread != null) {
15787                        try {
15788                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15789                                    "Trimming memory of ui hidden " + app.processName
15790                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15791                            app.thread.scheduleTrimMemory(
15792                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15793                        } catch (RemoteException e) {
15794                        }
15795                    }
15796                    app.pendingUiClean = false;
15797                }
15798                app.trimMemoryLevel = 0;
15799            }
15800        }
15801
15802        if (mAlwaysFinishActivities) {
15803            // Need to do this on its own message because the stack may not
15804            // be in a consistent state at this point.
15805            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15806        }
15807
15808        if (allChanged) {
15809            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15810        }
15811
15812        if (mProcessStats.shouldWriteNowLocked(now)) {
15813            mHandler.post(new Runnable() {
15814                @Override public void run() {
15815                    synchronized (ActivityManagerService.this) {
15816                        mProcessStats.writeStateAsyncLocked();
15817                    }
15818                }
15819            });
15820        }
15821
15822        if (DEBUG_OOM_ADJ) {
15823            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15824        }
15825    }
15826
15827    final void trimApplications() {
15828        synchronized (this) {
15829            int i;
15830
15831            // First remove any unused application processes whose package
15832            // has been removed.
15833            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15834                final ProcessRecord app = mRemovedProcesses.get(i);
15835                if (app.activities.size() == 0
15836                        && app.curReceiver == null && app.services.size() == 0) {
15837                    Slog.i(
15838                        TAG, "Exiting empty application process "
15839                        + app.processName + " ("
15840                        + (app.thread != null ? app.thread.asBinder() : null)
15841                        + ")\n");
15842                    if (app.pid > 0 && app.pid != MY_PID) {
15843                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15844                                app.processName, app.setAdj, "empty");
15845                        app.killedByAm = true;
15846                        Process.killProcessQuiet(app.pid);
15847                    } else {
15848                        try {
15849                            app.thread.scheduleExit();
15850                        } catch (Exception e) {
15851                            // Ignore exceptions.
15852                        }
15853                    }
15854                    cleanUpApplicationRecordLocked(app, false, true, -1);
15855                    mRemovedProcesses.remove(i);
15856
15857                    if (app.persistent) {
15858                        if (app.persistent) {
15859                            addAppLocked(app.info, false);
15860                        }
15861                    }
15862                }
15863            }
15864
15865            // Now update the oom adj for all processes.
15866            updateOomAdjLocked();
15867        }
15868    }
15869
15870    /** This method sends the specified signal to each of the persistent apps */
15871    public void signalPersistentProcesses(int sig) throws RemoteException {
15872        if (sig != Process.SIGNAL_USR1) {
15873            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15874        }
15875
15876        synchronized (this) {
15877            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15878                    != PackageManager.PERMISSION_GRANTED) {
15879                throw new SecurityException("Requires permission "
15880                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15881            }
15882
15883            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15884                ProcessRecord r = mLruProcesses.get(i);
15885                if (r.thread != null && r.persistent) {
15886                    Process.sendSignal(r.pid, sig);
15887                }
15888            }
15889        }
15890    }
15891
15892    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15893        if (proc == null || proc == mProfileProc) {
15894            proc = mProfileProc;
15895            path = mProfileFile;
15896            profileType = mProfileType;
15897            clearProfilerLocked();
15898        }
15899        if (proc == null) {
15900            return;
15901        }
15902        try {
15903            proc.thread.profilerControl(false, path, null, profileType);
15904        } catch (RemoteException e) {
15905            throw new IllegalStateException("Process disappeared");
15906        }
15907    }
15908
15909    private void clearProfilerLocked() {
15910        if (mProfileFd != null) {
15911            try {
15912                mProfileFd.close();
15913            } catch (IOException e) {
15914            }
15915        }
15916        mProfileApp = null;
15917        mProfileProc = null;
15918        mProfileFile = null;
15919        mProfileType = 0;
15920        mAutoStopProfiler = false;
15921    }
15922
15923    public boolean profileControl(String process, int userId, boolean start,
15924            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15925
15926        try {
15927            synchronized (this) {
15928                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15929                // its own permission.
15930                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15931                        != PackageManager.PERMISSION_GRANTED) {
15932                    throw new SecurityException("Requires permission "
15933                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15934                }
15935
15936                if (start && fd == null) {
15937                    throw new IllegalArgumentException("null fd");
15938                }
15939
15940                ProcessRecord proc = null;
15941                if (process != null) {
15942                    proc = findProcessLocked(process, userId, "profileControl");
15943                }
15944
15945                if (start && (proc == null || proc.thread == null)) {
15946                    throw new IllegalArgumentException("Unknown process: " + process);
15947                }
15948
15949                if (start) {
15950                    stopProfilerLocked(null, null, 0);
15951                    setProfileApp(proc.info, proc.processName, path, fd, false);
15952                    mProfileProc = proc;
15953                    mProfileType = profileType;
15954                    try {
15955                        fd = fd.dup();
15956                    } catch (IOException e) {
15957                        fd = null;
15958                    }
15959                    proc.thread.profilerControl(start, path, fd, profileType);
15960                    fd = null;
15961                    mProfileFd = null;
15962                } else {
15963                    stopProfilerLocked(proc, path, profileType);
15964                    if (fd != null) {
15965                        try {
15966                            fd.close();
15967                        } catch (IOException e) {
15968                        }
15969                    }
15970                }
15971
15972                return true;
15973            }
15974        } catch (RemoteException e) {
15975            throw new IllegalStateException("Process disappeared");
15976        } finally {
15977            if (fd != null) {
15978                try {
15979                    fd.close();
15980                } catch (IOException e) {
15981                }
15982            }
15983        }
15984    }
15985
15986    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15987        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15988                userId, true, true, callName, null);
15989        ProcessRecord proc = null;
15990        try {
15991            int pid = Integer.parseInt(process);
15992            synchronized (mPidsSelfLocked) {
15993                proc = mPidsSelfLocked.get(pid);
15994            }
15995        } catch (NumberFormatException e) {
15996        }
15997
15998        if (proc == null) {
15999            ArrayMap<String, SparseArray<ProcessRecord>> all
16000                    = mProcessNames.getMap();
16001            SparseArray<ProcessRecord> procs = all.get(process);
16002            if (procs != null && procs.size() > 0) {
16003                proc = procs.valueAt(0);
16004                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16005                    for (int i=1; i<procs.size(); i++) {
16006                        ProcessRecord thisProc = procs.valueAt(i);
16007                        if (thisProc.userId == userId) {
16008                            proc = thisProc;
16009                            break;
16010                        }
16011                    }
16012                }
16013            }
16014        }
16015
16016        return proc;
16017    }
16018
16019    public boolean dumpHeap(String process, int userId, boolean managed,
16020            String path, ParcelFileDescriptor fd) throws RemoteException {
16021
16022        try {
16023            synchronized (this) {
16024                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16025                // its own permission (same as profileControl).
16026                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16027                        != PackageManager.PERMISSION_GRANTED) {
16028                    throw new SecurityException("Requires permission "
16029                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16030                }
16031
16032                if (fd == null) {
16033                    throw new IllegalArgumentException("null fd");
16034                }
16035
16036                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16037                if (proc == null || proc.thread == null) {
16038                    throw new IllegalArgumentException("Unknown process: " + process);
16039                }
16040
16041                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16042                if (!isDebuggable) {
16043                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16044                        throw new SecurityException("Process not debuggable: " + proc);
16045                    }
16046                }
16047
16048                proc.thread.dumpHeap(managed, path, fd);
16049                fd = null;
16050                return true;
16051            }
16052        } catch (RemoteException e) {
16053            throw new IllegalStateException("Process disappeared");
16054        } finally {
16055            if (fd != null) {
16056                try {
16057                    fd.close();
16058                } catch (IOException e) {
16059                }
16060            }
16061        }
16062    }
16063
16064    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16065    public void monitor() {
16066        synchronized (this) { }
16067    }
16068
16069    void onCoreSettingsChange(Bundle settings) {
16070        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16071            ProcessRecord processRecord = mLruProcesses.get(i);
16072            try {
16073                if (processRecord.thread != null) {
16074                    processRecord.thread.setCoreSettings(settings);
16075                }
16076            } catch (RemoteException re) {
16077                /* ignore */
16078            }
16079        }
16080    }
16081
16082    // Multi-user methods
16083
16084    /**
16085     * Start user, if its not already running, but don't bring it to foreground.
16086     */
16087    @Override
16088    public boolean startUserInBackground(final int userId) {
16089        return startUser(userId, /* foreground */ false);
16090    }
16091
16092    @Override
16093    public boolean switchUser(final int userId) {
16094        return startUser(userId, /* foregound */ true);
16095    }
16096
16097    private boolean startUser(final int userId, boolean foreground) {
16098        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16099                != PackageManager.PERMISSION_GRANTED) {
16100            String msg = "Permission Denial: switchUser() from pid="
16101                    + Binder.getCallingPid()
16102                    + ", uid=" + Binder.getCallingUid()
16103                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16104            Slog.w(TAG, msg);
16105            throw new SecurityException(msg);
16106        }
16107
16108        final long ident = Binder.clearCallingIdentity();
16109        try {
16110            synchronized (this) {
16111                final int oldUserId = mCurrentUserId;
16112                if (oldUserId == userId) {
16113                    return true;
16114                }
16115
16116                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16117                if (userInfo == null) {
16118                    Slog.w(TAG, "No user info for user #" + userId);
16119                    return false;
16120                }
16121
16122                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16123                        R.anim.screen_user_enter);
16124
16125                boolean needStart = false;
16126
16127                // If the user we are switching to is not currently started, then
16128                // we need to start it now.
16129                if (mStartedUsers.get(userId) == null) {
16130                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16131                    updateStartedUserArrayLocked();
16132                    needStart = true;
16133                }
16134
16135                final Integer userIdInt = Integer.valueOf(userId);
16136                mUserLru.remove(userIdInt);
16137                mUserLru.add(userIdInt);
16138
16139                if (foreground) {
16140                    mCurrentUserId = userId;
16141                    mWindowManager.setCurrentUser(userId);
16142                } else {
16143                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16144                    mUserLru.remove(currentUserIdInt);
16145                    mUserLru.add(currentUserIdInt);
16146                }
16147
16148                // Once the internal notion of the active user has switched, we lock the device
16149                // with the option to show the user switcher on the keyguard.
16150                mWindowManager.lockNow(null);
16151
16152                final UserStartedState uss = mStartedUsers.get(userId);
16153
16154                // Make sure user is in the started state.  If it is currently
16155                // stopping, we need to knock that off.
16156                if (uss.mState == UserStartedState.STATE_STOPPING) {
16157                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16158                    // so we can just fairly silently bring the user back from
16159                    // the almost-dead.
16160                    uss.mState = UserStartedState.STATE_RUNNING;
16161                    updateStartedUserArrayLocked();
16162                    needStart = true;
16163                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16164                    // This means ACTION_SHUTDOWN has been sent, so we will
16165                    // need to treat this as a new boot of the user.
16166                    uss.mState = UserStartedState.STATE_BOOTING;
16167                    updateStartedUserArrayLocked();
16168                    needStart = true;
16169                }
16170
16171                if (foreground) {
16172                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16173                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16174                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16175                            oldUserId, userId, uss));
16176                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16177                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16178                }
16179
16180                if (needStart) {
16181                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16182                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16183                            | Intent.FLAG_RECEIVER_FOREGROUND);
16184                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16185                    broadcastIntentLocked(null, null, intent,
16186                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16187                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16188                }
16189
16190                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16191                    if (userId != 0) {
16192                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16193                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16194                        broadcastIntentLocked(null, null, intent, null,
16195                                new IIntentReceiver.Stub() {
16196                                    public void performReceive(Intent intent, int resultCode,
16197                                            String data, Bundle extras, boolean ordered,
16198                                            boolean sticky, int sendingUser) {
16199                                        userInitialized(uss, userId);
16200                                    }
16201                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16202                                true, false, MY_PID, Process.SYSTEM_UID,
16203                                userId);
16204                        uss.initializing = true;
16205                    } else {
16206                        getUserManagerLocked().makeInitialized(userInfo.id);
16207                    }
16208                }
16209
16210                if (foreground) {
16211                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16212                    if (homeInFront) {
16213                        startHomeActivityLocked(userId);
16214                    } else {
16215                        mStackSupervisor.resumeTopActivitiesLocked();
16216                    }
16217                    EventLogTags.writeAmSwitchUser(userId);
16218                    getUserManagerLocked().userForeground(userId);
16219                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16220                }
16221
16222                if (needStart) {
16223                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16224                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16225                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16226                    broadcastIntentLocked(null, null, intent,
16227                            null, new IIntentReceiver.Stub() {
16228                                @Override
16229                                public void performReceive(Intent intent, int resultCode, String data,
16230                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16231                                        throws RemoteException {
16232                                }
16233                            }, 0, null, null,
16234                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16235                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16236                }
16237            }
16238        } finally {
16239            Binder.restoreCallingIdentity(ident);
16240        }
16241
16242        return true;
16243    }
16244
16245    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16246        long ident = Binder.clearCallingIdentity();
16247        try {
16248            Intent intent;
16249            if (oldUserId >= 0) {
16250                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16251                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16252                        | Intent.FLAG_RECEIVER_FOREGROUND);
16253                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16254                broadcastIntentLocked(null, null, intent,
16255                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16256                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16257            }
16258            if (newUserId >= 0) {
16259                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16260                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16261                        | Intent.FLAG_RECEIVER_FOREGROUND);
16262                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16263                broadcastIntentLocked(null, null, intent,
16264                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16265                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16266                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16267                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16268                        | Intent.FLAG_RECEIVER_FOREGROUND);
16269                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16270                broadcastIntentLocked(null, null, intent,
16271                        null, null, 0, null, null,
16272                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16273                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16274            }
16275        } finally {
16276            Binder.restoreCallingIdentity(ident);
16277        }
16278    }
16279
16280    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16281            final int newUserId) {
16282        final int N = mUserSwitchObservers.beginBroadcast();
16283        if (N > 0) {
16284            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16285                int mCount = 0;
16286                @Override
16287                public void sendResult(Bundle data) throws RemoteException {
16288                    synchronized (ActivityManagerService.this) {
16289                        if (mCurUserSwitchCallback == this) {
16290                            mCount++;
16291                            if (mCount == N) {
16292                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16293                            }
16294                        }
16295                    }
16296                }
16297            };
16298            synchronized (this) {
16299                uss.switching = true;
16300                mCurUserSwitchCallback = callback;
16301            }
16302            for (int i=0; i<N; i++) {
16303                try {
16304                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16305                            newUserId, callback);
16306                } catch (RemoteException e) {
16307                }
16308            }
16309        } else {
16310            synchronized (this) {
16311                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16312            }
16313        }
16314        mUserSwitchObservers.finishBroadcast();
16315    }
16316
16317    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16318        synchronized (this) {
16319            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16320            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16321        }
16322    }
16323
16324    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16325        mCurUserSwitchCallback = null;
16326        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16327        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16328                oldUserId, newUserId, uss));
16329    }
16330
16331    void userInitialized(UserStartedState uss, int newUserId) {
16332        completeSwitchAndInitalize(uss, newUserId, true, false);
16333    }
16334
16335    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16336        completeSwitchAndInitalize(uss, newUserId, false, true);
16337    }
16338
16339    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16340            boolean clearInitializing, boolean clearSwitching) {
16341        boolean unfrozen = false;
16342        synchronized (this) {
16343            if (clearInitializing) {
16344                uss.initializing = false;
16345                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16346            }
16347            if (clearSwitching) {
16348                uss.switching = false;
16349            }
16350            if (!uss.switching && !uss.initializing) {
16351                mWindowManager.stopFreezingScreen();
16352                unfrozen = true;
16353            }
16354        }
16355        if (unfrozen) {
16356            final int N = mUserSwitchObservers.beginBroadcast();
16357            for (int i=0; i<N; i++) {
16358                try {
16359                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16360                } catch (RemoteException e) {
16361                }
16362            }
16363            mUserSwitchObservers.finishBroadcast();
16364        }
16365    }
16366
16367    void finishUserSwitch(UserStartedState uss) {
16368        synchronized (this) {
16369            if (uss.mState == UserStartedState.STATE_BOOTING
16370                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16371                uss.mState = UserStartedState.STATE_RUNNING;
16372                final int userId = uss.mHandle.getIdentifier();
16373                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16374                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16375                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16376                broadcastIntentLocked(null, null, intent,
16377                        null, null, 0, null, null,
16378                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16379                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16380            }
16381            int num = mUserLru.size();
16382            int i = 0;
16383            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16384                Integer oldUserId = mUserLru.get(i);
16385                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16386                if (oldUss == null) {
16387                    // Shouldn't happen, but be sane if it does.
16388                    mUserLru.remove(i);
16389                    num--;
16390                    continue;
16391                }
16392                if (oldUss.mState == UserStartedState.STATE_STOPPING
16393                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16394                    // This user is already stopping, doesn't count.
16395                    num--;
16396                    i++;
16397                    continue;
16398                }
16399                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16400                    // Owner and current can't be stopped, but count as running.
16401                    i++;
16402                    continue;
16403                }
16404                // This is a user to be stopped.
16405                stopUserLocked(oldUserId, null);
16406                num--;
16407                i++;
16408            }
16409        }
16410    }
16411
16412    @Override
16413    public int stopUser(final int userId, final IStopUserCallback callback) {
16414        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16415                != PackageManager.PERMISSION_GRANTED) {
16416            String msg = "Permission Denial: switchUser() from pid="
16417                    + Binder.getCallingPid()
16418                    + ", uid=" + Binder.getCallingUid()
16419                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16420            Slog.w(TAG, msg);
16421            throw new SecurityException(msg);
16422        }
16423        if (userId <= 0) {
16424            throw new IllegalArgumentException("Can't stop primary user " + userId);
16425        }
16426        synchronized (this) {
16427            return stopUserLocked(userId, callback);
16428        }
16429    }
16430
16431    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16432        if (mCurrentUserId == userId) {
16433            return ActivityManager.USER_OP_IS_CURRENT;
16434        }
16435
16436        final UserStartedState uss = mStartedUsers.get(userId);
16437        if (uss == null) {
16438            // User is not started, nothing to do...  but we do need to
16439            // callback if requested.
16440            if (callback != null) {
16441                mHandler.post(new Runnable() {
16442                    @Override
16443                    public void run() {
16444                        try {
16445                            callback.userStopped(userId);
16446                        } catch (RemoteException e) {
16447                        }
16448                    }
16449                });
16450            }
16451            return ActivityManager.USER_OP_SUCCESS;
16452        }
16453
16454        if (callback != null) {
16455            uss.mStopCallbacks.add(callback);
16456        }
16457
16458        if (uss.mState != UserStartedState.STATE_STOPPING
16459                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16460            uss.mState = UserStartedState.STATE_STOPPING;
16461            updateStartedUserArrayLocked();
16462
16463            long ident = Binder.clearCallingIdentity();
16464            try {
16465                // We are going to broadcast ACTION_USER_STOPPING and then
16466                // once that is done send a final ACTION_SHUTDOWN and then
16467                // stop the user.
16468                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16469                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16470                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16471                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16472                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16473                // This is the result receiver for the final shutdown broadcast.
16474                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16475                    @Override
16476                    public void performReceive(Intent intent, int resultCode, String data,
16477                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16478                        finishUserStop(uss);
16479                    }
16480                };
16481                // This is the result receiver for the initial stopping broadcast.
16482                final IIntentReceiver stoppingReceiver = 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                        // On to the next.
16487                        synchronized (ActivityManagerService.this) {
16488                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16489                                // Whoops, we are being started back up.  Abort, abort!
16490                                return;
16491                            }
16492                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16493                        }
16494                        broadcastIntentLocked(null, null, shutdownIntent,
16495                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16496                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16497                    }
16498                };
16499                // Kick things off.
16500                broadcastIntentLocked(null, null, stoppingIntent,
16501                        null, stoppingReceiver, 0, null, null,
16502                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16503                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16504            } finally {
16505                Binder.restoreCallingIdentity(ident);
16506            }
16507        }
16508
16509        return ActivityManager.USER_OP_SUCCESS;
16510    }
16511
16512    void finishUserStop(UserStartedState uss) {
16513        final int userId = uss.mHandle.getIdentifier();
16514        boolean stopped;
16515        ArrayList<IStopUserCallback> callbacks;
16516        synchronized (this) {
16517            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16518            if (mStartedUsers.get(userId) != uss) {
16519                stopped = false;
16520            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16521                stopped = false;
16522            } else {
16523                stopped = true;
16524                // User can no longer run.
16525                mStartedUsers.remove(userId);
16526                mUserLru.remove(Integer.valueOf(userId));
16527                updateStartedUserArrayLocked();
16528
16529                // Clean up all state and processes associated with the user.
16530                // Kill all the processes for the user.
16531                forceStopUserLocked(userId, "finish user");
16532            }
16533        }
16534
16535        for (int i=0; i<callbacks.size(); i++) {
16536            try {
16537                if (stopped) callbacks.get(i).userStopped(userId);
16538                else callbacks.get(i).userStopAborted(userId);
16539            } catch (RemoteException e) {
16540            }
16541        }
16542
16543        mStackSupervisor.removeUserLocked(userId);
16544    }
16545
16546    @Override
16547    public UserInfo getCurrentUser() {
16548        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16549                != PackageManager.PERMISSION_GRANTED) && (
16550                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16551                != PackageManager.PERMISSION_GRANTED)) {
16552            String msg = "Permission Denial: getCurrentUser() from pid="
16553                    + Binder.getCallingPid()
16554                    + ", uid=" + Binder.getCallingUid()
16555                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16556            Slog.w(TAG, msg);
16557            throw new SecurityException(msg);
16558        }
16559        synchronized (this) {
16560            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16561        }
16562    }
16563
16564    int getCurrentUserIdLocked() {
16565        return mCurrentUserId;
16566    }
16567
16568    @Override
16569    public boolean isUserRunning(int userId, boolean orStopped) {
16570        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16571                != PackageManager.PERMISSION_GRANTED) {
16572            String msg = "Permission Denial: isUserRunning() from pid="
16573                    + Binder.getCallingPid()
16574                    + ", uid=" + Binder.getCallingUid()
16575                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16576            Slog.w(TAG, msg);
16577            throw new SecurityException(msg);
16578        }
16579        synchronized (this) {
16580            return isUserRunningLocked(userId, orStopped);
16581        }
16582    }
16583
16584    boolean isUserRunningLocked(int userId, boolean orStopped) {
16585        UserStartedState state = mStartedUsers.get(userId);
16586        if (state == null) {
16587            return false;
16588        }
16589        if (orStopped) {
16590            return true;
16591        }
16592        return state.mState != UserStartedState.STATE_STOPPING
16593                && state.mState != UserStartedState.STATE_SHUTDOWN;
16594    }
16595
16596    @Override
16597    public int[] getRunningUserIds() {
16598        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16599                != PackageManager.PERMISSION_GRANTED) {
16600            String msg = "Permission Denial: isUserRunning() from pid="
16601                    + Binder.getCallingPid()
16602                    + ", uid=" + Binder.getCallingUid()
16603                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16604            Slog.w(TAG, msg);
16605            throw new SecurityException(msg);
16606        }
16607        synchronized (this) {
16608            return mStartedUserArray;
16609        }
16610    }
16611
16612    private void updateStartedUserArrayLocked() {
16613        int num = 0;
16614        for (int i=0; i<mStartedUsers.size();  i++) {
16615            UserStartedState uss = mStartedUsers.valueAt(i);
16616            // This list does not include stopping users.
16617            if (uss.mState != UserStartedState.STATE_STOPPING
16618                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16619                num++;
16620            }
16621        }
16622        mStartedUserArray = new int[num];
16623        num = 0;
16624        for (int i=0; i<mStartedUsers.size();  i++) {
16625            UserStartedState uss = mStartedUsers.valueAt(i);
16626            if (uss.mState != UserStartedState.STATE_STOPPING
16627                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16628                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16629                num++;
16630            }
16631        }
16632    }
16633
16634    @Override
16635    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16636        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16637                != PackageManager.PERMISSION_GRANTED) {
16638            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16639                    + Binder.getCallingPid()
16640                    + ", uid=" + Binder.getCallingUid()
16641                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16642            Slog.w(TAG, msg);
16643            throw new SecurityException(msg);
16644        }
16645
16646        mUserSwitchObservers.register(observer);
16647    }
16648
16649    @Override
16650    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16651        mUserSwitchObservers.unregister(observer);
16652    }
16653
16654    private boolean userExists(int userId) {
16655        if (userId == 0) {
16656            return true;
16657        }
16658        UserManagerService ums = getUserManagerLocked();
16659        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16660    }
16661
16662    int[] getUsersLocked() {
16663        UserManagerService ums = getUserManagerLocked();
16664        return ums != null ? ums.getUserIds() : new int[] { 0 };
16665    }
16666
16667    UserManagerService getUserManagerLocked() {
16668        if (mUserManager == null) {
16669            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16670            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16671        }
16672        return mUserManager;
16673    }
16674
16675    private int applyUserId(int uid, int userId) {
16676        return UserHandle.getUid(userId, uid);
16677    }
16678
16679    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16680        if (info == null) return null;
16681        ApplicationInfo newInfo = new ApplicationInfo(info);
16682        newInfo.uid = applyUserId(info.uid, userId);
16683        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16684                + info.packageName;
16685        return newInfo;
16686    }
16687
16688    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16689        if (aInfo == null
16690                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16691            return aInfo;
16692        }
16693
16694        ActivityInfo info = new ActivityInfo(aInfo);
16695        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16696        return info;
16697    }
16698}
16699