ActivityManagerService.java revision 6f357d3284a833cc50a990e14b39f389b8972254
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.util.ArrayMap;
36import com.android.internal.R;
37import com.android.internal.annotations.GuardedBy;
38import com.android.internal.app.IAppOpsService;
39import com.android.internal.app.ProcessMap;
40import com.android.internal.app.ProcessStats;
41import com.android.internal.os.BackgroundThread;
42import com.android.internal.os.BatteryStatsImpl;
43import com.android.internal.os.ProcessCpuTracker;
44import com.android.internal.os.TransferPipe;
45import com.android.internal.util.FastPrintWriter;
46import com.android.internal.util.FastXmlSerializer;
47import com.android.internal.util.MemInfoReader;
48import com.android.internal.util.Preconditions;
49import com.android.server.AppOpsService;
50import com.android.server.AttributeCache;
51import com.android.server.IntentResolver;
52import com.android.server.ServiceThread;
53import com.android.server.SystemServer;
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 situatin started.
925     */
926    long mLowRamStartTime = 0;
927
928    /**
929     * This is set if we had to do a delayed dexopt of an app before launching
930     * it, to increasing the ANR timeouts in that case.
931     */
932    boolean mDidDexOpt;
933
934    String mDebugApp = null;
935    boolean mWaitForDebugger = false;
936    boolean mDebugTransient = false;
937    String mOrigDebugApp = null;
938    boolean mOrigWaitForDebugger = false;
939    boolean mAlwaysFinishActivities = false;
940    IActivityController mController = null;
941    String mProfileApp = null;
942    ProcessRecord mProfileProc = null;
943    String mProfileFile;
944    ParcelFileDescriptor mProfileFd;
945    int mProfileType = 0;
946    boolean mAutoStopProfiler = false;
947    String mOpenGlTraceApp = null;
948
949    static class ProcessChangeItem {
950        static final int CHANGE_ACTIVITIES = 1<<0;
951        static final int CHANGE_IMPORTANCE= 1<<1;
952        int changes;
953        int uid;
954        int pid;
955        int importance;
956        boolean foregroundActivities;
957    }
958
959    final RemoteCallbackList<IProcessObserver> mProcessObservers
960            = new RemoteCallbackList<IProcessObserver>();
961    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
962
963    final ArrayList<ProcessChangeItem> mPendingProcessChanges
964            = new ArrayList<ProcessChangeItem>();
965    final ArrayList<ProcessChangeItem> mAvailProcessChanges
966            = new ArrayList<ProcessChangeItem>();
967
968    /**
969     * Runtime CPU use collection thread.  This object's lock is used to
970     * protect all related state.
971     */
972    final Thread mProcessCpuThread;
973
974    /**
975     * Used to collect process stats when showing not responding dialog.
976     * Protected by mProcessCpuThread.
977     */
978    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
979            MONITOR_THREAD_CPU_USAGE);
980    final AtomicLong mLastCpuTime = new AtomicLong(0);
981    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
982
983    long mLastWriteTime = 0;
984
985    /**
986     * Used to retain an update lock when the foreground activity is in
987     * immersive mode.
988     */
989    final UpdateLock mUpdateLock = new UpdateLock("immersive");
990
991    /**
992     * Set to true after the system has finished booting.
993     */
994    boolean mBooted = false;
995
996    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
997    int mProcessLimitOverride = -1;
998
999    WindowManagerService mWindowManager;
1000
1001    static ActivityManagerService sSelf;
1002    static ActivityThread sSystemThread;
1003
1004    int mCurrentUserId = 0;
1005    private UserManagerService mUserManager;
1006
1007    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1008        final ProcessRecord mApp;
1009        final int mPid;
1010        final IApplicationThread mAppThread;
1011
1012        AppDeathRecipient(ProcessRecord app, int pid,
1013                IApplicationThread thread) {
1014            if (localLOGV) Slog.v(
1015                TAG, "New death recipient " + this
1016                + " for thread " + thread.asBinder());
1017            mApp = app;
1018            mPid = pid;
1019            mAppThread = thread;
1020        }
1021
1022        @Override
1023        public void binderDied() {
1024            if (localLOGV) Slog.v(
1025                TAG, "Death received in " + this
1026                + " for thread " + mAppThread.asBinder());
1027            synchronized(ActivityManagerService.this) {
1028                appDiedLocked(mApp, mPid, mAppThread);
1029            }
1030        }
1031    }
1032
1033    static final int SHOW_ERROR_MSG = 1;
1034    static final int SHOW_NOT_RESPONDING_MSG = 2;
1035    static final int SHOW_FACTORY_ERROR_MSG = 3;
1036    static final int UPDATE_CONFIGURATION_MSG = 4;
1037    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1038    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1039    static final int SERVICE_TIMEOUT_MSG = 12;
1040    static final int UPDATE_TIME_ZONE = 13;
1041    static final int SHOW_UID_ERROR_MSG = 14;
1042    static final int IM_FEELING_LUCKY_MSG = 15;
1043    static final int PROC_START_TIMEOUT_MSG = 20;
1044    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1045    static final int KILL_APPLICATION_MSG = 22;
1046    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1047    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1048    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1049    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1050    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1051    static final int CLEAR_DNS_CACHE_MSG = 28;
1052    static final int UPDATE_HTTP_PROXY_MSG = 29;
1053    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1054    static final int DISPATCH_PROCESSES_CHANGED = 31;
1055    static final int DISPATCH_PROCESS_DIED = 32;
1056    static final int REPORT_MEM_USAGE_MSG = 33;
1057    static final int REPORT_USER_SWITCH_MSG = 34;
1058    static final int CONTINUE_USER_SWITCH_MSG = 35;
1059    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1060    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1061    static final int PERSIST_URI_GRANTS_MSG = 38;
1062    static final int REQUEST_ALL_PSS_MSG = 39;
1063
1064    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1065    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1066    static final int FIRST_COMPAT_MODE_MSG = 300;
1067    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1068
1069    AlertDialog mUidAlert;
1070    CompatModeDialog mCompatModeDialog;
1071    long mLastMemUsageReportTime = 0;
1072
1073    /**
1074     * Flag whether the current user is a "monkey", i.e. whether
1075     * the UI is driven by a UI automation tool.
1076     */
1077    private boolean mUserIsMonkey;
1078
1079    final ServiceThread mHandlerThread;
1080    final MainHandler mHandler;
1081
1082    final class MainHandler extends Handler {
1083        public MainHandler(Looper looper) {
1084            super(looper, null, true);
1085        }
1086
1087        @Override
1088        public void handleMessage(Message msg) {
1089            switch (msg.what) {
1090            case SHOW_ERROR_MSG: {
1091                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1092                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1093                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1094                synchronized (ActivityManagerService.this) {
1095                    ProcessRecord proc = (ProcessRecord)data.get("app");
1096                    AppErrorResult res = (AppErrorResult) data.get("result");
1097                    if (proc != null && proc.crashDialog != null) {
1098                        Slog.e(TAG, "App already has crash dialog: " + proc);
1099                        if (res != null) {
1100                            res.set(0);
1101                        }
1102                        return;
1103                    }
1104                    if (!showBackground && UserHandle.getAppId(proc.uid)
1105                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1106                            && proc.pid != MY_PID) {
1107                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1108                        if (res != null) {
1109                            res.set(0);
1110                        }
1111                        return;
1112                    }
1113                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1114                        Dialog d = new AppErrorDialog(mContext,
1115                                ActivityManagerService.this, res, proc);
1116                        d.show();
1117                        proc.crashDialog = d;
1118                    } else {
1119                        // The device is asleep, so just pretend that the user
1120                        // saw a crash dialog and hit "force quit".
1121                        if (res != null) {
1122                            res.set(0);
1123                        }
1124                    }
1125                }
1126
1127                ensureBootCompleted();
1128            } break;
1129            case SHOW_NOT_RESPONDING_MSG: {
1130                synchronized (ActivityManagerService.this) {
1131                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1132                    ProcessRecord proc = (ProcessRecord)data.get("app");
1133                    if (proc != null && proc.anrDialog != null) {
1134                        Slog.e(TAG, "App already has anr dialog: " + proc);
1135                        return;
1136                    }
1137
1138                    Intent intent = new Intent("android.intent.action.ANR");
1139                    if (!mProcessesReady) {
1140                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1141                                | Intent.FLAG_RECEIVER_FOREGROUND);
1142                    }
1143                    broadcastIntentLocked(null, null, intent,
1144                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1145                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1146
1147                    if (mShowDialogs) {
1148                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1149                                mContext, proc, (ActivityRecord)data.get("activity"),
1150                                msg.arg1 != 0);
1151                        d.show();
1152                        proc.anrDialog = d;
1153                    } else {
1154                        // Just kill the app if there is no dialog to be shown.
1155                        killAppAtUsersRequest(proc, null);
1156                    }
1157                }
1158
1159                ensureBootCompleted();
1160            } break;
1161            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1162                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1163                synchronized (ActivityManagerService.this) {
1164                    ProcessRecord proc = (ProcessRecord) data.get("app");
1165                    if (proc == null) {
1166                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1167                        break;
1168                    }
1169                    if (proc.crashDialog != null) {
1170                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1171                        return;
1172                    }
1173                    AppErrorResult res = (AppErrorResult) data.get("result");
1174                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1175                        Dialog d = new StrictModeViolationDialog(mContext,
1176                                ActivityManagerService.this, res, proc);
1177                        d.show();
1178                        proc.crashDialog = d;
1179                    } else {
1180                        // The device is asleep, so just pretend that the user
1181                        // saw a crash dialog and hit "force quit".
1182                        res.set(0);
1183                    }
1184                }
1185                ensureBootCompleted();
1186            } break;
1187            case SHOW_FACTORY_ERROR_MSG: {
1188                Dialog d = new FactoryErrorDialog(
1189                    mContext, msg.getData().getCharSequence("msg"));
1190                d.show();
1191                ensureBootCompleted();
1192            } break;
1193            case UPDATE_CONFIGURATION_MSG: {
1194                final ContentResolver resolver = mContext.getContentResolver();
1195                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1196            } break;
1197            case GC_BACKGROUND_PROCESSES_MSG: {
1198                synchronized (ActivityManagerService.this) {
1199                    performAppGcsIfAppropriateLocked();
1200                }
1201            } break;
1202            case WAIT_FOR_DEBUGGER_MSG: {
1203                synchronized (ActivityManagerService.this) {
1204                    ProcessRecord app = (ProcessRecord)msg.obj;
1205                    if (msg.arg1 != 0) {
1206                        if (!app.waitedForDebugger) {
1207                            Dialog d = new AppWaitingForDebuggerDialog(
1208                                    ActivityManagerService.this,
1209                                    mContext, app);
1210                            app.waitDialog = d;
1211                            app.waitedForDebugger = true;
1212                            d.show();
1213                        }
1214                    } else {
1215                        if (app.waitDialog != null) {
1216                            app.waitDialog.dismiss();
1217                            app.waitDialog = null;
1218                        }
1219                    }
1220                }
1221            } break;
1222            case SERVICE_TIMEOUT_MSG: {
1223                if (mDidDexOpt) {
1224                    mDidDexOpt = false;
1225                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1226                    nmsg.obj = msg.obj;
1227                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1228                    return;
1229                }
1230                mServices.serviceTimeout((ProcessRecord)msg.obj);
1231            } break;
1232            case UPDATE_TIME_ZONE: {
1233                synchronized (ActivityManagerService.this) {
1234                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1235                        ProcessRecord r = mLruProcesses.get(i);
1236                        if (r.thread != null) {
1237                            try {
1238                                r.thread.updateTimeZone();
1239                            } catch (RemoteException ex) {
1240                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1241                            }
1242                        }
1243                    }
1244                }
1245            } break;
1246            case CLEAR_DNS_CACHE_MSG: {
1247                synchronized (ActivityManagerService.this) {
1248                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1249                        ProcessRecord r = mLruProcesses.get(i);
1250                        if (r.thread != null) {
1251                            try {
1252                                r.thread.clearDnsCache();
1253                            } catch (RemoteException ex) {
1254                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1255                            }
1256                        }
1257                    }
1258                }
1259            } break;
1260            case UPDATE_HTTP_PROXY_MSG: {
1261                ProxyProperties proxy = (ProxyProperties)msg.obj;
1262                String host = "";
1263                String port = "";
1264                String exclList = "";
1265                String pacFileUrl = null;
1266                if (proxy != null) {
1267                    host = proxy.getHost();
1268                    port = Integer.toString(proxy.getPort());
1269                    exclList = proxy.getExclusionList();
1270                    pacFileUrl = proxy.getPacFileUrl();
1271                }
1272                synchronized (ActivityManagerService.this) {
1273                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1274                        ProcessRecord r = mLruProcesses.get(i);
1275                        if (r.thread != null) {
1276                            try {
1277                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1278                            } catch (RemoteException ex) {
1279                                Slog.w(TAG, "Failed to update http proxy for: " +
1280                                        r.info.processName);
1281                            }
1282                        }
1283                    }
1284                }
1285            } break;
1286            case SHOW_UID_ERROR_MSG: {
1287                String title = "System UIDs Inconsistent";
1288                String text = "UIDs on the system are inconsistent, you need to wipe your"
1289                        + " data partition or your device will be unstable.";
1290                Log.e(TAG, title + ": " + text);
1291                if (mShowDialogs) {
1292                    // XXX This is a temporary dialog, no need to localize.
1293                    AlertDialog d = new BaseErrorDialog(mContext);
1294                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1295                    d.setCancelable(false);
1296                    d.setTitle(title);
1297                    d.setMessage(text);
1298                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1299                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1300                    mUidAlert = d;
1301                    d.show();
1302                }
1303            } break;
1304            case IM_FEELING_LUCKY_MSG: {
1305                if (mUidAlert != null) {
1306                    mUidAlert.dismiss();
1307                    mUidAlert = null;
1308                }
1309            } break;
1310            case PROC_START_TIMEOUT_MSG: {
1311                if (mDidDexOpt) {
1312                    mDidDexOpt = false;
1313                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1314                    nmsg.obj = msg.obj;
1315                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1316                    return;
1317                }
1318                ProcessRecord app = (ProcessRecord)msg.obj;
1319                synchronized (ActivityManagerService.this) {
1320                    processStartTimedOutLocked(app);
1321                }
1322            } break;
1323            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1324                synchronized (ActivityManagerService.this) {
1325                    doPendingActivityLaunchesLocked(true);
1326                }
1327            } break;
1328            case KILL_APPLICATION_MSG: {
1329                synchronized (ActivityManagerService.this) {
1330                    int appid = msg.arg1;
1331                    boolean restart = (msg.arg2 == 1);
1332                    Bundle bundle = (Bundle)msg.obj;
1333                    String pkg = bundle.getString("pkg");
1334                    String reason = bundle.getString("reason");
1335                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1336                            UserHandle.USER_ALL, reason);
1337                }
1338            } break;
1339            case FINALIZE_PENDING_INTENT_MSG: {
1340                ((PendingIntentRecord)msg.obj).completeFinalize();
1341            } break;
1342            case POST_HEAVY_NOTIFICATION_MSG: {
1343                INotificationManager inm = NotificationManager.getService();
1344                if (inm == null) {
1345                    return;
1346                }
1347
1348                ActivityRecord root = (ActivityRecord)msg.obj;
1349                ProcessRecord process = root.app;
1350                if (process == null) {
1351                    return;
1352                }
1353
1354                try {
1355                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1356                    String text = mContext.getString(R.string.heavy_weight_notification,
1357                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1358                    Notification notification = new Notification();
1359                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1360                    notification.when = 0;
1361                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1362                    notification.tickerText = text;
1363                    notification.defaults = 0; // please be quiet
1364                    notification.sound = null;
1365                    notification.vibrate = null;
1366                    notification.setLatestEventInfo(context, text,
1367                            mContext.getText(R.string.heavy_weight_notification_detail),
1368                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1369                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1370                                    new UserHandle(root.userId)));
1371
1372                    try {
1373                        int[] outId = new int[1];
1374                        inm.enqueueNotificationWithTag("android", "android", null,
1375                                R.string.heavy_weight_notification,
1376                                notification, outId, root.userId);
1377                    } catch (RuntimeException e) {
1378                        Slog.w(ActivityManagerService.TAG,
1379                                "Error showing notification for heavy-weight app", e);
1380                    } catch (RemoteException e) {
1381                    }
1382                } catch (NameNotFoundException e) {
1383                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1384                }
1385            } break;
1386            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1387                INotificationManager inm = NotificationManager.getService();
1388                if (inm == null) {
1389                    return;
1390                }
1391                try {
1392                    inm.cancelNotificationWithTag("android", null,
1393                            R.string.heavy_weight_notification,  msg.arg1);
1394                } catch (RuntimeException e) {
1395                    Slog.w(ActivityManagerService.TAG,
1396                            "Error canceling notification for service", e);
1397                } catch (RemoteException e) {
1398                }
1399            } break;
1400            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1401                synchronized (ActivityManagerService.this) {
1402                    checkExcessivePowerUsageLocked(true);
1403                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1404                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1405                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1406                }
1407            } break;
1408            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1409                synchronized (ActivityManagerService.this) {
1410                    ActivityRecord ar = (ActivityRecord)msg.obj;
1411                    if (mCompatModeDialog != null) {
1412                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1413                                ar.info.applicationInfo.packageName)) {
1414                            return;
1415                        }
1416                        mCompatModeDialog.dismiss();
1417                        mCompatModeDialog = null;
1418                    }
1419                    if (ar != null && false) {
1420                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1421                                ar.packageName)) {
1422                            int mode = mCompatModePackages.computeCompatModeLocked(
1423                                    ar.info.applicationInfo);
1424                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1425                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1426                                mCompatModeDialog = new CompatModeDialog(
1427                                        ActivityManagerService.this, mContext,
1428                                        ar.info.applicationInfo);
1429                                mCompatModeDialog.show();
1430                            }
1431                        }
1432                    }
1433                }
1434                break;
1435            }
1436            case DISPATCH_PROCESSES_CHANGED: {
1437                dispatchProcessesChanged();
1438                break;
1439            }
1440            case DISPATCH_PROCESS_DIED: {
1441                final int pid = msg.arg1;
1442                final int uid = msg.arg2;
1443                dispatchProcessDied(pid, uid);
1444                break;
1445            }
1446            case REPORT_MEM_USAGE_MSG: {
1447                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1448                Thread thread = new Thread() {
1449                    @Override public void run() {
1450                        final SparseArray<ProcessMemInfo> infoMap
1451                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1452                        for (int i=0, N=memInfos.size(); i<N; i++) {
1453                            ProcessMemInfo mi = memInfos.get(i);
1454                            infoMap.put(mi.pid, mi);
1455                        }
1456                        updateCpuStatsNow();
1457                        synchronized (mProcessCpuThread) {
1458                            final int N = mProcessCpuTracker.countStats();
1459                            for (int i=0; i<N; i++) {
1460                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1461                                if (st.vsize > 0) {
1462                                    long pss = Debug.getPss(st.pid, null);
1463                                    if (pss > 0) {
1464                                        if (infoMap.indexOfKey(st.pid) < 0) {
1465                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1466                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1467                                            mi.pss = pss;
1468                                            memInfos.add(mi);
1469                                        }
1470                                    }
1471                                }
1472                            }
1473                        }
1474
1475                        long totalPss = 0;
1476                        for (int i=0, N=memInfos.size(); i<N; i++) {
1477                            ProcessMemInfo mi = memInfos.get(i);
1478                            if (mi.pss == 0) {
1479                                mi.pss = Debug.getPss(mi.pid, null);
1480                            }
1481                            totalPss += mi.pss;
1482                        }
1483                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1484                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1485                                if (lhs.oomAdj != rhs.oomAdj) {
1486                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1487                                }
1488                                if (lhs.pss != rhs.pss) {
1489                                    return lhs.pss < rhs.pss ? 1 : -1;
1490                                }
1491                                return 0;
1492                            }
1493                        });
1494
1495                        StringBuilder tag = new StringBuilder(128);
1496                        StringBuilder stack = new StringBuilder(128);
1497                        tag.append("Low on memory -- ");
1498                        appendMemBucket(tag, totalPss, "total", false);
1499                        appendMemBucket(stack, totalPss, "total", true);
1500
1501                        StringBuilder logBuilder = new StringBuilder(1024);
1502                        logBuilder.append("Low on memory:\n");
1503
1504                        boolean firstLine = true;
1505                        int lastOomAdj = Integer.MIN_VALUE;
1506                        for (int i=0, N=memInfos.size(); i<N; i++) {
1507                            ProcessMemInfo mi = memInfos.get(i);
1508
1509                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1510                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1511                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1512                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1513                                if (lastOomAdj != mi.oomAdj) {
1514                                    lastOomAdj = mi.oomAdj;
1515                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1516                                        tag.append(" / ");
1517                                    }
1518                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1519                                        if (firstLine) {
1520                                            stack.append(":");
1521                                            firstLine = false;
1522                                        }
1523                                        stack.append("\n\t at ");
1524                                    } else {
1525                                        stack.append("$");
1526                                    }
1527                                } else {
1528                                    tag.append(" ");
1529                                    stack.append("$");
1530                                }
1531                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1532                                    appendMemBucket(tag, mi.pss, mi.name, false);
1533                                }
1534                                appendMemBucket(stack, mi.pss, mi.name, true);
1535                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1536                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1537                                    stack.append("(");
1538                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1539                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1540                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1541                                            stack.append(":");
1542                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1543                                        }
1544                                    }
1545                                    stack.append(")");
1546                                }
1547                            }
1548
1549                            logBuilder.append("  ");
1550                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1551                            logBuilder.append(' ');
1552                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1553                            logBuilder.append(' ');
1554                            ProcessList.appendRamKb(logBuilder, mi.pss);
1555                            logBuilder.append(" kB: ");
1556                            logBuilder.append(mi.name);
1557                            logBuilder.append(" (");
1558                            logBuilder.append(mi.pid);
1559                            logBuilder.append(") ");
1560                            logBuilder.append(mi.adjType);
1561                            logBuilder.append('\n');
1562                            if (mi.adjReason != null) {
1563                                logBuilder.append("                      ");
1564                                logBuilder.append(mi.adjReason);
1565                                logBuilder.append('\n');
1566                            }
1567                        }
1568
1569                        logBuilder.append("           ");
1570                        ProcessList.appendRamKb(logBuilder, totalPss);
1571                        logBuilder.append(" kB: TOTAL\n");
1572
1573                        long[] infos = new long[Debug.MEMINFO_COUNT];
1574                        Debug.getMemInfo(infos);
1575                        logBuilder.append("  MemInfo: ");
1576                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1577                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1578                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1579                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1580                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1581                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1582                            logBuilder.append("  ZRAM: ");
1583                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1584                            logBuilder.append(" kB RAM, ");
1585                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1586                            logBuilder.append(" kB swap total, ");
1587                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1588                            logBuilder.append(" kB swap free\n");
1589                        }
1590                        Slog.i(TAG, logBuilder.toString());
1591
1592                        StringBuilder dropBuilder = new StringBuilder(1024);
1593                        /*
1594                        StringWriter oomSw = new StringWriter();
1595                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1596                        StringWriter catSw = new StringWriter();
1597                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1598                        String[] emptyArgs = new String[] { };
1599                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1600                        oomPw.flush();
1601                        String oomString = oomSw.toString();
1602                        */
1603                        dropBuilder.append(stack);
1604                        dropBuilder.append('\n');
1605                        dropBuilder.append('\n');
1606                        dropBuilder.append(logBuilder);
1607                        dropBuilder.append('\n');
1608                        /*
1609                        dropBuilder.append(oomString);
1610                        dropBuilder.append('\n');
1611                        */
1612                        StringWriter catSw = new StringWriter();
1613                        synchronized (ActivityManagerService.this) {
1614                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1615                            String[] emptyArgs = new String[] { };
1616                            catPw.println();
1617                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1618                            catPw.println();
1619                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1620                                    false, false, null);
1621                            catPw.println();
1622                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1623                            catPw.flush();
1624                        }
1625                        dropBuilder.append(catSw.toString());
1626                        addErrorToDropBox("lowmem", null, "system_server", null,
1627                                null, tag.toString(), dropBuilder.toString(), null, null);
1628                        //Slog.i(TAG, "Sent to dropbox:");
1629                        //Slog.i(TAG, dropBuilder.toString());
1630                        synchronized (ActivityManagerService.this) {
1631                            long now = SystemClock.uptimeMillis();
1632                            if (mLastMemUsageReportTime < now) {
1633                                mLastMemUsageReportTime = now;
1634                            }
1635                        }
1636                    }
1637                };
1638                thread.start();
1639                break;
1640            }
1641            case REPORT_USER_SWITCH_MSG: {
1642                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1643                break;
1644            }
1645            case CONTINUE_USER_SWITCH_MSG: {
1646                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1647                break;
1648            }
1649            case USER_SWITCH_TIMEOUT_MSG: {
1650                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1651                break;
1652            }
1653            case IMMERSIVE_MODE_LOCK_MSG: {
1654                final boolean nextState = (msg.arg1 != 0);
1655                if (mUpdateLock.isHeld() != nextState) {
1656                    if (DEBUG_IMMERSIVE) {
1657                        final ActivityRecord r = (ActivityRecord) msg.obj;
1658                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1659                    }
1660                    if (nextState) {
1661                        mUpdateLock.acquire();
1662                    } else {
1663                        mUpdateLock.release();
1664                    }
1665                }
1666                break;
1667            }
1668            case PERSIST_URI_GRANTS_MSG: {
1669                writeGrantedUriPermissions();
1670                break;
1671            }
1672            case REQUEST_ALL_PSS_MSG: {
1673                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1674                break;
1675            }
1676            }
1677        }
1678    };
1679
1680    static final int COLLECT_PSS_BG_MSG = 1;
1681
1682    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1683        @Override
1684        public void handleMessage(Message msg) {
1685            switch (msg.what) {
1686            case COLLECT_PSS_BG_MSG: {
1687                int i=0, num=0;
1688                long start = SystemClock.uptimeMillis();
1689                long[] tmp = new long[1];
1690                do {
1691                    ProcessRecord proc;
1692                    int procState;
1693                    int pid;
1694                    synchronized (ActivityManagerService.this) {
1695                        if (i >= mPendingPssProcesses.size()) {
1696                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1697                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1698                            mPendingPssProcesses.clear();
1699                            return;
1700                        }
1701                        proc = mPendingPssProcesses.get(i);
1702                        procState = proc.pssProcState;
1703                        if (proc.thread != null && procState == proc.setProcState) {
1704                            pid = proc.pid;
1705                        } else {
1706                            proc = null;
1707                            pid = 0;
1708                        }
1709                        i++;
1710                    }
1711                    if (proc != null) {
1712                        long pss = Debug.getPss(pid, tmp);
1713                        synchronized (ActivityManagerService.this) {
1714                            if (proc.thread != null && proc.setProcState == procState
1715                                    && proc.pid == pid) {
1716                                num++;
1717                                proc.lastPssTime = SystemClock.uptimeMillis();
1718                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1719                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1720                                        + ": " + pss + " lastPss=" + proc.lastPss
1721                                        + " state=" + ProcessList.makeProcStateString(procState));
1722                                if (proc.initialIdlePss == 0) {
1723                                    proc.initialIdlePss = pss;
1724                                }
1725                                proc.lastPss = pss;
1726                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1727                                    proc.lastCachedPss = pss;
1728                                }
1729                            }
1730                        }
1731                    }
1732                } while (true);
1733            }
1734            }
1735        }
1736    };
1737
1738    public static void setSystemProcess() {
1739        try {
1740            ActivityManagerService m = sSelf;
1741
1742            ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
1743            ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
1744            ServiceManager.addService("meminfo", new MemBinder(m));
1745            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1746            ServiceManager.addService("dbinfo", new DbBinder(m));
1747            if (MONITOR_CPU_USAGE) {
1748                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1749            }
1750            ServiceManager.addService("permission", new PermissionController(m));
1751
1752            ApplicationInfo info =
1753                sSelf.mContext.getPackageManager().getApplicationInfo(
1754                            "android", STOCK_PM_FLAGS);
1755            sSystemThread.installSystemApplicationInfo(info);
1756
1757            synchronized (sSelf) {
1758                ProcessRecord app = sSelf.newProcessRecordLocked(info,
1759                        info.processName, false);
1760                app.persistent = true;
1761                app.pid = MY_PID;
1762                app.maxAdj = ProcessList.SYSTEM_ADJ;
1763                app.makeActive(sSystemThread.getApplicationThread(), sSelf.mProcessStats);
1764                sSelf.mProcessNames.put(app.processName, app.uid, app);
1765                synchronized (sSelf.mPidsSelfLocked) {
1766                    sSelf.mPidsSelfLocked.put(app.pid, app);
1767                }
1768                sSelf.updateLruProcessLocked(app, false, null);
1769                sSelf.updateOomAdjLocked();
1770            }
1771        } catch (PackageManager.NameNotFoundException e) {
1772            throw new RuntimeException(
1773                    "Unable to find android system package", e);
1774        }
1775    }
1776
1777    public void setWindowManager(WindowManagerService wm) {
1778        mWindowManager = wm;
1779        mStackSupervisor.setWindowManager(wm);
1780    }
1781
1782    public void startObservingNativeCrashes() {
1783        final NativeCrashListener ncl = new NativeCrashListener();
1784        ncl.start();
1785    }
1786
1787    public static ActivityManagerService self() {
1788        return sSelf;
1789    }
1790
1791    public IAppOpsService getAppOpsService() {
1792        return mAppOpsService;
1793    }
1794
1795    static class MemBinder extends Binder {
1796        ActivityManagerService mActivityManagerService;
1797        MemBinder(ActivityManagerService activityManagerService) {
1798            mActivityManagerService = activityManagerService;
1799        }
1800
1801        @Override
1802        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1803            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1804                    != PackageManager.PERMISSION_GRANTED) {
1805                pw.println("Permission Denial: can't dump meminfo from from pid="
1806                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1807                        + " without permission " + android.Manifest.permission.DUMP);
1808                return;
1809            }
1810
1811            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1812        }
1813    }
1814
1815    static class GraphicsBinder extends Binder {
1816        ActivityManagerService mActivityManagerService;
1817        GraphicsBinder(ActivityManagerService activityManagerService) {
1818            mActivityManagerService = activityManagerService;
1819        }
1820
1821        @Override
1822        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1823            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1824                    != PackageManager.PERMISSION_GRANTED) {
1825                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1826                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1827                        + " without permission " + android.Manifest.permission.DUMP);
1828                return;
1829            }
1830
1831            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1832        }
1833    }
1834
1835    static class DbBinder extends Binder {
1836        ActivityManagerService mActivityManagerService;
1837        DbBinder(ActivityManagerService activityManagerService) {
1838            mActivityManagerService = activityManagerService;
1839        }
1840
1841        @Override
1842        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1843            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1844                    != PackageManager.PERMISSION_GRANTED) {
1845                pw.println("Permission Denial: can't dump dbinfo from from pid="
1846                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1847                        + " without permission " + android.Manifest.permission.DUMP);
1848                return;
1849            }
1850
1851            mActivityManagerService.dumpDbInfo(fd, pw, args);
1852        }
1853    }
1854
1855    static class CpuBinder extends Binder {
1856        ActivityManagerService mActivityManagerService;
1857        CpuBinder(ActivityManagerService activityManagerService) {
1858            mActivityManagerService = activityManagerService;
1859        }
1860
1861        @Override
1862        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1863            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1864                    != PackageManager.PERMISSION_GRANTED) {
1865                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1866                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1867                        + " without permission " + android.Manifest.permission.DUMP);
1868                return;
1869            }
1870
1871            synchronized (mActivityManagerService.mProcessCpuThread) {
1872                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1873                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1874                        SystemClock.uptimeMillis()));
1875            }
1876        }
1877    }
1878
1879    public static class Lifecycle extends SystemService {
1880        private ActivityManagerService mService;
1881
1882        @Override
1883        public void onCreate(Context context) {
1884            mService = new ActivityManagerService(context);
1885        }
1886
1887        @Override
1888        public void onStart() {
1889            mService.start();
1890        }
1891    }
1892
1893    // Note: This method is invoked on the main thread but may need to attach various
1894    // handlers to other threads.  So take care to be explicit about the looper.
1895    public ActivityManagerService(Context systemContext) {
1896        sSelf = this;
1897        sSystemThread = ActivityThread.currentActivityThread();
1898
1899        mContext = systemContext;
1900        mFactoryTest = FactoryTest.getMode();
1901
1902        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1903
1904        mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND);
1905        mHandlerThread.start();
1906        mHandler = new MainHandler(mHandlerThread.getLooper());
1907
1908        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1909                "foreground", BROADCAST_FG_TIMEOUT, false);
1910        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1911                "background", BROADCAST_BG_TIMEOUT, true);
1912        mBroadcastQueues[0] = mFgBroadcastQueue;
1913        mBroadcastQueues[1] = mBgBroadcastQueue;
1914
1915        mServices = new ActiveServices(this);
1916        mProviderMap = new ProviderMap(this);
1917
1918        // TODO: Move creation of battery stats service outside of activity manager service.
1919        File dataDir = Environment.getDataDirectory();
1920        File systemDir = new File(dataDir, "system");
1921        systemDir.mkdirs();
1922        mBatteryStatsService = new BatteryStatsService(new File(
1923                systemDir, "batterystats.bin").toString(), mHandler);
1924        mBatteryStatsService.getActiveStatistics().readLocked();
1925        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1926        mOnBattery = DEBUG_POWER ? true
1927                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1928        mBatteryStatsService.getActiveStatistics().setCallback(this);
1929
1930        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1931
1932        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1933        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1934
1935        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1936
1937        // User 0 is the first and only user that runs at boot.
1938        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1939        mUserLru.add(Integer.valueOf(0));
1940        updateStartedUserArrayLocked();
1941
1942        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1943            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1944
1945        mConfiguration.setToDefaults();
1946        mConfiguration.setLocale(Locale.getDefault());
1947
1948        mConfigurationSeq = mConfiguration.seq = 1;
1949        mProcessCpuTracker.init();
1950
1951        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1952        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1953        mStackSupervisor = new ActivityStackSupervisor(this);
1954
1955        mProcessCpuThread = new Thread("CpuTracker") {
1956            @Override
1957            public void run() {
1958                while (true) {
1959                    try {
1960                        try {
1961                            synchronized(this) {
1962                                final long now = SystemClock.uptimeMillis();
1963                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1964                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1965                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1966                                //        + ", write delay=" + nextWriteDelay);
1967                                if (nextWriteDelay < nextCpuDelay) {
1968                                    nextCpuDelay = nextWriteDelay;
1969                                }
1970                                if (nextCpuDelay > 0) {
1971                                    mProcessCpuMutexFree.set(true);
1972                                    this.wait(nextCpuDelay);
1973                                }
1974                            }
1975                        } catch (InterruptedException e) {
1976                        }
1977                        updateCpuStatsNow();
1978                    } catch (Exception e) {
1979                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1980                    }
1981                }
1982            }
1983        };
1984
1985        Watchdog.getInstance().addMonitor(this);
1986        Watchdog.getInstance().addThread(mHandler);
1987    }
1988
1989    private void start() {
1990        mProcessCpuThread.start();
1991
1992        mBatteryStatsService.publish(mContext);
1993        mUsageStatsService.publish(mContext);
1994        mAppOpsService.publish(mContext);
1995        startRunning(null, null, null, null);
1996    }
1997
1998    @Override
1999    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2000            throws RemoteException {
2001        if (code == SYSPROPS_TRANSACTION) {
2002            // We need to tell all apps about the system property change.
2003            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2004            synchronized(this) {
2005                final int NP = mProcessNames.getMap().size();
2006                for (int ip=0; ip<NP; ip++) {
2007                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2008                    final int NA = apps.size();
2009                    for (int ia=0; ia<NA; ia++) {
2010                        ProcessRecord app = apps.valueAt(ia);
2011                        if (app.thread != null) {
2012                            procs.add(app.thread.asBinder());
2013                        }
2014                    }
2015                }
2016            }
2017
2018            int N = procs.size();
2019            for (int i=0; i<N; i++) {
2020                Parcel data2 = Parcel.obtain();
2021                try {
2022                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2023                } catch (RemoteException e) {
2024                }
2025                data2.recycle();
2026            }
2027        }
2028        try {
2029            return super.onTransact(code, data, reply, flags);
2030        } catch (RuntimeException e) {
2031            // The activity manager only throws security exceptions, so let's
2032            // log all others.
2033            if (!(e instanceof SecurityException)) {
2034                Slog.wtf(TAG, "Activity Manager Crash", e);
2035            }
2036            throw e;
2037        }
2038    }
2039
2040    void updateCpuStats() {
2041        final long now = SystemClock.uptimeMillis();
2042        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2043            return;
2044        }
2045        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2046            synchronized (mProcessCpuThread) {
2047                mProcessCpuThread.notify();
2048            }
2049        }
2050    }
2051
2052    void updateCpuStatsNow() {
2053        synchronized (mProcessCpuThread) {
2054            mProcessCpuMutexFree.set(false);
2055            final long now = SystemClock.uptimeMillis();
2056            boolean haveNewCpuStats = false;
2057
2058            if (MONITOR_CPU_USAGE &&
2059                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2060                mLastCpuTime.set(now);
2061                haveNewCpuStats = true;
2062                mProcessCpuTracker.update();
2063                //Slog.i(TAG, mProcessCpu.printCurrentState());
2064                //Slog.i(TAG, "Total CPU usage: "
2065                //        + mProcessCpu.getTotalCpuPercent() + "%");
2066
2067                // Slog the cpu usage if the property is set.
2068                if ("true".equals(SystemProperties.get("events.cpu"))) {
2069                    int user = mProcessCpuTracker.getLastUserTime();
2070                    int system = mProcessCpuTracker.getLastSystemTime();
2071                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2072                    int irq = mProcessCpuTracker.getLastIrqTime();
2073                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2074                    int idle = mProcessCpuTracker.getLastIdleTime();
2075
2076                    int total = user + system + iowait + irq + softIrq + idle;
2077                    if (total == 0) total = 1;
2078
2079                    EventLog.writeEvent(EventLogTags.CPU,
2080                            ((user+system+iowait+irq+softIrq) * 100) / total,
2081                            (user * 100) / total,
2082                            (system * 100) / total,
2083                            (iowait * 100) / total,
2084                            (irq * 100) / total,
2085                            (softIrq * 100) / total);
2086                }
2087            }
2088
2089            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2090            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2091            synchronized(bstats) {
2092                synchronized(mPidsSelfLocked) {
2093                    if (haveNewCpuStats) {
2094                        if (mOnBattery) {
2095                            int perc = bstats.startAddingCpuLocked();
2096                            int totalUTime = 0;
2097                            int totalSTime = 0;
2098                            final int N = mProcessCpuTracker.countStats();
2099                            for (int i=0; i<N; i++) {
2100                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2101                                if (!st.working) {
2102                                    continue;
2103                                }
2104                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2105                                int otherUTime = (st.rel_utime*perc)/100;
2106                                int otherSTime = (st.rel_stime*perc)/100;
2107                                totalUTime += otherUTime;
2108                                totalSTime += otherSTime;
2109                                if (pr != null) {
2110                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
2111                                            st.name, st.pid);
2112                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2113                                            st.rel_stime-otherSTime);
2114                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2115                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2116                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
2117                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2118                                    if (ps == null) {
2119                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
2120                                                "(Unknown)");
2121                                    }
2122                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2123                                            st.rel_stime-otherSTime);
2124                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2125                                } else {
2126                                    BatteryStatsImpl.Uid.Proc ps =
2127                                            bstats.getProcessStatsLocked(st.name, st.pid);
2128                                    if (ps != null) {
2129                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2130                                                st.rel_stime-otherSTime);
2131                                        ps.addSpeedStepTimes(cpuSpeedTimes);
2132                                    }
2133                                }
2134                            }
2135                            bstats.finishAddingCpuLocked(perc, totalUTime,
2136                                    totalSTime, cpuSpeedTimes);
2137                        }
2138                    }
2139                }
2140
2141                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2142                    mLastWriteTime = now;
2143                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2144                }
2145            }
2146        }
2147    }
2148
2149    @Override
2150    public void batteryNeedsCpuUpdate() {
2151        updateCpuStatsNow();
2152    }
2153
2154    @Override
2155    public void batteryPowerChanged(boolean onBattery) {
2156        // When plugging in, update the CPU stats first before changing
2157        // the plug state.
2158        updateCpuStatsNow();
2159        synchronized (this) {
2160            synchronized(mPidsSelfLocked) {
2161                mOnBattery = DEBUG_POWER ? true : onBattery;
2162            }
2163        }
2164    }
2165
2166    /**
2167     * Initialize the application bind args. These are passed to each
2168     * process when the bindApplication() IPC is sent to the process. They're
2169     * lazily setup to make sure the services are running when they're asked for.
2170     */
2171    private HashMap<String, IBinder> getCommonServicesLocked() {
2172        if (mAppBindArgs == null) {
2173            mAppBindArgs = new HashMap<String, IBinder>();
2174
2175            // Setup the application init args
2176            mAppBindArgs.put("package", ServiceManager.getService("package"));
2177            mAppBindArgs.put("window", ServiceManager.getService("window"));
2178            mAppBindArgs.put(Context.ALARM_SERVICE,
2179                    ServiceManager.getService(Context.ALARM_SERVICE));
2180        }
2181        return mAppBindArgs;
2182    }
2183
2184    final void setFocusedActivityLocked(ActivityRecord r) {
2185        if (mFocusedActivity != r) {
2186            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2187            mFocusedActivity = r;
2188            mStackSupervisor.setFocusedStack(r);
2189            if (r != null) {
2190                mWindowManager.setFocusedApp(r.appToken, true);
2191            }
2192            applyUpdateLockStateLocked(r);
2193        }
2194    }
2195
2196    @Override
2197    public void setFocusedStack(int stackId) {
2198        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2199        synchronized (ActivityManagerService.this) {
2200            ActivityStack stack = mStackSupervisor.getStack(stackId);
2201            if (stack != null) {
2202                ActivityRecord r = stack.topRunningActivityLocked(null);
2203                if (r != null) {
2204                    setFocusedActivityLocked(r);
2205                }
2206            }
2207        }
2208    }
2209
2210    @Override
2211    public void notifyActivityDrawn(IBinder token) {
2212        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2213        synchronized (this) {
2214            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2215            if (r != null) {
2216                r.task.stack.notifyActivityDrawnLocked(r);
2217            }
2218        }
2219    }
2220
2221    final void applyUpdateLockStateLocked(ActivityRecord r) {
2222        // Modifications to the UpdateLock state are done on our handler, outside
2223        // the activity manager's locks.  The new state is determined based on the
2224        // state *now* of the relevant activity record.  The object is passed to
2225        // the handler solely for logging detail, not to be consulted/modified.
2226        final boolean nextState = r != null && r.immersive;
2227        mHandler.sendMessage(
2228                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2229    }
2230
2231    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2232        Message msg = Message.obtain();
2233        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2234        msg.obj = r.task.askedCompatMode ? null : r;
2235        mHandler.sendMessage(msg);
2236    }
2237
2238    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2239            String what, Object obj, ProcessRecord srcApp) {
2240        app.lastActivityTime = now;
2241
2242        if (app.activities.size() > 0) {
2243            // Don't want to touch dependent processes that are hosting activities.
2244            return index;
2245        }
2246
2247        int lrui = mLruProcesses.lastIndexOf(app);
2248        if (lrui < 0) {
2249            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2250                    + what + " " + obj + " from " + srcApp);
2251            return index;
2252        }
2253
2254        if (lrui >= index) {
2255            // Don't want to cause this to move dependent processes *back* in the
2256            // list as if they were less frequently used.
2257            return index;
2258        }
2259
2260        if (lrui >= mLruProcessActivityStart) {
2261            // Don't want to touch dependent processes that are hosting activities.
2262            return index;
2263        }
2264
2265        mLruProcesses.remove(lrui);
2266        if (index > 0) {
2267            index--;
2268        }
2269        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2270                + " in LRU list: " + app);
2271        mLruProcesses.add(index, app);
2272        return index;
2273    }
2274
2275    final void removeLruProcessLocked(ProcessRecord app) {
2276        int lrui = mLruProcesses.lastIndexOf(app);
2277        if (lrui >= 0) {
2278            if (lrui <= mLruProcessActivityStart) {
2279                mLruProcessActivityStart--;
2280            }
2281            if (lrui <= mLruProcessServiceStart) {
2282                mLruProcessServiceStart--;
2283            }
2284            mLruProcesses.remove(lrui);
2285        }
2286    }
2287
2288    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2289            ProcessRecord client) {
2290        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2291        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2292        if (!activityChange && hasActivity) {
2293            // The process has activties, so we are only going to allow activity-based
2294            // adjustments move it.  It should be kept in the front of the list with other
2295            // processes that have activities, and we don't want those to change their
2296            // order except due to activity operations.
2297            return;
2298        }
2299
2300        mLruSeq++;
2301        final long now = SystemClock.uptimeMillis();
2302        app.lastActivityTime = now;
2303
2304        // First a quick reject: if the app is already at the position we will
2305        // put it, then there is nothing to do.
2306        if (hasActivity) {
2307            final int N = mLruProcesses.size();
2308            if (N > 0 && mLruProcesses.get(N-1) == app) {
2309                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2310                return;
2311            }
2312        } else {
2313            if (mLruProcessServiceStart > 0
2314                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2315                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2316                return;
2317            }
2318        }
2319
2320        int lrui = mLruProcesses.lastIndexOf(app);
2321
2322        if (app.persistent && lrui >= 0) {
2323            // We don't care about the position of persistent processes, as long as
2324            // they are in the list.
2325            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2326            return;
2327        }
2328
2329        /* In progress: compute new position first, so we can avoid doing work
2330           if the process is not actually going to move.  Not yet working.
2331        int addIndex;
2332        int nextIndex;
2333        boolean inActivity = false, inService = false;
2334        if (hasActivity) {
2335            // Process has activities, put it at the very tipsy-top.
2336            addIndex = mLruProcesses.size();
2337            nextIndex = mLruProcessServiceStart;
2338            inActivity = true;
2339        } else if (hasService) {
2340            // Process has services, put it at the top of the service list.
2341            addIndex = mLruProcessActivityStart;
2342            nextIndex = mLruProcessServiceStart;
2343            inActivity = true;
2344            inService = true;
2345        } else  {
2346            // Process not otherwise of interest, it goes to the top of the non-service area.
2347            addIndex = mLruProcessServiceStart;
2348            if (client != null) {
2349                int clientIndex = mLruProcesses.lastIndexOf(client);
2350                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2351                        + app);
2352                if (clientIndex >= 0 && addIndex > clientIndex) {
2353                    addIndex = clientIndex;
2354                }
2355            }
2356            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2357        }
2358
2359        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2360                + mLruProcessActivityStart + "): " + app);
2361        */
2362
2363        if (lrui >= 0) {
2364            if (lrui < mLruProcessActivityStart) {
2365                mLruProcessActivityStart--;
2366            }
2367            if (lrui < mLruProcessServiceStart) {
2368                mLruProcessServiceStart--;
2369            }
2370            /*
2371            if (addIndex > lrui) {
2372                addIndex--;
2373            }
2374            if (nextIndex > lrui) {
2375                nextIndex--;
2376            }
2377            */
2378            mLruProcesses.remove(lrui);
2379        }
2380
2381        /*
2382        mLruProcesses.add(addIndex, app);
2383        if (inActivity) {
2384            mLruProcessActivityStart++;
2385        }
2386        if (inService) {
2387            mLruProcessActivityStart++;
2388        }
2389        */
2390
2391        int nextIndex;
2392        if (hasActivity) {
2393            final int N = mLruProcesses.size();
2394            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2395                // Process doesn't have activities, but has clients with
2396                // activities...  move it up, but one below the top (the top
2397                // should always have a real activity).
2398                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2399                mLruProcesses.add(N-1, app);
2400                // To keep it from spamming the LRU list (by making a bunch of clients),
2401                // we will push down any other entries owned by the app.
2402                final int uid = app.info.uid;
2403                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2404                    ProcessRecord subProc = mLruProcesses.get(i);
2405                    if (subProc.info.uid == uid) {
2406                        // We want to push this one down the list.  If the process after
2407                        // it is for the same uid, however, don't do so, because we don't
2408                        // want them internally to be re-ordered.
2409                        if (mLruProcesses.get(i-1).info.uid != uid) {
2410                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2411                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2412                            ProcessRecord tmp = mLruProcesses.get(i);
2413                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2414                            mLruProcesses.set(i-1, tmp);
2415                            i--;
2416                        }
2417                    } else {
2418                        // A gap, we can stop here.
2419                        break;
2420                    }
2421                }
2422            } else {
2423                // Process has activities, put it at the very tipsy-top.
2424                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2425                mLruProcesses.add(app);
2426            }
2427            nextIndex = mLruProcessServiceStart;
2428        } else if (hasService) {
2429            // Process has services, put it at the top of the service list.
2430            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2431            mLruProcesses.add(mLruProcessActivityStart, app);
2432            nextIndex = mLruProcessServiceStart;
2433            mLruProcessActivityStart++;
2434        } else  {
2435            // Process not otherwise of interest, it goes to the top of the non-service area.
2436            int index = mLruProcessServiceStart;
2437            if (client != null) {
2438                // If there is a client, don't allow the process to be moved up higher
2439                // in the list than that client.
2440                int clientIndex = mLruProcesses.lastIndexOf(client);
2441                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2442                        + " when updating " + app);
2443                if (clientIndex <= lrui) {
2444                    // Don't allow the client index restriction to push it down farther in the
2445                    // list than it already is.
2446                    clientIndex = lrui;
2447                }
2448                if (clientIndex >= 0 && index > clientIndex) {
2449                    index = clientIndex;
2450                }
2451            }
2452            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2453            mLruProcesses.add(index, app);
2454            nextIndex = index-1;
2455            mLruProcessActivityStart++;
2456            mLruProcessServiceStart++;
2457        }
2458
2459        // If the app is currently using a content provider or service,
2460        // bump those processes as well.
2461        for (int j=app.connections.size()-1; j>=0; j--) {
2462            ConnectionRecord cr = app.connections.valueAt(j);
2463            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2464                    && cr.binding.service.app != null
2465                    && cr.binding.service.app.lruSeq != mLruSeq
2466                    && !cr.binding.service.app.persistent) {
2467                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2468                        "service connection", cr, app);
2469            }
2470        }
2471        for (int j=app.conProviders.size()-1; j>=0; j--) {
2472            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2473            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2474                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2475                        "provider reference", cpr, app);
2476            }
2477        }
2478    }
2479
2480    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2481        if (uid == Process.SYSTEM_UID) {
2482            // The system gets to run in any process.  If there are multiple
2483            // processes with the same uid, just pick the first (this
2484            // should never happen).
2485            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2486            if (procs == null) return null;
2487            final int N = procs.size();
2488            for (int i = 0; i < N; i++) {
2489                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2490            }
2491        }
2492        ProcessRecord proc = mProcessNames.get(processName, uid);
2493        if (false && proc != null && !keepIfLarge
2494                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2495                && proc.lastCachedPss >= 4000) {
2496            // Turn this condition on to cause killing to happen regularly, for testing.
2497            if (proc.baseProcessTracker != null) {
2498                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2499            }
2500            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2501                    + "k from cached");
2502        } else if (proc != null && !keepIfLarge
2503                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2504                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2505            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2506            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2507                if (proc.baseProcessTracker != null) {
2508                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2509                }
2510                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2511                        + "k from cached");
2512            }
2513        }
2514        return proc;
2515    }
2516
2517    void ensurePackageDexOpt(String packageName) {
2518        IPackageManager pm = AppGlobals.getPackageManager();
2519        try {
2520            if (pm.performDexOpt(packageName)) {
2521                mDidDexOpt = true;
2522            }
2523        } catch (RemoteException e) {
2524        }
2525    }
2526
2527    boolean isNextTransitionForward() {
2528        int transit = mWindowManager.getPendingAppTransition();
2529        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2530                || transit == AppTransition.TRANSIT_TASK_OPEN
2531                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2532    }
2533
2534    final ProcessRecord startProcessLocked(String processName,
2535            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2536            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2537            boolean isolated, boolean keepIfLarge) {
2538        ProcessRecord app;
2539        if (!isolated) {
2540            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2541        } else {
2542            // If this is an isolated process, it can't re-use an existing process.
2543            app = null;
2544        }
2545        // We don't have to do anything more if:
2546        // (1) There is an existing application record; and
2547        // (2) The caller doesn't think it is dead, OR there is no thread
2548        //     object attached to it so we know it couldn't have crashed; and
2549        // (3) There is a pid assigned to it, so it is either starting or
2550        //     already running.
2551        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2552                + " app=" + app + " knownToBeDead=" + knownToBeDead
2553                + " thread=" + (app != null ? app.thread : null)
2554                + " pid=" + (app != null ? app.pid : -1));
2555        if (app != null && app.pid > 0) {
2556            if (!knownToBeDead || app.thread == null) {
2557                // We already have the app running, or are waiting for it to
2558                // come up (we have a pid but not yet its thread), so keep it.
2559                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2560                // If this is a new package in the process, add the package to the list
2561                app.addPackage(info.packageName, mProcessStats);
2562                return app;
2563            }
2564
2565            // An application record is attached to a previous process,
2566            // clean it up now.
2567            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2568            handleAppDiedLocked(app, true, true);
2569        }
2570
2571        String hostingNameStr = hostingName != null
2572                ? hostingName.flattenToShortString() : null;
2573
2574        if (!isolated) {
2575            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2576                // If we are in the background, then check to see if this process
2577                // is bad.  If so, we will just silently fail.
2578                if (mBadProcesses.get(info.processName, info.uid) != null) {
2579                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2580                            + "/" + info.processName);
2581                    return null;
2582                }
2583            } else {
2584                // When the user is explicitly starting a process, then clear its
2585                // crash count so that we won't make it bad until they see at
2586                // least one crash dialog again, and make the process good again
2587                // if it had been bad.
2588                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2589                        + "/" + info.processName);
2590                mProcessCrashTimes.remove(info.processName, info.uid);
2591                if (mBadProcesses.get(info.processName, info.uid) != null) {
2592                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2593                            UserHandle.getUserId(info.uid), info.uid,
2594                            info.processName);
2595                    mBadProcesses.remove(info.processName, info.uid);
2596                    if (app != null) {
2597                        app.bad = false;
2598                    }
2599                }
2600            }
2601        }
2602
2603        if (app == null) {
2604            app = newProcessRecordLocked(info, processName, isolated);
2605            if (app == null) {
2606                Slog.w(TAG, "Failed making new process record for "
2607                        + processName + "/" + info.uid + " isolated=" + isolated);
2608                return null;
2609            }
2610            mProcessNames.put(processName, app.uid, app);
2611            if (isolated) {
2612                mIsolatedProcesses.put(app.uid, app);
2613            }
2614        } else {
2615            // If this is a new package in the process, add the package to the list
2616            app.addPackage(info.packageName, mProcessStats);
2617        }
2618
2619        // If the system is not ready yet, then hold off on starting this
2620        // process until it is.
2621        if (!mProcessesReady
2622                && !isAllowedWhileBooting(info)
2623                && !allowWhileBooting) {
2624            if (!mProcessesOnHold.contains(app)) {
2625                mProcessesOnHold.add(app);
2626            }
2627            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2628            return app;
2629        }
2630
2631        startProcessLocked(app, hostingType, hostingNameStr);
2632        return (app.pid != 0) ? app : null;
2633    }
2634
2635    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2636        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2637    }
2638
2639    private final void startProcessLocked(ProcessRecord app,
2640            String hostingType, String hostingNameStr) {
2641        if (app.pid > 0 && app.pid != MY_PID) {
2642            synchronized (mPidsSelfLocked) {
2643                mPidsSelfLocked.remove(app.pid);
2644                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2645            }
2646            app.setPid(0);
2647        }
2648
2649        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2650                "startProcessLocked removing on hold: " + app);
2651        mProcessesOnHold.remove(app);
2652
2653        updateCpuStats();
2654
2655        try {
2656            int uid = app.uid;
2657
2658            int[] gids = null;
2659            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2660            if (!app.isolated) {
2661                int[] permGids = null;
2662                try {
2663                    final PackageManager pm = mContext.getPackageManager();
2664                    permGids = pm.getPackageGids(app.info.packageName);
2665
2666                    if (Environment.isExternalStorageEmulated()) {
2667                        if (pm.checkPermission(
2668                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2669                                app.info.packageName) == PERMISSION_GRANTED) {
2670                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2671                        } else {
2672                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2673                        }
2674                    }
2675                } catch (PackageManager.NameNotFoundException e) {
2676                    Slog.w(TAG, "Unable to retrieve gids", e);
2677                }
2678
2679                /*
2680                 * Add shared application GID so applications can share some
2681                 * resources like shared libraries
2682                 */
2683                if (permGids == null) {
2684                    gids = new int[1];
2685                } else {
2686                    gids = new int[permGids.length + 1];
2687                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2688                }
2689                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2690            }
2691            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2692                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2693                        && mTopComponent != null
2694                        && app.processName.equals(mTopComponent.getPackageName())) {
2695                    uid = 0;
2696                }
2697                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2698                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2699                    uid = 0;
2700                }
2701            }
2702            int debugFlags = 0;
2703            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2704                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2705                // Also turn on CheckJNI for debuggable apps. It's quite
2706                // awkward to turn on otherwise.
2707                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2708            }
2709            // Run the app in safe mode if its manifest requests so or the
2710            // system is booted in safe mode.
2711            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2712                Zygote.systemInSafeMode == true) {
2713                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2714            }
2715            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2716                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2717            }
2718            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2719                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2720            }
2721            if ("1".equals(SystemProperties.get("debug.assert"))) {
2722                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2723            }
2724
2725            // Start the process.  It will either succeed and return a result containing
2726            // the PID of the new process, or else throw a RuntimeException.
2727            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2728                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2729                    app.info.targetSdkVersion, app.info.seinfo, null);
2730
2731            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2732            synchronized (bs) {
2733                if (bs.isOnBattery()) {
2734                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2735                }
2736            }
2737
2738            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2739                    UserHandle.getUserId(uid), startResult.pid, uid,
2740                    app.processName, hostingType,
2741                    hostingNameStr != null ? hostingNameStr : "");
2742
2743            if (app.persistent) {
2744                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2745            }
2746
2747            StringBuilder buf = mStringBuilder;
2748            buf.setLength(0);
2749            buf.append("Start proc ");
2750            buf.append(app.processName);
2751            buf.append(" for ");
2752            buf.append(hostingType);
2753            if (hostingNameStr != null) {
2754                buf.append(" ");
2755                buf.append(hostingNameStr);
2756            }
2757            buf.append(": pid=");
2758            buf.append(startResult.pid);
2759            buf.append(" uid=");
2760            buf.append(uid);
2761            buf.append(" gids={");
2762            if (gids != null) {
2763                for (int gi=0; gi<gids.length; gi++) {
2764                    if (gi != 0) buf.append(", ");
2765                    buf.append(gids[gi]);
2766
2767                }
2768            }
2769            buf.append("}");
2770            Slog.i(TAG, buf.toString());
2771            app.setPid(startResult.pid);
2772            app.usingWrapper = startResult.usingWrapper;
2773            app.removed = false;
2774            synchronized (mPidsSelfLocked) {
2775                this.mPidsSelfLocked.put(startResult.pid, app);
2776                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2777                msg.obj = app;
2778                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2779                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2780            }
2781        } catch (RuntimeException e) {
2782            // XXX do better error recovery.
2783            app.setPid(0);
2784            Slog.e(TAG, "Failure starting process " + app.processName, e);
2785        }
2786    }
2787
2788    void updateUsageStats(ActivityRecord component, boolean resumed) {
2789        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2790        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2791        if (resumed) {
2792            mUsageStatsService.noteResumeComponent(component.realActivity);
2793            synchronized (stats) {
2794                stats.noteActivityResumedLocked(component.app.uid);
2795            }
2796        } else {
2797            mUsageStatsService.notePauseComponent(component.realActivity);
2798            synchronized (stats) {
2799                stats.noteActivityPausedLocked(component.app.uid);
2800            }
2801        }
2802    }
2803
2804    Intent getHomeIntent() {
2805        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2806        intent.setComponent(mTopComponent);
2807        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2808            intent.addCategory(Intent.CATEGORY_HOME);
2809        }
2810        return intent;
2811    }
2812
2813    boolean startHomeActivityLocked(int userId) {
2814        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2815                && mTopAction == null) {
2816            // We are running in factory test mode, but unable to find
2817            // the factory test app, so just sit around displaying the
2818            // error message and don't try to start anything.
2819            return false;
2820        }
2821        Intent intent = getHomeIntent();
2822        ActivityInfo aInfo =
2823            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2824        if (aInfo != null) {
2825            intent.setComponent(new ComponentName(
2826                    aInfo.applicationInfo.packageName, aInfo.name));
2827            // Don't do this if the home app is currently being
2828            // instrumented.
2829            aInfo = new ActivityInfo(aInfo);
2830            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2831            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2832                    aInfo.applicationInfo.uid, true);
2833            if (app == null || app.instrumentationClass == null) {
2834                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2835                mStackSupervisor.startHomeActivity(intent, aInfo);
2836            }
2837        }
2838
2839        return true;
2840    }
2841
2842    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2843        ActivityInfo ai = null;
2844        ComponentName comp = intent.getComponent();
2845        try {
2846            if (comp != null) {
2847                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2848            } else {
2849                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2850                        intent,
2851                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2852                            flags, userId);
2853
2854                if (info != null) {
2855                    ai = info.activityInfo;
2856                }
2857            }
2858        } catch (RemoteException e) {
2859            // ignore
2860        }
2861
2862        return ai;
2863    }
2864
2865    /**
2866     * Starts the "new version setup screen" if appropriate.
2867     */
2868    void startSetupActivityLocked() {
2869        // Only do this once per boot.
2870        if (mCheckedForSetup) {
2871            return;
2872        }
2873
2874        // We will show this screen if the current one is a different
2875        // version than the last one shown, and we are not running in
2876        // low-level factory test mode.
2877        final ContentResolver resolver = mContext.getContentResolver();
2878        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2879                Settings.Global.getInt(resolver,
2880                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2881            mCheckedForSetup = true;
2882
2883            // See if we should be showing the platform update setup UI.
2884            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2885            List<ResolveInfo> ris = sSelf.mContext.getPackageManager()
2886                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2887
2888            // We don't allow third party apps to replace this.
2889            ResolveInfo ri = null;
2890            for (int i=0; ris != null && i<ris.size(); i++) {
2891                if ((ris.get(i).activityInfo.applicationInfo.flags
2892                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2893                    ri = ris.get(i);
2894                    break;
2895                }
2896            }
2897
2898            if (ri != null) {
2899                String vers = ri.activityInfo.metaData != null
2900                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2901                        : null;
2902                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2903                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2904                            Intent.METADATA_SETUP_VERSION);
2905                }
2906                String lastVers = Settings.Secure.getString(
2907                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2908                if (vers != null && !vers.equals(lastVers)) {
2909                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2910                    intent.setComponent(new ComponentName(
2911                            ri.activityInfo.packageName, ri.activityInfo.name));
2912                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2913                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2914                }
2915            }
2916        }
2917    }
2918
2919    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2920        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2921    }
2922
2923    void enforceNotIsolatedCaller(String caller) {
2924        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2925            throw new SecurityException("Isolated process not allowed to call " + caller);
2926        }
2927    }
2928
2929    @Override
2930    public int getFrontActivityScreenCompatMode() {
2931        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2932        synchronized (this) {
2933            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2934        }
2935    }
2936
2937    @Override
2938    public void setFrontActivityScreenCompatMode(int mode) {
2939        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2940                "setFrontActivityScreenCompatMode");
2941        synchronized (this) {
2942            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2943        }
2944    }
2945
2946    @Override
2947    public int getPackageScreenCompatMode(String packageName) {
2948        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2949        synchronized (this) {
2950            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2951        }
2952    }
2953
2954    @Override
2955    public void setPackageScreenCompatMode(String packageName, int mode) {
2956        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2957                "setPackageScreenCompatMode");
2958        synchronized (this) {
2959            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2960        }
2961    }
2962
2963    @Override
2964    public boolean getPackageAskScreenCompat(String packageName) {
2965        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2966        synchronized (this) {
2967            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2968        }
2969    }
2970
2971    @Override
2972    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2973        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2974                "setPackageAskScreenCompat");
2975        synchronized (this) {
2976            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2977        }
2978    }
2979
2980    private void dispatchProcessesChanged() {
2981        int N;
2982        synchronized (this) {
2983            N = mPendingProcessChanges.size();
2984            if (mActiveProcessChanges.length < N) {
2985                mActiveProcessChanges = new ProcessChangeItem[N];
2986            }
2987            mPendingProcessChanges.toArray(mActiveProcessChanges);
2988            mAvailProcessChanges.addAll(mPendingProcessChanges);
2989            mPendingProcessChanges.clear();
2990            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2991        }
2992
2993        int i = mProcessObservers.beginBroadcast();
2994        while (i > 0) {
2995            i--;
2996            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2997            if (observer != null) {
2998                try {
2999                    for (int j=0; j<N; j++) {
3000                        ProcessChangeItem item = mActiveProcessChanges[j];
3001                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3002                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3003                                    + item.pid + " uid=" + item.uid + ": "
3004                                    + item.foregroundActivities);
3005                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3006                                    item.foregroundActivities);
3007                        }
3008                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3009                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3010                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3011                            observer.onImportanceChanged(item.pid, item.uid,
3012                                    item.importance);
3013                        }
3014                    }
3015                } catch (RemoteException e) {
3016                }
3017            }
3018        }
3019        mProcessObservers.finishBroadcast();
3020    }
3021
3022    private void dispatchProcessDied(int pid, int uid) {
3023        int i = mProcessObservers.beginBroadcast();
3024        while (i > 0) {
3025            i--;
3026            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3027            if (observer != null) {
3028                try {
3029                    observer.onProcessDied(pid, uid);
3030                } catch (RemoteException e) {
3031                }
3032            }
3033        }
3034        mProcessObservers.finishBroadcast();
3035    }
3036
3037    final void doPendingActivityLaunchesLocked(boolean doResume) {
3038        final int N = mPendingActivityLaunches.size();
3039        if (N <= 0) {
3040            return;
3041        }
3042        for (int i=0; i<N; i++) {
3043            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3044            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3045                    doResume && i == (N-1), null);
3046        }
3047        mPendingActivityLaunches.clear();
3048    }
3049
3050    @Override
3051    public final int startActivity(IApplicationThread caller, String callingPackage,
3052            Intent intent, String resolvedType, IBinder resultTo,
3053            String resultWho, int requestCode, int startFlags,
3054            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3055        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3056                resultWho, requestCode,
3057                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3058    }
3059
3060    @Override
3061    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3062            Intent intent, String resolvedType, IBinder resultTo,
3063            String resultWho, int requestCode, int startFlags,
3064            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3065        enforceNotIsolatedCaller("startActivity");
3066        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3067                false, true, "startActivity", null);
3068        // TODO: Switch to user app stacks here.
3069        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3070                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3071                null, null, options, userId, null);
3072    }
3073
3074    @Override
3075    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3076            Intent intent, String resolvedType, IBinder resultTo,
3077            String resultWho, int requestCode, int startFlags, String profileFile,
3078            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3079        enforceNotIsolatedCaller("startActivityAndWait");
3080        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3081                false, true, "startActivityAndWait", null);
3082        WaitResult res = new WaitResult();
3083        // TODO: Switch to user app stacks here.
3084        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3085                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3086                res, null, options, UserHandle.getCallingUserId(), null);
3087        return res;
3088    }
3089
3090    @Override
3091    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3092            Intent intent, String resolvedType, IBinder resultTo,
3093            String resultWho, int requestCode, int startFlags, Configuration config,
3094            Bundle options, int userId) {
3095        enforceNotIsolatedCaller("startActivityWithConfig");
3096        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3097                false, true, "startActivityWithConfig", null);
3098        // TODO: Switch to user app stacks here.
3099        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3100                resolvedType, resultTo, resultWho, requestCode, startFlags,
3101                null, null, null, config, options, userId, null);
3102        return ret;
3103    }
3104
3105    @Override
3106    public int startActivityIntentSender(IApplicationThread caller,
3107            IntentSender intent, Intent fillInIntent, String resolvedType,
3108            IBinder resultTo, String resultWho, int requestCode,
3109            int flagsMask, int flagsValues, Bundle options) {
3110        enforceNotIsolatedCaller("startActivityIntentSender");
3111        // Refuse possible leaked file descriptors
3112        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3113            throw new IllegalArgumentException("File descriptors passed in Intent");
3114        }
3115
3116        IIntentSender sender = intent.getTarget();
3117        if (!(sender instanceof PendingIntentRecord)) {
3118            throw new IllegalArgumentException("Bad PendingIntent object");
3119        }
3120
3121        PendingIntentRecord pir = (PendingIntentRecord)sender;
3122
3123        synchronized (this) {
3124            // If this is coming from the currently resumed activity, it is
3125            // effectively saying that app switches are allowed at this point.
3126            final ActivityStack stack = getFocusedStack();
3127            if (stack.mResumedActivity != null &&
3128                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3129                mAppSwitchesAllowedTime = 0;
3130            }
3131        }
3132        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3133                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
3134        return ret;
3135    }
3136
3137    @Override
3138    public boolean startNextMatchingActivity(IBinder callingActivity,
3139            Intent intent, Bundle options) {
3140        // Refuse possible leaked file descriptors
3141        if (intent != null && intent.hasFileDescriptors() == true) {
3142            throw new IllegalArgumentException("File descriptors passed in Intent");
3143        }
3144
3145        synchronized (this) {
3146            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3147            if (r == null) {
3148                ActivityOptions.abort(options);
3149                return false;
3150            }
3151            if (r.app == null || r.app.thread == null) {
3152                // The caller is not running...  d'oh!
3153                ActivityOptions.abort(options);
3154                return false;
3155            }
3156            intent = new Intent(intent);
3157            // The caller is not allowed to change the data.
3158            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3159            // And we are resetting to find the next component...
3160            intent.setComponent(null);
3161
3162            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3163
3164            ActivityInfo aInfo = null;
3165            try {
3166                List<ResolveInfo> resolves =
3167                    AppGlobals.getPackageManager().queryIntentActivities(
3168                            intent, r.resolvedType,
3169                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3170                            UserHandle.getCallingUserId());
3171
3172                // Look for the original activity in the list...
3173                final int N = resolves != null ? resolves.size() : 0;
3174                for (int i=0; i<N; i++) {
3175                    ResolveInfo rInfo = resolves.get(i);
3176                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3177                            && rInfo.activityInfo.name.equals(r.info.name)) {
3178                        // We found the current one...  the next matching is
3179                        // after it.
3180                        i++;
3181                        if (i<N) {
3182                            aInfo = resolves.get(i).activityInfo;
3183                        }
3184                        if (debug) {
3185                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3186                                    + "/" + r.info.name);
3187                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3188                                    + "/" + aInfo.name);
3189                        }
3190                        break;
3191                    }
3192                }
3193            } catch (RemoteException e) {
3194            }
3195
3196            if (aInfo == null) {
3197                // Nobody who is next!
3198                ActivityOptions.abort(options);
3199                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3200                return false;
3201            }
3202
3203            intent.setComponent(new ComponentName(
3204                    aInfo.applicationInfo.packageName, aInfo.name));
3205            intent.setFlags(intent.getFlags()&~(
3206                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3207                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3208                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3209                    Intent.FLAG_ACTIVITY_NEW_TASK));
3210
3211            // Okay now we need to start the new activity, replacing the
3212            // currently running activity.  This is a little tricky because
3213            // we want to start the new one as if the current one is finished,
3214            // but not finish the current one first so that there is no flicker.
3215            // And thus...
3216            final boolean wasFinishing = r.finishing;
3217            r.finishing = true;
3218
3219            // Propagate reply information over to the new activity.
3220            final ActivityRecord resultTo = r.resultTo;
3221            final String resultWho = r.resultWho;
3222            final int requestCode = r.requestCode;
3223            r.resultTo = null;
3224            if (resultTo != null) {
3225                resultTo.removeResultsLocked(r, resultWho, requestCode);
3226            }
3227
3228            final long origId = Binder.clearCallingIdentity();
3229            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3230                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3231                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3232                    options, false, null, null);
3233            Binder.restoreCallingIdentity(origId);
3234
3235            r.finishing = wasFinishing;
3236            if (res != ActivityManager.START_SUCCESS) {
3237                return false;
3238            }
3239            return true;
3240        }
3241    }
3242
3243    final int startActivityInPackage(int uid, String callingPackage,
3244            Intent intent, String resolvedType, IBinder resultTo,
3245            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
3246
3247        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3248                false, true, "startActivityInPackage", null);
3249
3250        // TODO: Switch to user app stacks here.
3251        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3252                resultTo, resultWho, requestCode, startFlags,
3253                null, null, null, null, options, userId, null);
3254        return ret;
3255    }
3256
3257    @Override
3258    public final int startActivities(IApplicationThread caller, String callingPackage,
3259            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3260            int userId) {
3261        enforceNotIsolatedCaller("startActivities");
3262        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3263                false, true, "startActivity", null);
3264        // TODO: Switch to user app stacks here.
3265        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3266                resolvedTypes, resultTo, options, userId);
3267        return ret;
3268    }
3269
3270    final int startActivitiesInPackage(int uid, String callingPackage,
3271            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3272            Bundle options, int userId) {
3273
3274        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3275                false, true, "startActivityInPackage", null);
3276        // TODO: Switch to user app stacks here.
3277        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3278                resultTo, options, userId);
3279        return ret;
3280    }
3281
3282    final void addRecentTaskLocked(TaskRecord task) {
3283        int N = mRecentTasks.size();
3284        // Quick case: check if the top-most recent task is the same.
3285        if (N > 0 && mRecentTasks.get(0) == task) {
3286            return;
3287        }
3288        // Remove any existing entries that are the same kind of task.
3289        for (int i=0; i<N; i++) {
3290            TaskRecord tr = mRecentTasks.get(i);
3291            if (task.userId == tr.userId
3292                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3293                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3294                tr.disposeThumbnail();
3295                mRecentTasks.remove(i);
3296                i--;
3297                N--;
3298                if (task.intent == null) {
3299                    // If the new recent task we are adding is not fully
3300                    // specified, then replace it with the existing recent task.
3301                    task = tr;
3302                }
3303            }
3304        }
3305        if (N >= MAX_RECENT_TASKS) {
3306            mRecentTasks.remove(N-1).disposeThumbnail();
3307        }
3308        mRecentTasks.add(0, task);
3309    }
3310
3311    @Override
3312    public void reportActivityFullyDrawn(IBinder token) {
3313        synchronized (this) {
3314            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3315            if (r == null) {
3316                return;
3317            }
3318            r.reportFullyDrawnLocked();
3319        }
3320    }
3321
3322    @Override
3323    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3324        synchronized (this) {
3325            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3326            if (r == null) {
3327                return;
3328            }
3329            final long origId = Binder.clearCallingIdentity();
3330            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3331            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3332                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3333            if (config != null) {
3334                r.frozenBeforeDestroy = true;
3335                if (!updateConfigurationLocked(config, r, false, false)) {
3336                    mStackSupervisor.resumeTopActivitiesLocked();
3337                }
3338            }
3339            Binder.restoreCallingIdentity(origId);
3340        }
3341    }
3342
3343    @Override
3344    public int getRequestedOrientation(IBinder token) {
3345        synchronized (this) {
3346            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3347            if (r == null) {
3348                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3349            }
3350            return mWindowManager.getAppOrientation(r.appToken);
3351        }
3352    }
3353
3354    /**
3355     * This is the internal entry point for handling Activity.finish().
3356     *
3357     * @param token The Binder token referencing the Activity we want to finish.
3358     * @param resultCode Result code, if any, from this Activity.
3359     * @param resultData Result data (Intent), if any, from this Activity.
3360     *
3361     * @return Returns true if the activity successfully finished, or false if it is still running.
3362     */
3363    @Override
3364    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3365        // Refuse possible leaked file descriptors
3366        if (resultData != null && resultData.hasFileDescriptors() == true) {
3367            throw new IllegalArgumentException("File descriptors passed in Intent");
3368        }
3369
3370        synchronized(this) {
3371            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3372            if (r == null) {
3373                return true;
3374            }
3375            if (mController != null) {
3376                // Find the first activity that is not finishing.
3377                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3378                if (next != null) {
3379                    // ask watcher if this is allowed
3380                    boolean resumeOK = true;
3381                    try {
3382                        resumeOK = mController.activityResuming(next.packageName);
3383                    } catch (RemoteException e) {
3384                        mController = null;
3385                        Watchdog.getInstance().setActivityController(null);
3386                    }
3387
3388                    if (!resumeOK) {
3389                        return false;
3390                    }
3391                }
3392            }
3393            final long origId = Binder.clearCallingIdentity();
3394            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3395                    resultData, "app-request", true);
3396            Binder.restoreCallingIdentity(origId);
3397            return res;
3398        }
3399    }
3400
3401    @Override
3402    public final void finishHeavyWeightApp() {
3403        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3404                != PackageManager.PERMISSION_GRANTED) {
3405            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3406                    + Binder.getCallingPid()
3407                    + ", uid=" + Binder.getCallingUid()
3408                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3409            Slog.w(TAG, msg);
3410            throw new SecurityException(msg);
3411        }
3412
3413        synchronized(this) {
3414            if (mHeavyWeightProcess == null) {
3415                return;
3416            }
3417
3418            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3419                    mHeavyWeightProcess.activities);
3420            for (int i=0; i<activities.size(); i++) {
3421                ActivityRecord r = activities.get(i);
3422                if (!r.finishing) {
3423                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3424                            null, "finish-heavy", true);
3425                }
3426            }
3427
3428            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3429                    mHeavyWeightProcess.userId, 0));
3430            mHeavyWeightProcess = null;
3431        }
3432    }
3433
3434    @Override
3435    public void crashApplication(int uid, int initialPid, String packageName,
3436            String message) {
3437        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3438                != PackageManager.PERMISSION_GRANTED) {
3439            String msg = "Permission Denial: crashApplication() from pid="
3440                    + Binder.getCallingPid()
3441                    + ", uid=" + Binder.getCallingUid()
3442                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3443            Slog.w(TAG, msg);
3444            throw new SecurityException(msg);
3445        }
3446
3447        synchronized(this) {
3448            ProcessRecord proc = null;
3449
3450            // Figure out which process to kill.  We don't trust that initialPid
3451            // still has any relation to current pids, so must scan through the
3452            // list.
3453            synchronized (mPidsSelfLocked) {
3454                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3455                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3456                    if (p.uid != uid) {
3457                        continue;
3458                    }
3459                    if (p.pid == initialPid) {
3460                        proc = p;
3461                        break;
3462                    }
3463                    if (p.pkgList.containsKey(packageName)) {
3464                        proc = p;
3465                    }
3466                }
3467            }
3468
3469            if (proc == null) {
3470                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3471                        + " initialPid=" + initialPid
3472                        + " packageName=" + packageName);
3473                return;
3474            }
3475
3476            if (proc.thread != null) {
3477                if (proc.pid == Process.myPid()) {
3478                    Log.w(TAG, "crashApplication: trying to crash self!");
3479                    return;
3480                }
3481                long ident = Binder.clearCallingIdentity();
3482                try {
3483                    proc.thread.scheduleCrash(message);
3484                } catch (RemoteException e) {
3485                }
3486                Binder.restoreCallingIdentity(ident);
3487            }
3488        }
3489    }
3490
3491    @Override
3492    public final void finishSubActivity(IBinder token, String resultWho,
3493            int requestCode) {
3494        synchronized(this) {
3495            final long origId = Binder.clearCallingIdentity();
3496            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3497            if (r != null) {
3498                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3499            }
3500            Binder.restoreCallingIdentity(origId);
3501        }
3502    }
3503
3504    @Override
3505    public boolean finishActivityAffinity(IBinder token) {
3506        synchronized(this) {
3507            final long origId = Binder.clearCallingIdentity();
3508            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3509            boolean res = false;
3510            if (r != null) {
3511                res = r.task.stack.finishActivityAffinityLocked(r);
3512            }
3513            Binder.restoreCallingIdentity(origId);
3514            return res;
3515        }
3516    }
3517
3518    @Override
3519    public boolean willActivityBeVisible(IBinder token) {
3520        synchronized(this) {
3521            ActivityStack stack = ActivityRecord.getStackLocked(token);
3522            if (stack != null) {
3523                return stack.willActivityBeVisibleLocked(token);
3524            }
3525            return false;
3526        }
3527    }
3528
3529    @Override
3530    public void overridePendingTransition(IBinder token, String packageName,
3531            int enterAnim, int exitAnim) {
3532        synchronized(this) {
3533            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3534            if (self == null) {
3535                return;
3536            }
3537
3538            final long origId = Binder.clearCallingIdentity();
3539
3540            if (self.state == ActivityState.RESUMED
3541                    || self.state == ActivityState.PAUSING) {
3542                mWindowManager.overridePendingAppTransition(packageName,
3543                        enterAnim, exitAnim, null);
3544            }
3545
3546            Binder.restoreCallingIdentity(origId);
3547        }
3548    }
3549
3550    /**
3551     * Main function for removing an existing process from the activity manager
3552     * as a result of that process going away.  Clears out all connections
3553     * to the process.
3554     */
3555    private final void handleAppDiedLocked(ProcessRecord app,
3556            boolean restarting, boolean allowRestart) {
3557        int pid = app.pid;
3558        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3559        if (!restarting) {
3560            removeLruProcessLocked(app);
3561            if (pid > 0) {
3562                ProcessList.remove(pid);
3563            }
3564        }
3565
3566        if (mProfileProc == app) {
3567            clearProfilerLocked();
3568        }
3569
3570        // Remove this application's activities from active lists.
3571        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3572
3573        app.activities.clear();
3574
3575        if (app.instrumentationClass != null) {
3576            Slog.w(TAG, "Crash of app " + app.processName
3577                  + " running instrumentation " + app.instrumentationClass);
3578            Bundle info = new Bundle();
3579            info.putString("shortMsg", "Process crashed.");
3580            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3581        }
3582
3583        if (!restarting) {
3584            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3585                // If there was nothing to resume, and we are not already
3586                // restarting this process, but there is a visible activity that
3587                // is hosted by the process...  then make sure all visible
3588                // activities are running, taking care of restarting this
3589                // process.
3590                if (hasVisibleActivities) {
3591                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3592                }
3593            }
3594        }
3595    }
3596
3597    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3598        IBinder threadBinder = thread.asBinder();
3599        // Find the application record.
3600        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3601            ProcessRecord rec = mLruProcesses.get(i);
3602            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3603                return i;
3604            }
3605        }
3606        return -1;
3607    }
3608
3609    final ProcessRecord getRecordForAppLocked(
3610            IApplicationThread thread) {
3611        if (thread == null) {
3612            return null;
3613        }
3614
3615        int appIndex = getLRURecordIndexForAppLocked(thread);
3616        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3617    }
3618
3619    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3620        // If there are no longer any background processes running,
3621        // and the app that died was not running instrumentation,
3622        // then tell everyone we are now low on memory.
3623        boolean haveBg = false;
3624        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3625            ProcessRecord rec = mLruProcesses.get(i);
3626            if (rec.thread != null
3627                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3628                haveBg = true;
3629                break;
3630            }
3631        }
3632
3633        if (!haveBg) {
3634            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3635            if (doReport) {
3636                long now = SystemClock.uptimeMillis();
3637                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3638                    doReport = false;
3639                } else {
3640                    mLastMemUsageReportTime = now;
3641                }
3642            }
3643            final ArrayList<ProcessMemInfo> memInfos
3644                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3645            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3646            long now = SystemClock.uptimeMillis();
3647            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3648                ProcessRecord rec = mLruProcesses.get(i);
3649                if (rec == dyingProc || rec.thread == null) {
3650                    continue;
3651                }
3652                if (doReport) {
3653                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3654                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3655                }
3656                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3657                    // The low memory report is overriding any current
3658                    // state for a GC request.  Make sure to do
3659                    // heavy/important/visible/foreground processes first.
3660                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3661                        rec.lastRequestedGc = 0;
3662                    } else {
3663                        rec.lastRequestedGc = rec.lastLowMemory;
3664                    }
3665                    rec.reportLowMemory = true;
3666                    rec.lastLowMemory = now;
3667                    mProcessesToGc.remove(rec);
3668                    addProcessToGcListLocked(rec);
3669                }
3670            }
3671            if (doReport) {
3672                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3673                mHandler.sendMessage(msg);
3674            }
3675            scheduleAppGcsLocked();
3676        }
3677    }
3678
3679    final void appDiedLocked(ProcessRecord app, int pid,
3680            IApplicationThread thread) {
3681
3682        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3683        synchronized (stats) {
3684            stats.noteProcessDiedLocked(app.info.uid, pid);
3685        }
3686
3687        // Clean up already done if the process has been re-started.
3688        if (app.pid == pid && app.thread != null &&
3689                app.thread.asBinder() == thread.asBinder()) {
3690            boolean doLowMem = app.instrumentationClass == null;
3691            boolean doOomAdj = doLowMem;
3692            if (!app.killedByAm) {
3693                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3694                        + ") has died.");
3695                mAllowLowerMemLevel = true;
3696            } else {
3697                // Note that we always want to do oom adj to update our state with the
3698                // new number of procs.
3699                mAllowLowerMemLevel = false;
3700                doLowMem = false;
3701            }
3702            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3703            if (DEBUG_CLEANUP) Slog.v(
3704                TAG, "Dying app: " + app + ", pid: " + pid
3705                + ", thread: " + thread.asBinder());
3706            handleAppDiedLocked(app, false, true);
3707
3708            if (doOomAdj) {
3709                updateOomAdjLocked();
3710            }
3711            if (doLowMem) {
3712                doLowMemReportIfNeededLocked(app);
3713            }
3714        } else if (app.pid != pid) {
3715            // A new process has already been started.
3716            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3717                    + ") has died and restarted (pid " + app.pid + ").");
3718            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3719        } else if (DEBUG_PROCESSES) {
3720            Slog.d(TAG, "Received spurious death notification for thread "
3721                    + thread.asBinder());
3722        }
3723    }
3724
3725    /**
3726     * If a stack trace dump file is configured, dump process stack traces.
3727     * @param clearTraces causes the dump file to be erased prior to the new
3728     *    traces being written, if true; when false, the new traces will be
3729     *    appended to any existing file content.
3730     * @param firstPids of dalvik VM processes to dump stack traces for first
3731     * @param lastPids of dalvik VM processes to dump stack traces for last
3732     * @param nativeProcs optional list of native process names to dump stack crawls
3733     * @return file containing stack traces, or null if no dump file is configured
3734     */
3735    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3736            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3737        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3738        if (tracesPath == null || tracesPath.length() == 0) {
3739            return null;
3740        }
3741
3742        File tracesFile = new File(tracesPath);
3743        try {
3744            File tracesDir = tracesFile.getParentFile();
3745            if (!tracesDir.exists()) {
3746                tracesFile.mkdirs();
3747                if (!SELinux.restorecon(tracesDir)) {
3748                    return null;
3749                }
3750            }
3751            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3752
3753            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3754            tracesFile.createNewFile();
3755            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3756        } catch (IOException e) {
3757            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3758            return null;
3759        }
3760
3761        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3762        return tracesFile;
3763    }
3764
3765    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3766            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3767        // Use a FileObserver to detect when traces finish writing.
3768        // The order of traces is considered important to maintain for legibility.
3769        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3770            @Override
3771            public synchronized void onEvent(int event, String path) { notify(); }
3772        };
3773
3774        try {
3775            observer.startWatching();
3776
3777            // First collect all of the stacks of the most important pids.
3778            if (firstPids != null) {
3779                try {
3780                    int num = firstPids.size();
3781                    for (int i = 0; i < num; i++) {
3782                        synchronized (observer) {
3783                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3784                            observer.wait(200);  // Wait for write-close, give up after 200msec
3785                        }
3786                    }
3787                } catch (InterruptedException e) {
3788                    Log.wtf(TAG, e);
3789                }
3790            }
3791
3792            // Next collect the stacks of the native pids
3793            if (nativeProcs != null) {
3794                int[] pids = Process.getPidsForCommands(nativeProcs);
3795                if (pids != null) {
3796                    for (int pid : pids) {
3797                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3798                    }
3799                }
3800            }
3801
3802            // Lastly, measure CPU usage.
3803            if (processCpuTracker != null) {
3804                processCpuTracker.init();
3805                System.gc();
3806                processCpuTracker.update();
3807                try {
3808                    synchronized (processCpuTracker) {
3809                        processCpuTracker.wait(500); // measure over 1/2 second.
3810                    }
3811                } catch (InterruptedException e) {
3812                }
3813                processCpuTracker.update();
3814
3815                // We'll take the stack crawls of just the top apps using CPU.
3816                final int N = processCpuTracker.countWorkingStats();
3817                int numProcs = 0;
3818                for (int i=0; i<N && numProcs<5; i++) {
3819                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3820                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3821                        numProcs++;
3822                        try {
3823                            synchronized (observer) {
3824                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3825                                observer.wait(200);  // Wait for write-close, give up after 200msec
3826                            }
3827                        } catch (InterruptedException e) {
3828                            Log.wtf(TAG, e);
3829                        }
3830
3831                    }
3832                }
3833            }
3834        } finally {
3835            observer.stopWatching();
3836        }
3837    }
3838
3839    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3840        if (true || IS_USER_BUILD) {
3841            return;
3842        }
3843        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3844        if (tracesPath == null || tracesPath.length() == 0) {
3845            return;
3846        }
3847
3848        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3849        StrictMode.allowThreadDiskWrites();
3850        try {
3851            final File tracesFile = new File(tracesPath);
3852            final File tracesDir = tracesFile.getParentFile();
3853            final File tracesTmp = new File(tracesDir, "__tmp__");
3854            try {
3855                if (!tracesDir.exists()) {
3856                    tracesFile.mkdirs();
3857                    if (!SELinux.restorecon(tracesDir.getPath())) {
3858                        return;
3859                    }
3860                }
3861                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3862
3863                if (tracesFile.exists()) {
3864                    tracesTmp.delete();
3865                    tracesFile.renameTo(tracesTmp);
3866                }
3867                StringBuilder sb = new StringBuilder();
3868                Time tobj = new Time();
3869                tobj.set(System.currentTimeMillis());
3870                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3871                sb.append(": ");
3872                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3873                sb.append(" since ");
3874                sb.append(msg);
3875                FileOutputStream fos = new FileOutputStream(tracesFile);
3876                fos.write(sb.toString().getBytes());
3877                if (app == null) {
3878                    fos.write("\n*** No application process!".getBytes());
3879                }
3880                fos.close();
3881                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3882            } catch (IOException e) {
3883                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3884                return;
3885            }
3886
3887            if (app != null) {
3888                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3889                firstPids.add(app.pid);
3890                dumpStackTraces(tracesPath, firstPids, null, null, null);
3891            }
3892
3893            File lastTracesFile = null;
3894            File curTracesFile = null;
3895            for (int i=9; i>=0; i--) {
3896                String name = String.format(Locale.US, "slow%02d.txt", i);
3897                curTracesFile = new File(tracesDir, name);
3898                if (curTracesFile.exists()) {
3899                    if (lastTracesFile != null) {
3900                        curTracesFile.renameTo(lastTracesFile);
3901                    } else {
3902                        curTracesFile.delete();
3903                    }
3904                }
3905                lastTracesFile = curTracesFile;
3906            }
3907            tracesFile.renameTo(curTracesFile);
3908            if (tracesTmp.exists()) {
3909                tracesTmp.renameTo(tracesFile);
3910            }
3911        } finally {
3912            StrictMode.setThreadPolicy(oldPolicy);
3913        }
3914    }
3915
3916    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3917            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3918        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3919        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3920
3921        if (mController != null) {
3922            try {
3923                // 0 == continue, -1 = kill process immediately
3924                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3925                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3926            } catch (RemoteException e) {
3927                mController = null;
3928                Watchdog.getInstance().setActivityController(null);
3929            }
3930        }
3931
3932        long anrTime = SystemClock.uptimeMillis();
3933        if (MONITOR_CPU_USAGE) {
3934            updateCpuStatsNow();
3935        }
3936
3937        synchronized (this) {
3938            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3939            if (mShuttingDown) {
3940                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3941                return;
3942            } else if (app.notResponding) {
3943                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3944                return;
3945            } else if (app.crashing) {
3946                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3947                return;
3948            }
3949
3950            // In case we come through here for the same app before completing
3951            // this one, mark as anring now so we will bail out.
3952            app.notResponding = true;
3953
3954            // Log the ANR to the event log.
3955            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3956                    app.processName, app.info.flags, annotation);
3957
3958            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3959            firstPids.add(app.pid);
3960
3961            int parentPid = app.pid;
3962            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3963            if (parentPid != app.pid) firstPids.add(parentPid);
3964
3965            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3966
3967            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3968                ProcessRecord r = mLruProcesses.get(i);
3969                if (r != null && r.thread != null) {
3970                    int pid = r.pid;
3971                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3972                        if (r.persistent) {
3973                            firstPids.add(pid);
3974                        } else {
3975                            lastPids.put(pid, Boolean.TRUE);
3976                        }
3977                    }
3978                }
3979            }
3980        }
3981
3982        // Log the ANR to the main log.
3983        StringBuilder info = new StringBuilder();
3984        info.setLength(0);
3985        info.append("ANR in ").append(app.processName);
3986        if (activity != null && activity.shortComponentName != null) {
3987            info.append(" (").append(activity.shortComponentName).append(")");
3988        }
3989        info.append("\n");
3990        info.append("PID: ").append(app.pid).append("\n");
3991        if (annotation != null) {
3992            info.append("Reason: ").append(annotation).append("\n");
3993        }
3994        if (parent != null && parent != activity) {
3995            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3996        }
3997
3998        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
3999
4000        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4001                NATIVE_STACKS_OF_INTEREST);
4002
4003        String cpuInfo = null;
4004        if (MONITOR_CPU_USAGE) {
4005            updateCpuStatsNow();
4006            synchronized (mProcessCpuThread) {
4007                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4008            }
4009            info.append(processCpuTracker.printCurrentLoad());
4010            info.append(cpuInfo);
4011        }
4012
4013        info.append(processCpuTracker.printCurrentState(anrTime));
4014
4015        Slog.e(TAG, info.toString());
4016        if (tracesFile == null) {
4017            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4018            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4019        }
4020
4021        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4022                cpuInfo, tracesFile, null);
4023
4024        if (mController != null) {
4025            try {
4026                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4027                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4028                if (res != 0) {
4029                    if (res < 0 && app.pid != MY_PID) {
4030                        Process.killProcess(app.pid);
4031                    } else {
4032                        synchronized (this) {
4033                            mServices.scheduleServiceTimeoutLocked(app);
4034                        }
4035                    }
4036                    return;
4037                }
4038            } catch (RemoteException e) {
4039                mController = null;
4040                Watchdog.getInstance().setActivityController(null);
4041            }
4042        }
4043
4044        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4045        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4046                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4047
4048        synchronized (this) {
4049            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4050                killUnneededProcessLocked(app, "background ANR");
4051                return;
4052            }
4053
4054            // Set the app's notResponding state, and look up the errorReportReceiver
4055            makeAppNotRespondingLocked(app,
4056                    activity != null ? activity.shortComponentName : null,
4057                    annotation != null ? "ANR " + annotation : "ANR",
4058                    info.toString());
4059
4060            // Bring up the infamous App Not Responding dialog
4061            Message msg = Message.obtain();
4062            HashMap<String, Object> map = new HashMap<String, Object>();
4063            msg.what = SHOW_NOT_RESPONDING_MSG;
4064            msg.obj = map;
4065            msg.arg1 = aboveSystem ? 1 : 0;
4066            map.put("app", app);
4067            if (activity != null) {
4068                map.put("activity", activity);
4069            }
4070
4071            mHandler.sendMessage(msg);
4072        }
4073    }
4074
4075    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4076        if (!mLaunchWarningShown) {
4077            mLaunchWarningShown = true;
4078            mHandler.post(new Runnable() {
4079                @Override
4080                public void run() {
4081                    synchronized (ActivityManagerService.this) {
4082                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4083                        d.show();
4084                        mHandler.postDelayed(new Runnable() {
4085                            @Override
4086                            public void run() {
4087                                synchronized (ActivityManagerService.this) {
4088                                    d.dismiss();
4089                                    mLaunchWarningShown = false;
4090                                }
4091                            }
4092                        }, 4000);
4093                    }
4094                }
4095            });
4096        }
4097    }
4098
4099    @Override
4100    public boolean clearApplicationUserData(final String packageName,
4101            final IPackageDataObserver observer, int userId) {
4102        enforceNotIsolatedCaller("clearApplicationUserData");
4103        int uid = Binder.getCallingUid();
4104        int pid = Binder.getCallingPid();
4105        userId = handleIncomingUser(pid, uid,
4106                userId, false, true, "clearApplicationUserData", null);
4107        long callingId = Binder.clearCallingIdentity();
4108        try {
4109            IPackageManager pm = AppGlobals.getPackageManager();
4110            int pkgUid = -1;
4111            synchronized(this) {
4112                try {
4113                    pkgUid = pm.getPackageUid(packageName, userId);
4114                } catch (RemoteException e) {
4115                }
4116                if (pkgUid == -1) {
4117                    Slog.w(TAG, "Invalid packageName: " + packageName);
4118                    if (observer != null) {
4119                        try {
4120                            observer.onRemoveCompleted(packageName, false);
4121                        } catch (RemoteException e) {
4122                            Slog.i(TAG, "Observer no longer exists.");
4123                        }
4124                    }
4125                    return false;
4126                }
4127                if (uid == pkgUid || checkComponentPermission(
4128                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4129                        pid, uid, -1, true)
4130                        == PackageManager.PERMISSION_GRANTED) {
4131                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4132                } else {
4133                    throw new SecurityException("PID " + pid + " does not have permission "
4134                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4135                                    + " of package " + packageName);
4136                }
4137            }
4138
4139            try {
4140                // Clear application user data
4141                pm.clearApplicationUserData(packageName, observer, userId);
4142
4143                // Remove all permissions granted from/to this package
4144                removeUriPermissionsForPackageLocked(packageName, userId, true);
4145
4146                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4147                        Uri.fromParts("package", packageName, null));
4148                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4149                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4150                        null, null, 0, null, null, null, false, false, userId);
4151            } catch (RemoteException e) {
4152            }
4153        } finally {
4154            Binder.restoreCallingIdentity(callingId);
4155        }
4156        return true;
4157    }
4158
4159    @Override
4160    public void killBackgroundProcesses(final String packageName, int userId) {
4161        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4162                != PackageManager.PERMISSION_GRANTED &&
4163                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4164                        != PackageManager.PERMISSION_GRANTED) {
4165            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4166                    + Binder.getCallingPid()
4167                    + ", uid=" + Binder.getCallingUid()
4168                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4169            Slog.w(TAG, msg);
4170            throw new SecurityException(msg);
4171        }
4172
4173        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4174                userId, true, true, "killBackgroundProcesses", null);
4175        long callingId = Binder.clearCallingIdentity();
4176        try {
4177            IPackageManager pm = AppGlobals.getPackageManager();
4178            synchronized(this) {
4179                int appId = -1;
4180                try {
4181                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4182                } catch (RemoteException e) {
4183                }
4184                if (appId == -1) {
4185                    Slog.w(TAG, "Invalid packageName: " + packageName);
4186                    return;
4187                }
4188                killPackageProcessesLocked(packageName, appId, userId,
4189                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4190            }
4191        } finally {
4192            Binder.restoreCallingIdentity(callingId);
4193        }
4194    }
4195
4196    @Override
4197    public void killAllBackgroundProcesses() {
4198        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4199                != PackageManager.PERMISSION_GRANTED) {
4200            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4201                    + Binder.getCallingPid()
4202                    + ", uid=" + Binder.getCallingUid()
4203                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4204            Slog.w(TAG, msg);
4205            throw new SecurityException(msg);
4206        }
4207
4208        long callingId = Binder.clearCallingIdentity();
4209        try {
4210            synchronized(this) {
4211                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4212                final int NP = mProcessNames.getMap().size();
4213                for (int ip=0; ip<NP; ip++) {
4214                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4215                    final int NA = apps.size();
4216                    for (int ia=0; ia<NA; ia++) {
4217                        ProcessRecord app = apps.valueAt(ia);
4218                        if (app.persistent) {
4219                            // we don't kill persistent processes
4220                            continue;
4221                        }
4222                        if (app.removed) {
4223                            procs.add(app);
4224                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4225                            app.removed = true;
4226                            procs.add(app);
4227                        }
4228                    }
4229                }
4230
4231                int N = procs.size();
4232                for (int i=0; i<N; i++) {
4233                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4234                }
4235                mAllowLowerMemLevel = true;
4236                updateOomAdjLocked();
4237                doLowMemReportIfNeededLocked(null);
4238            }
4239        } finally {
4240            Binder.restoreCallingIdentity(callingId);
4241        }
4242    }
4243
4244    @Override
4245    public void forceStopPackage(final String packageName, int userId) {
4246        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4247                != PackageManager.PERMISSION_GRANTED) {
4248            String msg = "Permission Denial: forceStopPackage() from pid="
4249                    + Binder.getCallingPid()
4250                    + ", uid=" + Binder.getCallingUid()
4251                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4252            Slog.w(TAG, msg);
4253            throw new SecurityException(msg);
4254        }
4255        final int callingPid = Binder.getCallingPid();
4256        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4257                userId, true, true, "forceStopPackage", null);
4258        long callingId = Binder.clearCallingIdentity();
4259        try {
4260            IPackageManager pm = AppGlobals.getPackageManager();
4261            synchronized(this) {
4262                int[] users = userId == UserHandle.USER_ALL
4263                        ? getUsersLocked() : new int[] { userId };
4264                for (int user : users) {
4265                    int pkgUid = -1;
4266                    try {
4267                        pkgUid = pm.getPackageUid(packageName, user);
4268                    } catch (RemoteException e) {
4269                    }
4270                    if (pkgUid == -1) {
4271                        Slog.w(TAG, "Invalid packageName: " + packageName);
4272                        continue;
4273                    }
4274                    try {
4275                        pm.setPackageStoppedState(packageName, true, user);
4276                    } catch (RemoteException e) {
4277                    } catch (IllegalArgumentException e) {
4278                        Slog.w(TAG, "Failed trying to unstop package "
4279                                + packageName + ": " + e);
4280                    }
4281                    if (isUserRunningLocked(user, false)) {
4282                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4283                    }
4284                }
4285            }
4286        } finally {
4287            Binder.restoreCallingIdentity(callingId);
4288        }
4289    }
4290
4291    /*
4292     * The pkg name and app id have to be specified.
4293     */
4294    @Override
4295    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4296        if (pkg == null) {
4297            return;
4298        }
4299        // Make sure the uid is valid.
4300        if (appid < 0) {
4301            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4302            return;
4303        }
4304        int callerUid = Binder.getCallingUid();
4305        // Only the system server can kill an application
4306        if (callerUid == Process.SYSTEM_UID) {
4307            // Post an aysnc message to kill the application
4308            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4309            msg.arg1 = appid;
4310            msg.arg2 = 0;
4311            Bundle bundle = new Bundle();
4312            bundle.putString("pkg", pkg);
4313            bundle.putString("reason", reason);
4314            msg.obj = bundle;
4315            mHandler.sendMessage(msg);
4316        } else {
4317            throw new SecurityException(callerUid + " cannot kill pkg: " +
4318                    pkg);
4319        }
4320    }
4321
4322    @Override
4323    public void closeSystemDialogs(String reason) {
4324        enforceNotIsolatedCaller("closeSystemDialogs");
4325
4326        final int pid = Binder.getCallingPid();
4327        final int uid = Binder.getCallingUid();
4328        final long origId = Binder.clearCallingIdentity();
4329        try {
4330            synchronized (this) {
4331                // Only allow this from foreground processes, so that background
4332                // applications can't abuse it to prevent system UI from being shown.
4333                if (uid >= Process.FIRST_APPLICATION_UID) {
4334                    ProcessRecord proc;
4335                    synchronized (mPidsSelfLocked) {
4336                        proc = mPidsSelfLocked.get(pid);
4337                    }
4338                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4339                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4340                                + " from background process " + proc);
4341                        return;
4342                    }
4343                }
4344                closeSystemDialogsLocked(reason);
4345            }
4346        } finally {
4347            Binder.restoreCallingIdentity(origId);
4348        }
4349    }
4350
4351    void closeSystemDialogsLocked(String reason) {
4352        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4353        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4354                | Intent.FLAG_RECEIVER_FOREGROUND);
4355        if (reason != null) {
4356            intent.putExtra("reason", reason);
4357        }
4358        mWindowManager.closeSystemDialogs(reason);
4359
4360        mStackSupervisor.closeSystemDialogsLocked();
4361
4362        broadcastIntentLocked(null, null, intent, null,
4363                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4364                Process.SYSTEM_UID, UserHandle.USER_ALL);
4365    }
4366
4367    @Override
4368    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4369        enforceNotIsolatedCaller("getProcessMemoryInfo");
4370        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4371        for (int i=pids.length-1; i>=0; i--) {
4372            ProcessRecord proc;
4373            int oomAdj;
4374            synchronized (this) {
4375                synchronized (mPidsSelfLocked) {
4376                    proc = mPidsSelfLocked.get(pids[i]);
4377                    oomAdj = proc != null ? proc.setAdj : 0;
4378                }
4379            }
4380            infos[i] = new Debug.MemoryInfo();
4381            Debug.getMemoryInfo(pids[i], infos[i]);
4382            if (proc != null) {
4383                synchronized (this) {
4384                    if (proc.thread != null && proc.setAdj == oomAdj) {
4385                        // Record this for posterity if the process has been stable.
4386                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4387                                infos[i].getTotalUss(), false, proc.pkgList);
4388                    }
4389                }
4390            }
4391        }
4392        return infos;
4393    }
4394
4395    @Override
4396    public long[] getProcessPss(int[] pids) {
4397        enforceNotIsolatedCaller("getProcessPss");
4398        long[] pss = new long[pids.length];
4399        for (int i=pids.length-1; i>=0; i--) {
4400            ProcessRecord proc;
4401            int oomAdj;
4402            synchronized (this) {
4403                synchronized (mPidsSelfLocked) {
4404                    proc = mPidsSelfLocked.get(pids[i]);
4405                    oomAdj = proc != null ? proc.setAdj : 0;
4406                }
4407            }
4408            long[] tmpUss = new long[1];
4409            pss[i] = Debug.getPss(pids[i], tmpUss);
4410            if (proc != null) {
4411                synchronized (this) {
4412                    if (proc.thread != null && proc.setAdj == oomAdj) {
4413                        // Record this for posterity if the process has been stable.
4414                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4415                    }
4416                }
4417            }
4418        }
4419        return pss;
4420    }
4421
4422    @Override
4423    public void killApplicationProcess(String processName, int uid) {
4424        if (processName == null) {
4425            return;
4426        }
4427
4428        int callerUid = Binder.getCallingUid();
4429        // Only the system server can kill an application
4430        if (callerUid == Process.SYSTEM_UID) {
4431            synchronized (this) {
4432                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4433                if (app != null && app.thread != null) {
4434                    try {
4435                        app.thread.scheduleSuicide();
4436                    } catch (RemoteException e) {
4437                        // If the other end already died, then our work here is done.
4438                    }
4439                } else {
4440                    Slog.w(TAG, "Process/uid not found attempting kill of "
4441                            + processName + " / " + uid);
4442                }
4443            }
4444        } else {
4445            throw new SecurityException(callerUid + " cannot kill app process: " +
4446                    processName);
4447        }
4448    }
4449
4450    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4451        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4452                false, true, false, UserHandle.getUserId(uid), reason);
4453        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4454                Uri.fromParts("package", packageName, null));
4455        if (!mProcessesReady) {
4456            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4457                    | Intent.FLAG_RECEIVER_FOREGROUND);
4458        }
4459        intent.putExtra(Intent.EXTRA_UID, uid);
4460        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4461        broadcastIntentLocked(null, null, intent,
4462                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4463                false, false,
4464                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4465    }
4466
4467    private void forceStopUserLocked(int userId, String reason) {
4468        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
4469        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4470        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4471                | Intent.FLAG_RECEIVER_FOREGROUND);
4472        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4473        broadcastIntentLocked(null, null, intent,
4474                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4475                false, false,
4476                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4477    }
4478
4479    private final boolean killPackageProcessesLocked(String packageName, int appId,
4480            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4481            boolean doit, boolean evenPersistent, String reason) {
4482        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4483
4484        // Remove all processes this package may have touched: all with the
4485        // same UID (except for the system or root user), and all whose name
4486        // matches the package name.
4487        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4488        final int NP = mProcessNames.getMap().size();
4489        for (int ip=0; ip<NP; ip++) {
4490            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4491            final int NA = apps.size();
4492            for (int ia=0; ia<NA; ia++) {
4493                ProcessRecord app = apps.valueAt(ia);
4494                if (app.persistent && !evenPersistent) {
4495                    // we don't kill persistent processes
4496                    continue;
4497                }
4498                if (app.removed) {
4499                    if (doit) {
4500                        procs.add(app);
4501                    }
4502                    continue;
4503                }
4504
4505                // Skip process if it doesn't meet our oom adj requirement.
4506                if (app.setAdj < minOomAdj) {
4507                    continue;
4508                }
4509
4510                // If no package is specified, we call all processes under the
4511                // give user id.
4512                if (packageName == null) {
4513                    if (app.userId != userId) {
4514                        continue;
4515                    }
4516                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4517                        continue;
4518                    }
4519                // Package has been specified, we want to hit all processes
4520                // that match it.  We need to qualify this by the processes
4521                // that are running under the specified app and user ID.
4522                } else {
4523                    if (UserHandle.getAppId(app.uid) != appId) {
4524                        continue;
4525                    }
4526                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4527                        continue;
4528                    }
4529                    if (!app.pkgList.containsKey(packageName)) {
4530                        continue;
4531                    }
4532                }
4533
4534                // Process has passed all conditions, kill it!
4535                if (!doit) {
4536                    return true;
4537                }
4538                app.removed = true;
4539                procs.add(app);
4540            }
4541        }
4542
4543        int N = procs.size();
4544        for (int i=0; i<N; i++) {
4545            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4546        }
4547        updateOomAdjLocked();
4548        return N > 0;
4549    }
4550
4551    private final boolean forceStopPackageLocked(String name, int appId,
4552            boolean callerWillRestart, boolean purgeCache, boolean doit,
4553            boolean evenPersistent, int userId, String reason) {
4554        int i;
4555        int N;
4556
4557        if (userId == UserHandle.USER_ALL && name == null) {
4558            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4559        }
4560
4561        if (appId < 0 && name != null) {
4562            try {
4563                appId = UserHandle.getAppId(
4564                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4565            } catch (RemoteException e) {
4566            }
4567        }
4568
4569        if (doit) {
4570            if (name != null) {
4571                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4572                        + " user=" + userId + ": " + reason);
4573            } else {
4574                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4575            }
4576
4577            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4578            for (int ip=pmap.size()-1; ip>=0; ip--) {
4579                SparseArray<Long> ba = pmap.valueAt(ip);
4580                for (i=ba.size()-1; i>=0; i--) {
4581                    boolean remove = false;
4582                    final int entUid = ba.keyAt(i);
4583                    if (name != null) {
4584                        if (userId == UserHandle.USER_ALL) {
4585                            if (UserHandle.getAppId(entUid) == appId) {
4586                                remove = true;
4587                            }
4588                        } else {
4589                            if (entUid == UserHandle.getUid(userId, appId)) {
4590                                remove = true;
4591                            }
4592                        }
4593                    } else if (UserHandle.getUserId(entUid) == userId) {
4594                        remove = true;
4595                    }
4596                    if (remove) {
4597                        ba.removeAt(i);
4598                    }
4599                }
4600                if (ba.size() == 0) {
4601                    pmap.removeAt(ip);
4602                }
4603            }
4604        }
4605
4606        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4607                -100, callerWillRestart, true, doit, evenPersistent,
4608                name == null ? ("stop user " + userId) : ("stop " + name));
4609
4610        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4611            if (!doit) {
4612                return true;
4613            }
4614            didSomething = true;
4615        }
4616
4617        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4618            if (!doit) {
4619                return true;
4620            }
4621            didSomething = true;
4622        }
4623
4624        if (name == null) {
4625            // Remove all sticky broadcasts from this user.
4626            mStickyBroadcasts.remove(userId);
4627        }
4628
4629        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4630        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4631                userId, providers)) {
4632            if (!doit) {
4633                return true;
4634            }
4635            didSomething = true;
4636        }
4637        N = providers.size();
4638        for (i=0; i<N; i++) {
4639            removeDyingProviderLocked(null, providers.get(i), true);
4640        }
4641
4642        // Remove transient permissions granted from/to this package/user
4643        removeUriPermissionsForPackageLocked(name, userId, false);
4644
4645        if (name == null) {
4646            // Remove pending intents.  For now we only do this when force
4647            // stopping users, because we have some problems when doing this
4648            // for packages -- app widgets are not currently cleaned up for
4649            // such packages, so they can be left with bad pending intents.
4650            if (mIntentSenderRecords.size() > 0) {
4651                Iterator<WeakReference<PendingIntentRecord>> it
4652                        = mIntentSenderRecords.values().iterator();
4653                while (it.hasNext()) {
4654                    WeakReference<PendingIntentRecord> wpir = it.next();
4655                    if (wpir == null) {
4656                        it.remove();
4657                        continue;
4658                    }
4659                    PendingIntentRecord pir = wpir.get();
4660                    if (pir == null) {
4661                        it.remove();
4662                        continue;
4663                    }
4664                    if (name == null) {
4665                        // Stopping user, remove all objects for the user.
4666                        if (pir.key.userId != userId) {
4667                            // Not the same user, skip it.
4668                            continue;
4669                        }
4670                    } else {
4671                        if (UserHandle.getAppId(pir.uid) != appId) {
4672                            // Different app id, skip it.
4673                            continue;
4674                        }
4675                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4676                            // Different user, skip it.
4677                            continue;
4678                        }
4679                        if (!pir.key.packageName.equals(name)) {
4680                            // Different package, skip it.
4681                            continue;
4682                        }
4683                    }
4684                    if (!doit) {
4685                        return true;
4686                    }
4687                    didSomething = true;
4688                    it.remove();
4689                    pir.canceled = true;
4690                    if (pir.key.activity != null) {
4691                        pir.key.activity.pendingResults.remove(pir.ref);
4692                    }
4693                }
4694            }
4695        }
4696
4697        if (doit) {
4698            if (purgeCache && name != null) {
4699                AttributeCache ac = AttributeCache.instance();
4700                if (ac != null) {
4701                    ac.removePackage(name);
4702                }
4703            }
4704            if (mBooted) {
4705                mStackSupervisor.resumeTopActivitiesLocked();
4706                mStackSupervisor.scheduleIdleLocked();
4707            }
4708        }
4709
4710        return didSomething;
4711    }
4712
4713    private final boolean removeProcessLocked(ProcessRecord app,
4714            boolean callerWillRestart, boolean allowRestart, String reason) {
4715        final String name = app.processName;
4716        final int uid = app.uid;
4717        if (DEBUG_PROCESSES) Slog.d(
4718            TAG, "Force removing proc " + app.toShortString() + " (" + name
4719            + "/" + uid + ")");
4720
4721        mProcessNames.remove(name, uid);
4722        mIsolatedProcesses.remove(app.uid);
4723        if (mHeavyWeightProcess == app) {
4724            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4725                    mHeavyWeightProcess.userId, 0));
4726            mHeavyWeightProcess = null;
4727        }
4728        boolean needRestart = false;
4729        if (app.pid > 0 && app.pid != MY_PID) {
4730            int pid = app.pid;
4731            synchronized (mPidsSelfLocked) {
4732                mPidsSelfLocked.remove(pid);
4733                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4734            }
4735            killUnneededProcessLocked(app, reason);
4736            handleAppDiedLocked(app, true, allowRestart);
4737            removeLruProcessLocked(app);
4738
4739            if (app.persistent && !app.isolated) {
4740                if (!callerWillRestart) {
4741                    addAppLocked(app.info, false);
4742                } else {
4743                    needRestart = true;
4744                }
4745            }
4746        } else {
4747            mRemovedProcesses.add(app);
4748        }
4749
4750        return needRestart;
4751    }
4752
4753    private final void processStartTimedOutLocked(ProcessRecord app) {
4754        final int pid = app.pid;
4755        boolean gone = false;
4756        synchronized (mPidsSelfLocked) {
4757            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4758            if (knownApp != null && knownApp.thread == null) {
4759                mPidsSelfLocked.remove(pid);
4760                gone = true;
4761            }
4762        }
4763
4764        if (gone) {
4765            Slog.w(TAG, "Process " + app + " failed to attach");
4766            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4767                    pid, app.uid, app.processName);
4768            mProcessNames.remove(app.processName, app.uid);
4769            mIsolatedProcesses.remove(app.uid);
4770            if (mHeavyWeightProcess == app) {
4771                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4772                        mHeavyWeightProcess.userId, 0));
4773                mHeavyWeightProcess = null;
4774            }
4775            // Take care of any launching providers waiting for this process.
4776            checkAppInLaunchingProvidersLocked(app, true);
4777            // Take care of any services that are waiting for the process.
4778            mServices.processStartTimedOutLocked(app);
4779            killUnneededProcessLocked(app, "start timeout");
4780            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4781                Slog.w(TAG, "Unattached app died before backup, skipping");
4782                try {
4783                    IBackupManager bm = IBackupManager.Stub.asInterface(
4784                            ServiceManager.getService(Context.BACKUP_SERVICE));
4785                    bm.agentDisconnected(app.info.packageName);
4786                } catch (RemoteException e) {
4787                    // Can't happen; the backup manager is local
4788                }
4789            }
4790            if (isPendingBroadcastProcessLocked(pid)) {
4791                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4792                skipPendingBroadcastLocked(pid);
4793            }
4794        } else {
4795            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4796        }
4797    }
4798
4799    private final boolean attachApplicationLocked(IApplicationThread thread,
4800            int pid) {
4801
4802        // Find the application record that is being attached...  either via
4803        // the pid if we are running in multiple processes, or just pull the
4804        // next app record if we are emulating process with anonymous threads.
4805        ProcessRecord app;
4806        if (pid != MY_PID && pid >= 0) {
4807            synchronized (mPidsSelfLocked) {
4808                app = mPidsSelfLocked.get(pid);
4809            }
4810        } else {
4811            app = null;
4812        }
4813
4814        if (app == null) {
4815            Slog.w(TAG, "No pending application record for pid " + pid
4816                    + " (IApplicationThread " + thread + "); dropping process");
4817            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4818            if (pid > 0 && pid != MY_PID) {
4819                Process.killProcessQuiet(pid);
4820            } else {
4821                try {
4822                    thread.scheduleExit();
4823                } catch (Exception e) {
4824                    // Ignore exceptions.
4825                }
4826            }
4827            return false;
4828        }
4829
4830        // If this application record is still attached to a previous
4831        // process, clean it up now.
4832        if (app.thread != null) {
4833            handleAppDiedLocked(app, true, true);
4834        }
4835
4836        // Tell the process all about itself.
4837
4838        if (localLOGV) Slog.v(
4839                TAG, "Binding process pid " + pid + " to record " + app);
4840
4841        final String processName = app.processName;
4842        try {
4843            AppDeathRecipient adr = new AppDeathRecipient(
4844                    app, pid, thread);
4845            thread.asBinder().linkToDeath(adr, 0);
4846            app.deathRecipient = adr;
4847        } catch (RemoteException e) {
4848            app.resetPackageList(mProcessStats);
4849            startProcessLocked(app, "link fail", processName);
4850            return false;
4851        }
4852
4853        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4854
4855        app.makeActive(thread, mProcessStats);
4856        app.curAdj = app.setAdj = -100;
4857        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4858        app.forcingToForeground = null;
4859        app.foregroundServices = false;
4860        app.hasShownUi = false;
4861        app.debugging = false;
4862        app.cached = false;
4863
4864        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4865
4866        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4867        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4868
4869        if (!normalMode) {
4870            Slog.i(TAG, "Launching preboot mode app: " + app);
4871        }
4872
4873        if (localLOGV) Slog.v(
4874            TAG, "New app record " + app
4875            + " thread=" + thread.asBinder() + " pid=" + pid);
4876        try {
4877            int testMode = IApplicationThread.DEBUG_OFF;
4878            if (mDebugApp != null && mDebugApp.equals(processName)) {
4879                testMode = mWaitForDebugger
4880                    ? IApplicationThread.DEBUG_WAIT
4881                    : IApplicationThread.DEBUG_ON;
4882                app.debugging = true;
4883                if (mDebugTransient) {
4884                    mDebugApp = mOrigDebugApp;
4885                    mWaitForDebugger = mOrigWaitForDebugger;
4886                }
4887            }
4888            String profileFile = app.instrumentationProfileFile;
4889            ParcelFileDescriptor profileFd = null;
4890            boolean profileAutoStop = false;
4891            if (mProfileApp != null && mProfileApp.equals(processName)) {
4892                mProfileProc = app;
4893                profileFile = mProfileFile;
4894                profileFd = mProfileFd;
4895                profileAutoStop = mAutoStopProfiler;
4896            }
4897            boolean enableOpenGlTrace = false;
4898            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4899                enableOpenGlTrace = true;
4900                mOpenGlTraceApp = null;
4901            }
4902
4903            // If the app is being launched for restore or full backup, set it up specially
4904            boolean isRestrictedBackupMode = false;
4905            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4906                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4907                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4908                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4909            }
4910
4911            ensurePackageDexOpt(app.instrumentationInfo != null
4912                    ? app.instrumentationInfo.packageName
4913                    : app.info.packageName);
4914            if (app.instrumentationClass != null) {
4915                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4916            }
4917            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4918                    + processName + " with config " + mConfiguration);
4919            ApplicationInfo appInfo = app.instrumentationInfo != null
4920                    ? app.instrumentationInfo : app.info;
4921            app.compat = compatibilityInfoForPackageLocked(appInfo);
4922            if (profileFd != null) {
4923                profileFd = profileFd.dup();
4924            }
4925            thread.bindApplication(processName, appInfo, providers,
4926                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4927                    app.instrumentationArguments, app.instrumentationWatcher,
4928                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4929                    isRestrictedBackupMode || !normalMode, app.persistent,
4930                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4931                    mCoreSettingsObserver.getCoreSettingsLocked());
4932            updateLruProcessLocked(app, false, null);
4933            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4934        } catch (Exception e) {
4935            // todo: Yikes!  What should we do?  For now we will try to
4936            // start another process, but that could easily get us in
4937            // an infinite loop of restarting processes...
4938            Slog.w(TAG, "Exception thrown during bind!", e);
4939
4940            app.resetPackageList(mProcessStats);
4941            app.unlinkDeathRecipient();
4942            startProcessLocked(app, "bind fail", processName);
4943            return false;
4944        }
4945
4946        // Remove this record from the list of starting applications.
4947        mPersistentStartingProcesses.remove(app);
4948        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4949                "Attach application locked removing on hold: " + app);
4950        mProcessesOnHold.remove(app);
4951
4952        boolean badApp = false;
4953        boolean didSomething = false;
4954
4955        // See if the top visible activity is waiting to run in this process...
4956        if (normalMode) {
4957            try {
4958                if (mStackSupervisor.attachApplicationLocked(app)) {
4959                    didSomething = true;
4960                }
4961            } catch (Exception e) {
4962                badApp = true;
4963            }
4964        }
4965
4966        // Find any services that should be running in this process...
4967        if (!badApp) {
4968            try {
4969                didSomething |= mServices.attachApplicationLocked(app, processName);
4970            } catch (Exception e) {
4971                badApp = true;
4972            }
4973        }
4974
4975        // Check if a next-broadcast receiver is in this process...
4976        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4977            try {
4978                didSomething |= sendPendingBroadcastsLocked(app);
4979            } catch (Exception e) {
4980                // If the app died trying to launch the receiver we declare it 'bad'
4981                badApp = true;
4982            }
4983        }
4984
4985        // Check whether the next backup agent is in this process...
4986        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4987            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4988            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4989            try {
4990                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4991                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4992                        mBackupTarget.backupMode);
4993            } catch (Exception e) {
4994                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4995                e.printStackTrace();
4996            }
4997        }
4998
4999        if (badApp) {
5000            // todo: Also need to kill application to deal with all
5001            // kinds of exceptions.
5002            handleAppDiedLocked(app, false, true);
5003            return false;
5004        }
5005
5006        if (!didSomething) {
5007            updateOomAdjLocked();
5008        }
5009
5010        return true;
5011    }
5012
5013    @Override
5014    public final void attachApplication(IApplicationThread thread) {
5015        synchronized (this) {
5016            int callingPid = Binder.getCallingPid();
5017            final long origId = Binder.clearCallingIdentity();
5018            attachApplicationLocked(thread, callingPid);
5019            Binder.restoreCallingIdentity(origId);
5020        }
5021    }
5022
5023    @Override
5024    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5025        final long origId = Binder.clearCallingIdentity();
5026        synchronized (this) {
5027            ActivityStack stack = ActivityRecord.getStackLocked(token);
5028            if (stack != null) {
5029                ActivityRecord r =
5030                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5031                if (stopProfiling) {
5032                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5033                        try {
5034                            mProfileFd.close();
5035                        } catch (IOException e) {
5036                        }
5037                        clearProfilerLocked();
5038                    }
5039                }
5040            }
5041        }
5042        Binder.restoreCallingIdentity(origId);
5043    }
5044
5045    void enableScreenAfterBoot() {
5046        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5047                SystemClock.uptimeMillis());
5048        mWindowManager.enableScreenAfterBoot();
5049
5050        synchronized (this) {
5051            updateEventDispatchingLocked();
5052        }
5053    }
5054
5055    @Override
5056    public void showBootMessage(final CharSequence msg, final boolean always) {
5057        enforceNotIsolatedCaller("showBootMessage");
5058        mWindowManager.showBootMessage(msg, always);
5059    }
5060
5061    @Override
5062    public void dismissKeyguardOnNextActivity() {
5063        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5064        final long token = Binder.clearCallingIdentity();
5065        try {
5066            synchronized (this) {
5067                if (DEBUG_LOCKSCREEN) logLockScreen("");
5068                if (mLockScreenShown) {
5069                    mLockScreenShown = false;
5070                    comeOutOfSleepIfNeededLocked();
5071                }
5072                mStackSupervisor.setDismissKeyguard(true);
5073            }
5074        } finally {
5075            Binder.restoreCallingIdentity(token);
5076        }
5077    }
5078
5079    final void finishBooting() {
5080        IntentFilter pkgFilter = new IntentFilter();
5081        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5082        pkgFilter.addDataScheme("package");
5083        mContext.registerReceiver(new BroadcastReceiver() {
5084            @Override
5085            public void onReceive(Context context, Intent intent) {
5086                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5087                if (pkgs != null) {
5088                    for (String pkg : pkgs) {
5089                        synchronized (ActivityManagerService.this) {
5090                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
5091                                    "finished booting")) {
5092                                setResultCode(Activity.RESULT_OK);
5093                                return;
5094                            }
5095                        }
5096                    }
5097                }
5098            }
5099        }, pkgFilter);
5100
5101        synchronized (this) {
5102            // Ensure that any processes we had put on hold are now started
5103            // up.
5104            final int NP = mProcessesOnHold.size();
5105            if (NP > 0) {
5106                ArrayList<ProcessRecord> procs =
5107                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5108                for (int ip=0; ip<NP; ip++) {
5109                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5110                            + procs.get(ip));
5111                    startProcessLocked(procs.get(ip), "on-hold", null);
5112                }
5113            }
5114
5115            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5116                // Start looking for apps that are abusing wake locks.
5117                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5118                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5119                // Tell anyone interested that we are done booting!
5120                SystemProperties.set("sys.boot_completed", "1");
5121                SystemProperties.set("dev.bootcomplete", "1");
5122                for (int i=0; i<mStartedUsers.size(); i++) {
5123                    UserStartedState uss = mStartedUsers.valueAt(i);
5124                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5125                        uss.mState = UserStartedState.STATE_RUNNING;
5126                        final int userId = mStartedUsers.keyAt(i);
5127                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5128                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5129                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5130                        broadcastIntentLocked(null, null, intent, null,
5131                                new IIntentReceiver.Stub() {
5132                                    @Override
5133                                    public void performReceive(Intent intent, int resultCode,
5134                                            String data, Bundle extras, boolean ordered,
5135                                            boolean sticky, int sendingUser) {
5136                                        synchronized (ActivityManagerService.this) {
5137                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5138                                                    true, false);
5139                                        }
5140                                    }
5141                                },
5142                                0, null, null,
5143                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5144                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5145                                userId);
5146                    }
5147                }
5148            }
5149        }
5150    }
5151
5152    final void ensureBootCompleted() {
5153        boolean booting;
5154        boolean enableScreen;
5155        synchronized (this) {
5156            booting = mBooting;
5157            mBooting = false;
5158            enableScreen = !mBooted;
5159            mBooted = true;
5160        }
5161
5162        if (booting) {
5163            finishBooting();
5164        }
5165
5166        if (enableScreen) {
5167            enableScreenAfterBoot();
5168        }
5169    }
5170
5171    @Override
5172    public final void activityResumed(IBinder token) {
5173        final long origId = Binder.clearCallingIdentity();
5174        synchronized(this) {
5175            ActivityStack stack = ActivityRecord.getStackLocked(token);
5176            if (stack != null) {
5177                ActivityRecord.activityResumedLocked(token);
5178            }
5179        }
5180        Binder.restoreCallingIdentity(origId);
5181    }
5182
5183    @Override
5184    public final void activityPaused(IBinder token) {
5185        final long origId = Binder.clearCallingIdentity();
5186        synchronized(this) {
5187            ActivityStack stack = ActivityRecord.getStackLocked(token);
5188            if (stack != null) {
5189                stack.activityPausedLocked(token, false);
5190            }
5191        }
5192        Binder.restoreCallingIdentity(origId);
5193    }
5194
5195    @Override
5196    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5197            CharSequence description) {
5198        if (localLOGV) Slog.v(
5199            TAG, "Activity stopped: token=" + token);
5200
5201        // Refuse possible leaked file descriptors
5202        if (icicle != null && icicle.hasFileDescriptors()) {
5203            throw new IllegalArgumentException("File descriptors passed in Bundle");
5204        }
5205
5206        ActivityRecord r = null;
5207
5208        final long origId = Binder.clearCallingIdentity();
5209
5210        synchronized (this) {
5211            r = ActivityRecord.isInStackLocked(token);
5212            if (r != null) {
5213                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5214            }
5215        }
5216
5217        if (r != null) {
5218            sendPendingThumbnail(r, null, null, null, false);
5219        }
5220
5221        trimApplications();
5222
5223        Binder.restoreCallingIdentity(origId);
5224    }
5225
5226    @Override
5227    public final void activityDestroyed(IBinder token) {
5228        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5229        synchronized (this) {
5230            ActivityStack stack = ActivityRecord.getStackLocked(token);
5231            if (stack != null) {
5232                stack.activityDestroyedLocked(token);
5233            }
5234        }
5235    }
5236
5237    @Override
5238    public String getCallingPackage(IBinder token) {
5239        synchronized (this) {
5240            ActivityRecord r = getCallingRecordLocked(token);
5241            return r != null ? r.info.packageName : null;
5242        }
5243    }
5244
5245    @Override
5246    public ComponentName getCallingActivity(IBinder token) {
5247        synchronized (this) {
5248            ActivityRecord r = getCallingRecordLocked(token);
5249            return r != null ? r.intent.getComponent() : null;
5250        }
5251    }
5252
5253    private ActivityRecord getCallingRecordLocked(IBinder token) {
5254        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5255        if (r == null) {
5256            return null;
5257        }
5258        return r.resultTo;
5259    }
5260
5261    @Override
5262    public ComponentName getActivityClassForToken(IBinder token) {
5263        synchronized(this) {
5264            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5265            if (r == null) {
5266                return null;
5267            }
5268            return r.intent.getComponent();
5269        }
5270    }
5271
5272    @Override
5273    public String getPackageForToken(IBinder token) {
5274        synchronized(this) {
5275            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5276            if (r == null) {
5277                return null;
5278            }
5279            return r.packageName;
5280        }
5281    }
5282
5283    @Override
5284    public IIntentSender getIntentSender(int type,
5285            String packageName, IBinder token, String resultWho,
5286            int requestCode, Intent[] intents, String[] resolvedTypes,
5287            int flags, Bundle options, int userId) {
5288        enforceNotIsolatedCaller("getIntentSender");
5289        // Refuse possible leaked file descriptors
5290        if (intents != null) {
5291            if (intents.length < 1) {
5292                throw new IllegalArgumentException("Intents array length must be >= 1");
5293            }
5294            for (int i=0; i<intents.length; i++) {
5295                Intent intent = intents[i];
5296                if (intent != null) {
5297                    if (intent.hasFileDescriptors()) {
5298                        throw new IllegalArgumentException("File descriptors passed in Intent");
5299                    }
5300                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5301                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5302                        throw new IllegalArgumentException(
5303                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5304                    }
5305                    intents[i] = new Intent(intent);
5306                }
5307            }
5308            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5309                throw new IllegalArgumentException(
5310                        "Intent array length does not match resolvedTypes length");
5311            }
5312        }
5313        if (options != null) {
5314            if (options.hasFileDescriptors()) {
5315                throw new IllegalArgumentException("File descriptors passed in options");
5316            }
5317        }
5318
5319        synchronized(this) {
5320            int callingUid = Binder.getCallingUid();
5321            int origUserId = userId;
5322            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5323                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5324                    "getIntentSender", null);
5325            if (origUserId == UserHandle.USER_CURRENT) {
5326                // We don't want to evaluate this until the pending intent is
5327                // actually executed.  However, we do want to always do the
5328                // security checking for it above.
5329                userId = UserHandle.USER_CURRENT;
5330            }
5331            try {
5332                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5333                    int uid = AppGlobals.getPackageManager()
5334                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5335                    if (!UserHandle.isSameApp(callingUid, uid)) {
5336                        String msg = "Permission Denial: getIntentSender() from pid="
5337                            + Binder.getCallingPid()
5338                            + ", uid=" + Binder.getCallingUid()
5339                            + ", (need uid=" + uid + ")"
5340                            + " is not allowed to send as package " + packageName;
5341                        Slog.w(TAG, msg);
5342                        throw new SecurityException(msg);
5343                    }
5344                }
5345
5346                return getIntentSenderLocked(type, packageName, callingUid, userId,
5347                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5348
5349            } catch (RemoteException e) {
5350                throw new SecurityException(e);
5351            }
5352        }
5353    }
5354
5355    IIntentSender getIntentSenderLocked(int type, String packageName,
5356            int callingUid, int userId, IBinder token, String resultWho,
5357            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5358            Bundle options) {
5359        if (DEBUG_MU)
5360            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5361        ActivityRecord activity = null;
5362        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5363            activity = ActivityRecord.isInStackLocked(token);
5364            if (activity == null) {
5365                return null;
5366            }
5367            if (activity.finishing) {
5368                return null;
5369            }
5370        }
5371
5372        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5373        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5374        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5375        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5376                |PendingIntent.FLAG_UPDATE_CURRENT);
5377
5378        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5379                type, packageName, activity, resultWho,
5380                requestCode, intents, resolvedTypes, flags, options, userId);
5381        WeakReference<PendingIntentRecord> ref;
5382        ref = mIntentSenderRecords.get(key);
5383        PendingIntentRecord rec = ref != null ? ref.get() : null;
5384        if (rec != null) {
5385            if (!cancelCurrent) {
5386                if (updateCurrent) {
5387                    if (rec.key.requestIntent != null) {
5388                        rec.key.requestIntent.replaceExtras(intents != null ?
5389                                intents[intents.length - 1] : null);
5390                    }
5391                    if (intents != null) {
5392                        intents[intents.length-1] = rec.key.requestIntent;
5393                        rec.key.allIntents = intents;
5394                        rec.key.allResolvedTypes = resolvedTypes;
5395                    } else {
5396                        rec.key.allIntents = null;
5397                        rec.key.allResolvedTypes = null;
5398                    }
5399                }
5400                return rec;
5401            }
5402            rec.canceled = true;
5403            mIntentSenderRecords.remove(key);
5404        }
5405        if (noCreate) {
5406            return rec;
5407        }
5408        rec = new PendingIntentRecord(this, key, callingUid);
5409        mIntentSenderRecords.put(key, rec.ref);
5410        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5411            if (activity.pendingResults == null) {
5412                activity.pendingResults
5413                        = new HashSet<WeakReference<PendingIntentRecord>>();
5414            }
5415            activity.pendingResults.add(rec.ref);
5416        }
5417        return rec;
5418    }
5419
5420    @Override
5421    public void cancelIntentSender(IIntentSender sender) {
5422        if (!(sender instanceof PendingIntentRecord)) {
5423            return;
5424        }
5425        synchronized(this) {
5426            PendingIntentRecord rec = (PendingIntentRecord)sender;
5427            try {
5428                int uid = AppGlobals.getPackageManager()
5429                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5430                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5431                    String msg = "Permission Denial: cancelIntentSender() from pid="
5432                        + Binder.getCallingPid()
5433                        + ", uid=" + Binder.getCallingUid()
5434                        + " is not allowed to cancel packges "
5435                        + rec.key.packageName;
5436                    Slog.w(TAG, msg);
5437                    throw new SecurityException(msg);
5438                }
5439            } catch (RemoteException e) {
5440                throw new SecurityException(e);
5441            }
5442            cancelIntentSenderLocked(rec, true);
5443        }
5444    }
5445
5446    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5447        rec.canceled = true;
5448        mIntentSenderRecords.remove(rec.key);
5449        if (cleanActivity && rec.key.activity != null) {
5450            rec.key.activity.pendingResults.remove(rec.ref);
5451        }
5452    }
5453
5454    @Override
5455    public String getPackageForIntentSender(IIntentSender pendingResult) {
5456        if (!(pendingResult instanceof PendingIntentRecord)) {
5457            return null;
5458        }
5459        try {
5460            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5461            return res.key.packageName;
5462        } catch (ClassCastException e) {
5463        }
5464        return null;
5465    }
5466
5467    @Override
5468    public int getUidForIntentSender(IIntentSender sender) {
5469        if (sender instanceof PendingIntentRecord) {
5470            try {
5471                PendingIntentRecord res = (PendingIntentRecord)sender;
5472                return res.uid;
5473            } catch (ClassCastException e) {
5474            }
5475        }
5476        return -1;
5477    }
5478
5479    @Override
5480    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5481        if (!(pendingResult instanceof PendingIntentRecord)) {
5482            return false;
5483        }
5484        try {
5485            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5486            if (res.key.allIntents == null) {
5487                return false;
5488            }
5489            for (int i=0; i<res.key.allIntents.length; i++) {
5490                Intent intent = res.key.allIntents[i];
5491                if (intent.getPackage() != null && intent.getComponent() != null) {
5492                    return false;
5493                }
5494            }
5495            return true;
5496        } catch (ClassCastException e) {
5497        }
5498        return false;
5499    }
5500
5501    @Override
5502    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5503        if (!(pendingResult instanceof PendingIntentRecord)) {
5504            return false;
5505        }
5506        try {
5507            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5508            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5509                return true;
5510            }
5511            return false;
5512        } catch (ClassCastException e) {
5513        }
5514        return false;
5515    }
5516
5517    @Override
5518    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5519        if (!(pendingResult instanceof PendingIntentRecord)) {
5520            return null;
5521        }
5522        try {
5523            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5524            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5525        } catch (ClassCastException e) {
5526        }
5527        return null;
5528    }
5529
5530    @Override
5531    public void setProcessLimit(int max) {
5532        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5533                "setProcessLimit()");
5534        synchronized (this) {
5535            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5536            mProcessLimitOverride = max;
5537        }
5538        trimApplications();
5539    }
5540
5541    @Override
5542    public int getProcessLimit() {
5543        synchronized (this) {
5544            return mProcessLimitOverride;
5545        }
5546    }
5547
5548    void foregroundTokenDied(ForegroundToken token) {
5549        synchronized (ActivityManagerService.this) {
5550            synchronized (mPidsSelfLocked) {
5551                ForegroundToken cur
5552                    = mForegroundProcesses.get(token.pid);
5553                if (cur != token) {
5554                    return;
5555                }
5556                mForegroundProcesses.remove(token.pid);
5557                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5558                if (pr == null) {
5559                    return;
5560                }
5561                pr.forcingToForeground = null;
5562                pr.foregroundServices = false;
5563            }
5564            updateOomAdjLocked();
5565        }
5566    }
5567
5568    @Override
5569    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5570        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5571                "setProcessForeground()");
5572        synchronized(this) {
5573            boolean changed = false;
5574
5575            synchronized (mPidsSelfLocked) {
5576                ProcessRecord pr = mPidsSelfLocked.get(pid);
5577                if (pr == null && isForeground) {
5578                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5579                    return;
5580                }
5581                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5582                if (oldToken != null) {
5583                    oldToken.token.unlinkToDeath(oldToken, 0);
5584                    mForegroundProcesses.remove(pid);
5585                    if (pr != null) {
5586                        pr.forcingToForeground = null;
5587                    }
5588                    changed = true;
5589                }
5590                if (isForeground && token != null) {
5591                    ForegroundToken newToken = new ForegroundToken() {
5592                        @Override
5593                        public void binderDied() {
5594                            foregroundTokenDied(this);
5595                        }
5596                    };
5597                    newToken.pid = pid;
5598                    newToken.token = token;
5599                    try {
5600                        token.linkToDeath(newToken, 0);
5601                        mForegroundProcesses.put(pid, newToken);
5602                        pr.forcingToForeground = token;
5603                        changed = true;
5604                    } catch (RemoteException e) {
5605                        // If the process died while doing this, we will later
5606                        // do the cleanup with the process death link.
5607                    }
5608                }
5609            }
5610
5611            if (changed) {
5612                updateOomAdjLocked();
5613            }
5614        }
5615    }
5616
5617    // =========================================================
5618    // PERMISSIONS
5619    // =========================================================
5620
5621    static class PermissionController extends IPermissionController.Stub {
5622        ActivityManagerService mActivityManagerService;
5623        PermissionController(ActivityManagerService activityManagerService) {
5624            mActivityManagerService = activityManagerService;
5625        }
5626
5627        @Override
5628        public boolean checkPermission(String permission, int pid, int uid) {
5629            return mActivityManagerService.checkPermission(permission, pid,
5630                    uid) == PackageManager.PERMISSION_GRANTED;
5631        }
5632    }
5633
5634    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5635        @Override
5636        public int checkComponentPermission(String permission, int pid, int uid,
5637                int owningUid, boolean exported) {
5638            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5639                    owningUid, exported);
5640        }
5641
5642        @Override
5643        public Object getAMSLock() {
5644            return ActivityManagerService.this;
5645        }
5646    }
5647
5648    /**
5649     * This can be called with or without the global lock held.
5650     */
5651    int checkComponentPermission(String permission, int pid, int uid,
5652            int owningUid, boolean exported) {
5653        // We might be performing an operation on behalf of an indirect binder
5654        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5655        // client identity accordingly before proceeding.
5656        Identity tlsIdentity = sCallerIdentity.get();
5657        if (tlsIdentity != null) {
5658            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5659                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5660            uid = tlsIdentity.uid;
5661            pid = tlsIdentity.pid;
5662        }
5663
5664        if (pid == MY_PID) {
5665            return PackageManager.PERMISSION_GRANTED;
5666        }
5667
5668        return ActivityManager.checkComponentPermission(permission, uid,
5669                owningUid, exported);
5670    }
5671
5672    /**
5673     * As the only public entry point for permissions checking, this method
5674     * can enforce the semantic that requesting a check on a null global
5675     * permission is automatically denied.  (Internally a null permission
5676     * string is used when calling {@link #checkComponentPermission} in cases
5677     * when only uid-based security is needed.)
5678     *
5679     * This can be called with or without the global lock held.
5680     */
5681    @Override
5682    public int checkPermission(String permission, int pid, int uid) {
5683        if (permission == null) {
5684            return PackageManager.PERMISSION_DENIED;
5685        }
5686        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5687    }
5688
5689    /**
5690     * Binder IPC calls go through the public entry point.
5691     * This can be called with or without the global lock held.
5692     */
5693    int checkCallingPermission(String permission) {
5694        return checkPermission(permission,
5695                Binder.getCallingPid(),
5696                UserHandle.getAppId(Binder.getCallingUid()));
5697    }
5698
5699    /**
5700     * This can be called with or without the global lock held.
5701     */
5702    void enforceCallingPermission(String permission, String func) {
5703        if (checkCallingPermission(permission)
5704                == PackageManager.PERMISSION_GRANTED) {
5705            return;
5706        }
5707
5708        String msg = "Permission Denial: " + func + " from pid="
5709                + Binder.getCallingPid()
5710                + ", uid=" + Binder.getCallingUid()
5711                + " requires " + permission;
5712        Slog.w(TAG, msg);
5713        throw new SecurityException(msg);
5714    }
5715
5716    /**
5717     * Determine if UID is holding permissions required to access {@link Uri} in
5718     * the given {@link ProviderInfo}. Final permission checking is always done
5719     * in {@link ContentProvider}.
5720     */
5721    private final boolean checkHoldingPermissionsLocked(
5722            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5723        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5724                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5725
5726        if (pi.applicationInfo.uid == uid) {
5727            return true;
5728        } else if (!pi.exported) {
5729            return false;
5730        }
5731
5732        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5733        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5734        try {
5735            // check if target holds top-level <provider> permissions
5736            if (!readMet && pi.readPermission != null
5737                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5738                readMet = true;
5739            }
5740            if (!writeMet && pi.writePermission != null
5741                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5742                writeMet = true;
5743            }
5744
5745            // track if unprotected read/write is allowed; any denied
5746            // <path-permission> below removes this ability
5747            boolean allowDefaultRead = pi.readPermission == null;
5748            boolean allowDefaultWrite = pi.writePermission == null;
5749
5750            // check if target holds any <path-permission> that match uri
5751            final PathPermission[] pps = pi.pathPermissions;
5752            if (pps != null) {
5753                final String path = uri.getPath();
5754                int i = pps.length;
5755                while (i > 0 && (!readMet || !writeMet)) {
5756                    i--;
5757                    PathPermission pp = pps[i];
5758                    if (pp.match(path)) {
5759                        if (!readMet) {
5760                            final String pprperm = pp.getReadPermission();
5761                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5762                                    + pprperm + " for " + pp.getPath()
5763                                    + ": match=" + pp.match(path)
5764                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5765                            if (pprperm != null) {
5766                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5767                                    readMet = true;
5768                                } else {
5769                                    allowDefaultRead = false;
5770                                }
5771                            }
5772                        }
5773                        if (!writeMet) {
5774                            final String ppwperm = pp.getWritePermission();
5775                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5776                                    + ppwperm + " for " + pp.getPath()
5777                                    + ": match=" + pp.match(path)
5778                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5779                            if (ppwperm != null) {
5780                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5781                                    writeMet = true;
5782                                } else {
5783                                    allowDefaultWrite = false;
5784                                }
5785                            }
5786                        }
5787                    }
5788                }
5789            }
5790
5791            // grant unprotected <provider> read/write, if not blocked by
5792            // <path-permission> above
5793            if (allowDefaultRead) readMet = true;
5794            if (allowDefaultWrite) writeMet = true;
5795
5796        } catch (RemoteException e) {
5797            return false;
5798        }
5799
5800        return readMet && writeMet;
5801    }
5802
5803    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5804        ProviderInfo pi = null;
5805        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5806        if (cpr != null) {
5807            pi = cpr.info;
5808        } else {
5809            try {
5810                pi = AppGlobals.getPackageManager().resolveContentProvider(
5811                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5812            } catch (RemoteException ex) {
5813            }
5814        }
5815        return pi;
5816    }
5817
5818    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5819        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5820        if (targetUris != null) {
5821            return targetUris.get(uri);
5822        } else {
5823            return null;
5824        }
5825    }
5826
5827    private UriPermission findOrCreateUriPermissionLocked(
5828            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5829        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5830        if (targetUris == null) {
5831            targetUris = Maps.newArrayMap();
5832            mGrantedUriPermissions.put(targetUid, targetUris);
5833        }
5834
5835        UriPermission perm = targetUris.get(uri);
5836        if (perm == null) {
5837            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5838            targetUris.put(uri, perm);
5839        }
5840
5841        return perm;
5842    }
5843
5844    private final boolean checkUriPermissionLocked(
5845            Uri uri, int uid, int modeFlags, int minStrength) {
5846        // Root gets to do everything.
5847        if (uid == 0) {
5848            return true;
5849        }
5850        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5851        if (perms == null) return false;
5852        UriPermission perm = perms.get(uri);
5853        if (perm == null) return false;
5854        return perm.getStrength(modeFlags) >= minStrength;
5855    }
5856
5857    @Override
5858    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5859        enforceNotIsolatedCaller("checkUriPermission");
5860
5861        // Another redirected-binder-call permissions check as in
5862        // {@link checkComponentPermission}.
5863        Identity tlsIdentity = sCallerIdentity.get();
5864        if (tlsIdentity != null) {
5865            uid = tlsIdentity.uid;
5866            pid = tlsIdentity.pid;
5867        }
5868
5869        // Our own process gets to do everything.
5870        if (pid == MY_PID) {
5871            return PackageManager.PERMISSION_GRANTED;
5872        }
5873        synchronized(this) {
5874            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5875                    ? PackageManager.PERMISSION_GRANTED
5876                    : PackageManager.PERMISSION_DENIED;
5877        }
5878    }
5879
5880    /**
5881     * Check if the targetPkg can be granted permission to access uri by
5882     * the callingUid using the given modeFlags.  Throws a security exception
5883     * if callingUid is not allowed to do this.  Returns the uid of the target
5884     * if the URI permission grant should be performed; returns -1 if it is not
5885     * needed (for example targetPkg already has permission to access the URI).
5886     * If you already know the uid of the target, you can supply it in
5887     * lastTargetUid else set that to -1.
5888     */
5889    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5890            Uri uri, int modeFlags, int lastTargetUid) {
5891        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5892        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5893                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5894        if (modeFlags == 0) {
5895            return -1;
5896        }
5897
5898        if (targetPkg != null) {
5899            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5900                    "Checking grant " + targetPkg + " permission to " + uri);
5901        }
5902
5903        final IPackageManager pm = AppGlobals.getPackageManager();
5904
5905        // If this is not a content: uri, we can't do anything with it.
5906        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5907            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5908                    "Can't grant URI permission for non-content URI: " + uri);
5909            return -1;
5910        }
5911
5912        final String authority = uri.getAuthority();
5913        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5914        if (pi == null) {
5915            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5916            return -1;
5917        }
5918
5919        int targetUid = lastTargetUid;
5920        if (targetUid < 0 && targetPkg != null) {
5921            try {
5922                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5923                if (targetUid < 0) {
5924                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5925                            "Can't grant URI permission no uid for: " + targetPkg);
5926                    return -1;
5927                }
5928            } catch (RemoteException ex) {
5929                return -1;
5930            }
5931        }
5932
5933        if (targetUid >= 0) {
5934            // First...  does the target actually need this permission?
5935            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5936                // No need to grant the target this permission.
5937                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5938                        "Target " + targetPkg + " already has full permission to " + uri);
5939                return -1;
5940            }
5941        } else {
5942            // First...  there is no target package, so can anyone access it?
5943            boolean allowed = pi.exported;
5944            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5945                if (pi.readPermission != null) {
5946                    allowed = false;
5947                }
5948            }
5949            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5950                if (pi.writePermission != null) {
5951                    allowed = false;
5952                }
5953            }
5954            if (allowed) {
5955                return -1;
5956            }
5957        }
5958
5959        // Second...  is the provider allowing granting of URI permissions?
5960        if (!pi.grantUriPermissions) {
5961            throw new SecurityException("Provider " + pi.packageName
5962                    + "/" + pi.name
5963                    + " does not allow granting of Uri permissions (uri "
5964                    + uri + ")");
5965        }
5966        if (pi.uriPermissionPatterns != null) {
5967            final int N = pi.uriPermissionPatterns.length;
5968            boolean allowed = false;
5969            for (int i=0; i<N; i++) {
5970                if (pi.uriPermissionPatterns[i] != null
5971                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5972                    allowed = true;
5973                    break;
5974                }
5975            }
5976            if (!allowed) {
5977                throw new SecurityException("Provider " + pi.packageName
5978                        + "/" + pi.name
5979                        + " does not allow granting of permission to path of Uri "
5980                        + uri);
5981            }
5982        }
5983
5984        // Third...  does the caller itself have permission to access
5985        // this uri?
5986        if (callingUid != Process.myUid()) {
5987            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5988                // Require they hold a strong enough Uri permission
5989                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
5990                        : UriPermission.STRENGTH_OWNED;
5991                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
5992                    throw new SecurityException("Uid " + callingUid
5993                            + " does not have permission to uri " + uri);
5994                }
5995            }
5996        }
5997
5998        return targetUid;
5999    }
6000
6001    @Override
6002    public int checkGrantUriPermission(int callingUid, String targetPkg,
6003            Uri uri, int modeFlags) {
6004        enforceNotIsolatedCaller("checkGrantUriPermission");
6005        synchronized(this) {
6006            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6007        }
6008    }
6009
6010    void grantUriPermissionUncheckedLocked(
6011            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6012        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6013        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6014                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6015        if (modeFlags == 0) {
6016            return;
6017        }
6018
6019        // So here we are: the caller has the assumed permission
6020        // to the uri, and the target doesn't.  Let's now give this to
6021        // the target.
6022
6023        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6024                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6025
6026        final String authority = uri.getAuthority();
6027        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6028        if (pi == null) {
6029            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6030            return;
6031        }
6032
6033        final UriPermission perm = findOrCreateUriPermissionLocked(
6034                pi.packageName, targetPkg, targetUid, uri);
6035        perm.grantModes(modeFlags, persistable, owner);
6036    }
6037
6038    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6039            int modeFlags, UriPermissionOwner owner) {
6040        if (targetPkg == null) {
6041            throw new NullPointerException("targetPkg");
6042        }
6043
6044        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6045        if (targetUid < 0) {
6046            return;
6047        }
6048
6049        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6050    }
6051
6052    static class NeededUriGrants extends ArrayList<Uri> {
6053        final String targetPkg;
6054        final int targetUid;
6055        final int flags;
6056
6057        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6058            this.targetPkg = targetPkg;
6059            this.targetUid = targetUid;
6060            this.flags = flags;
6061        }
6062    }
6063
6064    /**
6065     * Like checkGrantUriPermissionLocked, but takes an Intent.
6066     */
6067    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6068            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6069        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6070                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6071                + " clip=" + (intent != null ? intent.getClipData() : null)
6072                + " from " + intent + "; flags=0x"
6073                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6074
6075        if (targetPkg == null) {
6076            throw new NullPointerException("targetPkg");
6077        }
6078
6079        if (intent == null) {
6080            return null;
6081        }
6082        Uri data = intent.getData();
6083        ClipData clip = intent.getClipData();
6084        if (data == null && clip == null) {
6085            return null;
6086        }
6087
6088        if (data != null) {
6089            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6090                mode, needed != null ? needed.targetUid : -1);
6091            if (targetUid > 0) {
6092                if (needed == null) {
6093                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6094                }
6095                needed.add(data);
6096            }
6097        }
6098        if (clip != null) {
6099            for (int i=0; i<clip.getItemCount(); i++) {
6100                Uri uri = clip.getItemAt(i).getUri();
6101                if (uri != null) {
6102                    int targetUid = -1;
6103                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6104                            mode, needed != null ? needed.targetUid : -1);
6105                    if (targetUid > 0) {
6106                        if (needed == null) {
6107                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6108                        }
6109                        needed.add(uri);
6110                    }
6111                } else {
6112                    Intent clipIntent = clip.getItemAt(i).getIntent();
6113                    if (clipIntent != null) {
6114                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6115                                callingUid, targetPkg, clipIntent, mode, needed);
6116                        if (newNeeded != null) {
6117                            needed = newNeeded;
6118                        }
6119                    }
6120                }
6121            }
6122        }
6123
6124        return needed;
6125    }
6126
6127    /**
6128     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6129     */
6130    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6131            UriPermissionOwner owner) {
6132        if (needed != null) {
6133            for (int i=0; i<needed.size(); i++) {
6134                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6135                        needed.get(i), needed.flags, owner);
6136            }
6137        }
6138    }
6139
6140    void grantUriPermissionFromIntentLocked(int callingUid,
6141            String targetPkg, Intent intent, UriPermissionOwner owner) {
6142        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6143                intent, intent != null ? intent.getFlags() : 0, null);
6144        if (needed == null) {
6145            return;
6146        }
6147
6148        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6149    }
6150
6151    @Override
6152    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6153            Uri uri, int modeFlags) {
6154        enforceNotIsolatedCaller("grantUriPermission");
6155        synchronized(this) {
6156            final ProcessRecord r = getRecordForAppLocked(caller);
6157            if (r == null) {
6158                throw new SecurityException("Unable to find app for caller "
6159                        + caller
6160                        + " when granting permission to uri " + uri);
6161            }
6162            if (targetPkg == null) {
6163                throw new IllegalArgumentException("null target");
6164            }
6165            if (uri == null) {
6166                throw new IllegalArgumentException("null uri");
6167            }
6168
6169            // Persistable only supported through Intents
6170            Preconditions.checkFlagsArgument(modeFlags,
6171                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6172
6173            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6174                    null);
6175        }
6176    }
6177
6178    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6179        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6180                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6181            ArrayMap<Uri, UriPermission> perms
6182                    = mGrantedUriPermissions.get(perm.targetUid);
6183            if (perms != null) {
6184                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6185                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6186                perms.remove(perm.uri);
6187                if (perms.size() == 0) {
6188                    mGrantedUriPermissions.remove(perm.targetUid);
6189                }
6190            }
6191        }
6192    }
6193
6194    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6195        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6196
6197        final IPackageManager pm = AppGlobals.getPackageManager();
6198        final String authority = uri.getAuthority();
6199        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6200        if (pi == null) {
6201            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6202            return;
6203        }
6204
6205        // Does the caller have this permission on the URI?
6206        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6207            // Right now, if you are not the original owner of the permission,
6208            // you are not allowed to revoke it.
6209            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6210                throw new SecurityException("Uid " + callingUid
6211                        + " does not have permission to uri " + uri);
6212            //}
6213        }
6214
6215        boolean persistChanged = false;
6216
6217        // Go through all of the permissions and remove any that match.
6218        final List<String> SEGMENTS = uri.getPathSegments();
6219        if (SEGMENTS != null) {
6220            final int NS = SEGMENTS.size();
6221            int N = mGrantedUriPermissions.size();
6222            for (int i=0; i<N; i++) {
6223                ArrayMap<Uri, UriPermission> perms
6224                        = mGrantedUriPermissions.valueAt(i);
6225                Iterator<UriPermission> it = perms.values().iterator();
6226            toploop:
6227                while (it.hasNext()) {
6228                    UriPermission perm = it.next();
6229                    Uri targetUri = perm.uri;
6230                    if (!authority.equals(targetUri.getAuthority())) {
6231                        continue;
6232                    }
6233                    List<String> targetSegments = targetUri.getPathSegments();
6234                    if (targetSegments == null) {
6235                        continue;
6236                    }
6237                    if (targetSegments.size() < NS) {
6238                        continue;
6239                    }
6240                    for (int j=0; j<NS; j++) {
6241                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6242                            continue toploop;
6243                        }
6244                    }
6245                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6246                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6247                    persistChanged |= perm.clearModes(modeFlags, true);
6248                    if (perm.modeFlags == 0) {
6249                        it.remove();
6250                    }
6251                }
6252                if (perms.size() == 0) {
6253                    mGrantedUriPermissions.remove(
6254                            mGrantedUriPermissions.keyAt(i));
6255                    N--;
6256                    i--;
6257                }
6258            }
6259        }
6260
6261        if (persistChanged) {
6262            schedulePersistUriGrants();
6263        }
6264    }
6265
6266    @Override
6267    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6268            int modeFlags) {
6269        enforceNotIsolatedCaller("revokeUriPermission");
6270        synchronized(this) {
6271            final ProcessRecord r = getRecordForAppLocked(caller);
6272            if (r == null) {
6273                throw new SecurityException("Unable to find app for caller "
6274                        + caller
6275                        + " when revoking permission to uri " + uri);
6276            }
6277            if (uri == null) {
6278                Slog.w(TAG, "revokeUriPermission: null uri");
6279                return;
6280            }
6281
6282            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6283                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6284            if (modeFlags == 0) {
6285                return;
6286            }
6287
6288            final IPackageManager pm = AppGlobals.getPackageManager();
6289            final String authority = uri.getAuthority();
6290            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6291            if (pi == null) {
6292                Slog.w(TAG, "No content provider found for permission revoke: "
6293                        + uri.toSafeString());
6294                return;
6295            }
6296
6297            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6298        }
6299    }
6300
6301    /**
6302     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6303     * given package.
6304     *
6305     * @param packageName Package name to match, or {@code null} to apply to all
6306     *            packages.
6307     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6308     *            to all users.
6309     * @param persistable If persistable grants should be removed.
6310     */
6311    private void removeUriPermissionsForPackageLocked(
6312            String packageName, int userHandle, boolean persistable) {
6313        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6314            throw new IllegalArgumentException("Must narrow by either package or user");
6315        }
6316
6317        boolean persistChanged = false;
6318
6319        final int size = mGrantedUriPermissions.size();
6320        for (int i = 0; i < size; i++) {
6321            // Only inspect grants matching user
6322            if (userHandle == UserHandle.USER_ALL
6323                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6324                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6325                        .values().iterator();
6326                while (it.hasNext()) {
6327                    final UriPermission perm = it.next();
6328
6329                    // Only inspect grants matching package
6330                    if (packageName == null || perm.sourcePkg.equals(packageName)
6331                            || perm.targetPkg.equals(packageName)) {
6332                        persistChanged |= perm.clearModes(~0, persistable);
6333
6334                        // Only remove when no modes remain; any persisted grants
6335                        // will keep this alive.
6336                        if (perm.modeFlags == 0) {
6337                            it.remove();
6338                        }
6339                    }
6340                }
6341            }
6342        }
6343
6344        if (persistChanged) {
6345            schedulePersistUriGrants();
6346        }
6347    }
6348
6349    @Override
6350    public IBinder newUriPermissionOwner(String name) {
6351        enforceNotIsolatedCaller("newUriPermissionOwner");
6352        synchronized(this) {
6353            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6354            return owner.getExternalTokenLocked();
6355        }
6356    }
6357
6358    @Override
6359    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6360            Uri uri, int modeFlags) {
6361        synchronized(this) {
6362            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6363            if (owner == null) {
6364                throw new IllegalArgumentException("Unknown owner: " + token);
6365            }
6366            if (fromUid != Binder.getCallingUid()) {
6367                if (Binder.getCallingUid() != Process.myUid()) {
6368                    // Only system code can grant URI permissions on behalf
6369                    // of other users.
6370                    throw new SecurityException("nice try");
6371                }
6372            }
6373            if (targetPkg == null) {
6374                throw new IllegalArgumentException("null target");
6375            }
6376            if (uri == null) {
6377                throw new IllegalArgumentException("null uri");
6378            }
6379
6380            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6381        }
6382    }
6383
6384    @Override
6385    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6386        synchronized(this) {
6387            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6388            if (owner == null) {
6389                throw new IllegalArgumentException("Unknown owner: " + token);
6390            }
6391
6392            if (uri == null) {
6393                owner.removeUriPermissionsLocked(mode);
6394            } else {
6395                owner.removeUriPermissionLocked(uri, mode);
6396            }
6397        }
6398    }
6399
6400    private void schedulePersistUriGrants() {
6401        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6402            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6403                    10 * DateUtils.SECOND_IN_MILLIS);
6404        }
6405    }
6406
6407    private void writeGrantedUriPermissions() {
6408        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6409
6410        // Snapshot permissions so we can persist without lock
6411        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6412        synchronized (this) {
6413            final int size = mGrantedUriPermissions.size();
6414            for (int i = 0 ; i < size; i++) {
6415                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6416                    if (perm.persistedModeFlags != 0) {
6417                        persist.add(perm.snapshot());
6418                    }
6419                }
6420            }
6421        }
6422
6423        FileOutputStream fos = null;
6424        try {
6425            fos = mGrantFile.startWrite();
6426
6427            XmlSerializer out = new FastXmlSerializer();
6428            out.setOutput(fos, "utf-8");
6429            out.startDocument(null, true);
6430            out.startTag(null, TAG_URI_GRANTS);
6431            for (UriPermission.Snapshot perm : persist) {
6432                out.startTag(null, TAG_URI_GRANT);
6433                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6434                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6435                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6436                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6437                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6438                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6439                out.endTag(null, TAG_URI_GRANT);
6440            }
6441            out.endTag(null, TAG_URI_GRANTS);
6442            out.endDocument();
6443
6444            mGrantFile.finishWrite(fos);
6445        } catch (IOException e) {
6446            if (fos != null) {
6447                mGrantFile.failWrite(fos);
6448            }
6449        }
6450    }
6451
6452    private void readGrantedUriPermissionsLocked() {
6453        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6454
6455        final long now = System.currentTimeMillis();
6456
6457        FileInputStream fis = null;
6458        try {
6459            fis = mGrantFile.openRead();
6460            final XmlPullParser in = Xml.newPullParser();
6461            in.setInput(fis, null);
6462
6463            int type;
6464            while ((type = in.next()) != END_DOCUMENT) {
6465                final String tag = in.getName();
6466                if (type == START_TAG) {
6467                    if (TAG_URI_GRANT.equals(tag)) {
6468                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6469                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6470                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6471                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6472                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6473                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6474
6475                        // Sanity check that provider still belongs to source package
6476                        final ProviderInfo pi = getProviderInfoLocked(
6477                                uri.getAuthority(), userHandle);
6478                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6479                            int targetUid = -1;
6480                            try {
6481                                targetUid = AppGlobals.getPackageManager()
6482                                        .getPackageUid(targetPkg, userHandle);
6483                            } catch (RemoteException e) {
6484                            }
6485                            if (targetUid != -1) {
6486                                final UriPermission perm = findOrCreateUriPermissionLocked(
6487                                        sourcePkg, targetPkg, targetUid, uri);
6488                                perm.initPersistedModes(modeFlags, createdTime);
6489                            }
6490                        } else {
6491                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6492                                    + " but instead found " + pi);
6493                        }
6494                    }
6495                }
6496            }
6497        } catch (FileNotFoundException e) {
6498            // Missing grants is okay
6499        } catch (IOException e) {
6500            Log.wtf(TAG, "Failed reading Uri grants", e);
6501        } catch (XmlPullParserException e) {
6502            Log.wtf(TAG, "Failed reading Uri grants", e);
6503        } finally {
6504            IoUtils.closeQuietly(fis);
6505        }
6506    }
6507
6508    @Override
6509    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6510        enforceNotIsolatedCaller("takePersistableUriPermission");
6511
6512        Preconditions.checkFlagsArgument(modeFlags,
6513                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6514
6515        synchronized (this) {
6516            final int callingUid = Binder.getCallingUid();
6517            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6518            if (perm == null) {
6519                throw new SecurityException("No permission grant found for UID " + callingUid
6520                        + " and Uri " + uri.toSafeString());
6521            }
6522
6523            boolean persistChanged = perm.takePersistableModes(modeFlags);
6524            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6525
6526            if (persistChanged) {
6527                schedulePersistUriGrants();
6528            }
6529        }
6530    }
6531
6532    @Override
6533    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6534        enforceNotIsolatedCaller("releasePersistableUriPermission");
6535
6536        Preconditions.checkFlagsArgument(modeFlags,
6537                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6538
6539        synchronized (this) {
6540            final int callingUid = Binder.getCallingUid();
6541
6542            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6543            if (perm == null) {
6544                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6545                        + uri.toSafeString());
6546                return;
6547            }
6548
6549            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6550            removeUriPermissionIfNeededLocked(perm);
6551            if (persistChanged) {
6552                schedulePersistUriGrants();
6553            }
6554        }
6555    }
6556
6557    /**
6558     * Prune any older {@link UriPermission} for the given UID until outstanding
6559     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6560     *
6561     * @return if any mutations occured that require persisting.
6562     */
6563    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6564        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6565        if (perms == null) return false;
6566        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6567
6568        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6569        for (UriPermission perm : perms.values()) {
6570            if (perm.persistedModeFlags != 0) {
6571                persisted.add(perm);
6572            }
6573        }
6574
6575        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6576        if (trimCount <= 0) return false;
6577
6578        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6579        for (int i = 0; i < trimCount; i++) {
6580            final UriPermission perm = persisted.get(i);
6581
6582            if (DEBUG_URI_PERMISSION) {
6583                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6584            }
6585
6586            perm.releasePersistableModes(~0);
6587            removeUriPermissionIfNeededLocked(perm);
6588        }
6589
6590        return true;
6591    }
6592
6593    @Override
6594    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6595            String packageName, boolean incoming) {
6596        enforceNotIsolatedCaller("getPersistedUriPermissions");
6597        Preconditions.checkNotNull(packageName, "packageName");
6598
6599        final int callingUid = Binder.getCallingUid();
6600        final IPackageManager pm = AppGlobals.getPackageManager();
6601        try {
6602            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6603            if (packageUid != callingUid) {
6604                throw new SecurityException(
6605                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6606            }
6607        } catch (RemoteException e) {
6608            throw new SecurityException("Failed to verify package name ownership");
6609        }
6610
6611        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6612        synchronized (this) {
6613            if (incoming) {
6614                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6615                if (perms == null) {
6616                    Slog.w(TAG, "No permission grants found for " + packageName);
6617                } else {
6618                    final int size = perms.size();
6619                    for (int i = 0; i < size; i++) {
6620                        final UriPermission perm = perms.valueAt(i);
6621                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6622                            result.add(perm.buildPersistedPublicApiObject());
6623                        }
6624                    }
6625                }
6626            } else {
6627                final int size = mGrantedUriPermissions.size();
6628                for (int i = 0; i < size; i++) {
6629                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6630                    final int permsSize = perms.size();
6631                    for (int j = 0; j < permsSize; j++) {
6632                        final UriPermission perm = perms.valueAt(j);
6633                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6634                            result.add(perm.buildPersistedPublicApiObject());
6635                        }
6636                    }
6637                }
6638            }
6639        }
6640        return new ParceledListSlice<android.content.UriPermission>(result);
6641    }
6642
6643    @Override
6644    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6645        synchronized (this) {
6646            ProcessRecord app =
6647                who != null ? getRecordForAppLocked(who) : null;
6648            if (app == null) return;
6649
6650            Message msg = Message.obtain();
6651            msg.what = WAIT_FOR_DEBUGGER_MSG;
6652            msg.obj = app;
6653            msg.arg1 = waiting ? 1 : 0;
6654            mHandler.sendMessage(msg);
6655        }
6656    }
6657
6658    @Override
6659    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6660        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6661        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6662        outInfo.availMem = Process.getFreeMemory();
6663        outInfo.totalMem = Process.getTotalMemory();
6664        outInfo.threshold = homeAppMem;
6665        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6666        outInfo.hiddenAppThreshold = cachedAppMem;
6667        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6668                ProcessList.SERVICE_ADJ);
6669        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6670                ProcessList.VISIBLE_APP_ADJ);
6671        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6672                ProcessList.FOREGROUND_APP_ADJ);
6673    }
6674
6675    // =========================================================
6676    // TASK MANAGEMENT
6677    // =========================================================
6678
6679    @Override
6680    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6681                         IThumbnailReceiver receiver) {
6682        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6683
6684        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6685        ActivityRecord topRecord = null;
6686
6687        synchronized(this) {
6688            if (localLOGV) Slog.v(
6689                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6690                + ", receiver=" + receiver);
6691
6692            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6693                    != PackageManager.PERMISSION_GRANTED) {
6694                if (receiver != null) {
6695                    // If the caller wants to wait for pending thumbnails,
6696                    // it ain't gonna get them.
6697                    try {
6698                        receiver.finished();
6699                    } catch (RemoteException ex) {
6700                    }
6701                }
6702                String msg = "Permission Denial: getTasks() from pid="
6703                        + Binder.getCallingPid()
6704                        + ", uid=" + Binder.getCallingUid()
6705                        + " requires " + android.Manifest.permission.GET_TASKS;
6706                Slog.w(TAG, msg);
6707                throw new SecurityException(msg);
6708            }
6709
6710            // TODO: Improve with MRU list from all ActivityStacks.
6711            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6712
6713            if (!pending.pendingRecords.isEmpty()) {
6714                mPendingThumbnails.add(pending);
6715            }
6716        }
6717
6718        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6719
6720        if (topRecord != null) {
6721            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6722            try {
6723                IApplicationThread topThumbnail = topRecord.app.thread;
6724                topThumbnail.requestThumbnail(topRecord.appToken);
6725            } catch (Exception e) {
6726                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6727                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6728            }
6729        }
6730
6731        if (pending == null && receiver != null) {
6732            // In this case all thumbnails were available and the client
6733            // is being asked to be told when the remaining ones come in...
6734            // which is unusually, since the top-most currently running
6735            // activity should never have a canned thumbnail!  Oh well.
6736            try {
6737                receiver.finished();
6738            } catch (RemoteException ex) {
6739            }
6740        }
6741
6742        return list;
6743    }
6744
6745    TaskRecord getMostRecentTask() {
6746        return mRecentTasks.get(0);
6747    }
6748
6749    @Override
6750    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6751            int flags, int userId) {
6752        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6753                false, true, "getRecentTasks", null);
6754
6755        synchronized (this) {
6756            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6757                    "getRecentTasks()");
6758            final boolean detailed = checkCallingPermission(
6759                    android.Manifest.permission.GET_DETAILED_TASKS)
6760                    == PackageManager.PERMISSION_GRANTED;
6761
6762            IPackageManager pm = AppGlobals.getPackageManager();
6763
6764            final int N = mRecentTasks.size();
6765            ArrayList<ActivityManager.RecentTaskInfo> res
6766                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6767                            maxNum < N ? maxNum : N);
6768            for (int i=0; i<N && maxNum > 0; i++) {
6769                TaskRecord tr = mRecentTasks.get(i);
6770                // Only add calling user's recent tasks
6771                if (tr.userId != userId) continue;
6772                // Return the entry if desired by the caller.  We always return
6773                // the first entry, because callers always expect this to be the
6774                // foreground app.  We may filter others if the caller has
6775                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6776                // we should exclude the entry.
6777
6778                if (i == 0
6779                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6780                        || (tr.intent == null)
6781                        || ((tr.intent.getFlags()
6782                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6783                    ActivityManager.RecentTaskInfo rti
6784                            = new ActivityManager.RecentTaskInfo();
6785                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6786                    rti.persistentId = tr.taskId;
6787                    rti.baseIntent = new Intent(
6788                            tr.intent != null ? tr.intent : tr.affinityIntent);
6789                    if (!detailed) {
6790                        rti.baseIntent.replaceExtras((Bundle)null);
6791                    }
6792                    rti.origActivity = tr.origActivity;
6793                    rti.description = tr.lastDescription;
6794                    rti.stackId = tr.stack.mStackId;
6795
6796                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6797                        // Check whether this activity is currently available.
6798                        try {
6799                            if (rti.origActivity != null) {
6800                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6801                                        == null) {
6802                                    continue;
6803                                }
6804                            } else if (rti.baseIntent != null) {
6805                                if (pm.queryIntentActivities(rti.baseIntent,
6806                                        null, 0, userId) == null) {
6807                                    continue;
6808                                }
6809                            }
6810                        } catch (RemoteException e) {
6811                            // Will never happen.
6812                        }
6813                    }
6814
6815                    res.add(rti);
6816                    maxNum--;
6817                }
6818            }
6819            return res;
6820        }
6821    }
6822
6823    private TaskRecord recentTaskForIdLocked(int id) {
6824        final int N = mRecentTasks.size();
6825            for (int i=0; i<N; i++) {
6826                TaskRecord tr = mRecentTasks.get(i);
6827                if (tr.taskId == id) {
6828                    return tr;
6829                }
6830            }
6831            return null;
6832    }
6833
6834    @Override
6835    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6836        synchronized (this) {
6837            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6838                    "getTaskThumbnails()");
6839            TaskRecord tr = recentTaskForIdLocked(id);
6840            if (tr != null) {
6841                return tr.getTaskThumbnailsLocked();
6842            }
6843        }
6844        return null;
6845    }
6846
6847    @Override
6848    public Bitmap getTaskTopThumbnail(int id) {
6849        synchronized (this) {
6850            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6851                    "getTaskTopThumbnail()");
6852            TaskRecord tr = recentTaskForIdLocked(id);
6853            if (tr != null) {
6854                return tr.getTaskTopThumbnailLocked();
6855            }
6856        }
6857        return null;
6858    }
6859
6860    @Override
6861    public boolean removeSubTask(int taskId, int subTaskIndex) {
6862        synchronized (this) {
6863            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6864                    "removeSubTask()");
6865            long ident = Binder.clearCallingIdentity();
6866            try {
6867                TaskRecord tr = recentTaskForIdLocked(taskId);
6868                if (tr != null) {
6869                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6870                }
6871                return false;
6872            } finally {
6873                Binder.restoreCallingIdentity(ident);
6874            }
6875        }
6876    }
6877
6878    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6879        if (!pr.killedByAm) {
6880            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6881            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6882                    pr.processName, pr.setAdj, reason);
6883            pr.killedByAm = true;
6884            Process.killProcessQuiet(pr.pid);
6885        }
6886    }
6887
6888    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6889        tr.disposeThumbnail();
6890        mRecentTasks.remove(tr);
6891        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6892        Intent baseIntent = new Intent(
6893                tr.intent != null ? tr.intent : tr.affinityIntent);
6894        ComponentName component = baseIntent.getComponent();
6895        if (component == null) {
6896            Slog.w(TAG, "Now component for base intent of task: " + tr);
6897            return;
6898        }
6899
6900        // Find any running services associated with this app.
6901        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6902
6903        if (killProcesses) {
6904            // Find any running processes associated with this app.
6905            final String pkg = component.getPackageName();
6906            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6907            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6908            for (int i=0; i<pmap.size(); i++) {
6909                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6910                for (int j=0; j<uids.size(); j++) {
6911                    ProcessRecord proc = uids.valueAt(j);
6912                    if (proc.userId != tr.userId) {
6913                        continue;
6914                    }
6915                    if (!proc.pkgList.containsKey(pkg)) {
6916                        continue;
6917                    }
6918                    procs.add(proc);
6919                }
6920            }
6921
6922            // Kill the running processes.
6923            for (int i=0; i<procs.size(); i++) {
6924                ProcessRecord pr = procs.get(i);
6925                if (pr == mHomeProcess) {
6926                    // Don't kill the home process along with tasks from the same package.
6927                    continue;
6928                }
6929                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6930                    killUnneededProcessLocked(pr, "remove task");
6931                } else {
6932                    pr.waitingToKill = "remove task";
6933                }
6934            }
6935        }
6936    }
6937
6938    @Override
6939    public boolean removeTask(int taskId, int flags) {
6940        synchronized (this) {
6941            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6942                    "removeTask()");
6943            long ident = Binder.clearCallingIdentity();
6944            try {
6945                TaskRecord tr = recentTaskForIdLocked(taskId);
6946                if (tr != null) {
6947                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
6948                    if (r != null) {
6949                        cleanUpRemovedTaskLocked(tr, flags);
6950                        return true;
6951                    }
6952                    if (tr.mActivities.size() == 0) {
6953                        // Caller is just removing a recent task that is
6954                        // not actively running.  That is easy!
6955                        cleanUpRemovedTaskLocked(tr, flags);
6956                        return true;
6957                    }
6958                    Slog.w(TAG, "removeTask: task " + taskId
6959                            + " does not have activities to remove, "
6960                            + " but numActivities=" + tr.numActivities
6961                            + ": " + tr);
6962                }
6963            } finally {
6964                Binder.restoreCallingIdentity(ident);
6965            }
6966        }
6967        return false;
6968    }
6969
6970    /**
6971     * TODO: Add mController hook
6972     */
6973    @Override
6974    public void moveTaskToFront(int task, int flags, Bundle options) {
6975        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6976                "moveTaskToFront()");
6977
6978        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
6979        synchronized(this) {
6980            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6981                    Binder.getCallingUid(), "Task to front")) {
6982                ActivityOptions.abort(options);
6983                return;
6984            }
6985            final long origId = Binder.clearCallingIdentity();
6986            try {
6987                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
6988            } finally {
6989                Binder.restoreCallingIdentity(origId);
6990            }
6991            ActivityOptions.abort(options);
6992        }
6993    }
6994
6995    @Override
6996    public void moveTaskToBack(int taskId) {
6997        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6998                "moveTaskToBack()");
6999
7000        synchronized(this) {
7001            TaskRecord tr = recentTaskForIdLocked(taskId);
7002            if (tr != null) {
7003                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7004                ActivityStack stack = tr.stack;
7005                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7006                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7007                            Binder.getCallingUid(), "Task to back")) {
7008                        return;
7009                    }
7010                }
7011                final long origId = Binder.clearCallingIdentity();
7012                try {
7013                    stack.moveTaskToBackLocked(taskId, null);
7014                } finally {
7015                    Binder.restoreCallingIdentity(origId);
7016                }
7017            }
7018        }
7019    }
7020
7021    /**
7022     * Moves an activity, and all of the other activities within the same task, to the bottom
7023     * of the history stack.  The activity's order within the task is unchanged.
7024     *
7025     * @param token A reference to the activity we wish to move
7026     * @param nonRoot If false then this only works if the activity is the root
7027     *                of a task; if true it will work for any activity in a task.
7028     * @return Returns true if the move completed, false if not.
7029     */
7030    @Override
7031    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7032        enforceNotIsolatedCaller("moveActivityTaskToBack");
7033        synchronized(this) {
7034            final long origId = Binder.clearCallingIdentity();
7035            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7036            if (taskId >= 0) {
7037                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7038            }
7039            Binder.restoreCallingIdentity(origId);
7040        }
7041        return false;
7042    }
7043
7044    @Override
7045    public void moveTaskBackwards(int task) {
7046        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7047                "moveTaskBackwards()");
7048
7049        synchronized(this) {
7050            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7051                    Binder.getCallingUid(), "Task backwards")) {
7052                return;
7053            }
7054            final long origId = Binder.clearCallingIdentity();
7055            moveTaskBackwardsLocked(task);
7056            Binder.restoreCallingIdentity(origId);
7057        }
7058    }
7059
7060    private final void moveTaskBackwardsLocked(int task) {
7061        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7062    }
7063
7064    @Override
7065    public IBinder getHomeActivityToken() throws RemoteException {
7066        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7067                "getHomeActivityToken()");
7068        synchronized (this) {
7069            return mStackSupervisor.getHomeActivityToken();
7070        }
7071    }
7072
7073    @Override
7074    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7075            IActivityContainerCallback callback) throws RemoteException {
7076        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7077                "createActivityContainer()");
7078        synchronized (this) {
7079            if (parentActivityToken == null) {
7080                throw new IllegalArgumentException("parent token must not be null");
7081            }
7082            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7083            if (r == null) {
7084                return null;
7085            }
7086            return mStackSupervisor.createActivityContainer(r, callback);
7087        }
7088    }
7089
7090    @Override
7091    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7092            throws RemoteException {
7093        synchronized (this) {
7094            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7095            if (stack != null) {
7096                return stack.mActivityContainer;
7097            }
7098            return null;
7099        }
7100    }
7101
7102    @Override
7103    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7104        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7105                "moveTaskToStack()");
7106        if (stackId == HOME_STACK_ID) {
7107            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7108                    new RuntimeException("here").fillInStackTrace());
7109        }
7110        synchronized (this) {
7111            long ident = Binder.clearCallingIdentity();
7112            try {
7113                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7114                        + stackId + " toTop=" + toTop);
7115                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7116            } finally {
7117                Binder.restoreCallingIdentity(ident);
7118            }
7119        }
7120    }
7121
7122    @Override
7123    public void resizeStack(int stackBoxId, Rect bounds) {
7124        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7125                "resizeStackBox()");
7126        long ident = Binder.clearCallingIdentity();
7127        try {
7128            mWindowManager.resizeStack(stackBoxId, bounds);
7129        } finally {
7130            Binder.restoreCallingIdentity(ident);
7131        }
7132    }
7133
7134    @Override
7135    public List<StackInfo> getAllStackInfos() {
7136        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7137                "getAllStackInfos()");
7138        long ident = Binder.clearCallingIdentity();
7139        try {
7140            synchronized (this) {
7141                return mStackSupervisor.getAllStackInfosLocked();
7142            }
7143        } finally {
7144            Binder.restoreCallingIdentity(ident);
7145        }
7146    }
7147
7148    @Override
7149    public StackInfo getStackInfo(int stackId) {
7150        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7151                "getStackInfo()");
7152        long ident = Binder.clearCallingIdentity();
7153        try {
7154            synchronized (this) {
7155                return mStackSupervisor.getStackInfoLocked(stackId);
7156            }
7157        } finally {
7158            Binder.restoreCallingIdentity(ident);
7159        }
7160    }
7161
7162    @Override
7163    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7164        synchronized(this) {
7165            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7166        }
7167    }
7168
7169    // =========================================================
7170    // THUMBNAILS
7171    // =========================================================
7172
7173    public void reportThumbnail(IBinder token,
7174            Bitmap thumbnail, CharSequence description) {
7175        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7176        final long origId = Binder.clearCallingIdentity();
7177        sendPendingThumbnail(null, token, thumbnail, description, true);
7178        Binder.restoreCallingIdentity(origId);
7179    }
7180
7181    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7182            Bitmap thumbnail, CharSequence description, boolean always) {
7183        TaskRecord task;
7184        ArrayList<PendingThumbnailsRecord> receivers = null;
7185
7186        //System.out.println("Send pending thumbnail: " + r);
7187
7188        synchronized(this) {
7189            if (r == null) {
7190                r = ActivityRecord.isInStackLocked(token);
7191                if (r == null) {
7192                    return;
7193                }
7194            }
7195            if (thumbnail == null && r.thumbHolder != null) {
7196                thumbnail = r.thumbHolder.lastThumbnail;
7197                description = r.thumbHolder.lastDescription;
7198            }
7199            if (thumbnail == null && !always) {
7200                // If there is no thumbnail, and this entry is not actually
7201                // going away, then abort for now and pick up the next
7202                // thumbnail we get.
7203                return;
7204            }
7205            task = r.task;
7206
7207            int N = mPendingThumbnails.size();
7208            int i=0;
7209            while (i<N) {
7210                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7211                //System.out.println("Looking in " + pr.pendingRecords);
7212                if (pr.pendingRecords.remove(r)) {
7213                    if (receivers == null) {
7214                        receivers = new ArrayList<PendingThumbnailsRecord>();
7215                    }
7216                    receivers.add(pr);
7217                    if (pr.pendingRecords.size() == 0) {
7218                        pr.finished = true;
7219                        mPendingThumbnails.remove(i);
7220                        N--;
7221                        continue;
7222                    }
7223                }
7224                i++;
7225            }
7226        }
7227
7228        if (receivers != null) {
7229            final int N = receivers.size();
7230            for (int i=0; i<N; i++) {
7231                try {
7232                    PendingThumbnailsRecord pr = receivers.get(i);
7233                    pr.receiver.newThumbnail(
7234                        task != null ? task.taskId : -1, thumbnail, description);
7235                    if (pr.finished) {
7236                        pr.receiver.finished();
7237                    }
7238                } catch (Exception e) {
7239                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7240                }
7241            }
7242        }
7243    }
7244
7245    // =========================================================
7246    // CONTENT PROVIDERS
7247    // =========================================================
7248
7249    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7250        List<ProviderInfo> providers = null;
7251        try {
7252            providers = AppGlobals.getPackageManager().
7253                queryContentProviders(app.processName, app.uid,
7254                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7255        } catch (RemoteException ex) {
7256        }
7257        if (DEBUG_MU)
7258            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7259        int userId = app.userId;
7260        if (providers != null) {
7261            int N = providers.size();
7262            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7263            for (int i=0; i<N; i++) {
7264                ProviderInfo cpi =
7265                    (ProviderInfo)providers.get(i);
7266                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7267                        cpi.name, cpi.flags);
7268                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7269                    // This is a singleton provider, but a user besides the
7270                    // default user is asking to initialize a process it runs
7271                    // in...  well, no, it doesn't actually run in this process,
7272                    // it runs in the process of the default user.  Get rid of it.
7273                    providers.remove(i);
7274                    N--;
7275                    i--;
7276                    continue;
7277                }
7278
7279                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7280                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7281                if (cpr == null) {
7282                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7283                    mProviderMap.putProviderByClass(comp, cpr);
7284                }
7285                if (DEBUG_MU)
7286                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7287                app.pubProviders.put(cpi.name, cpr);
7288                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7289                    // Don't add this if it is a platform component that is marked
7290                    // to run in multiple processes, because this is actually
7291                    // part of the framework so doesn't make sense to track as a
7292                    // separate apk in the process.
7293                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7294                }
7295                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7296            }
7297        }
7298        return providers;
7299    }
7300
7301    /**
7302     * Check if {@link ProcessRecord} has a possible chance at accessing the
7303     * given {@link ProviderInfo}. Final permission checking is always done
7304     * in {@link ContentProvider}.
7305     */
7306    private final String checkContentProviderPermissionLocked(
7307            ProviderInfo cpi, ProcessRecord r) {
7308        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7309        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7310        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7311                cpi.applicationInfo.uid, cpi.exported)
7312                == PackageManager.PERMISSION_GRANTED) {
7313            return null;
7314        }
7315        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7316                cpi.applicationInfo.uid, cpi.exported)
7317                == PackageManager.PERMISSION_GRANTED) {
7318            return null;
7319        }
7320
7321        PathPermission[] pps = cpi.pathPermissions;
7322        if (pps != null) {
7323            int i = pps.length;
7324            while (i > 0) {
7325                i--;
7326                PathPermission pp = pps[i];
7327                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7328                        cpi.applicationInfo.uid, cpi.exported)
7329                        == PackageManager.PERMISSION_GRANTED) {
7330                    return null;
7331                }
7332                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7333                        cpi.applicationInfo.uid, cpi.exported)
7334                        == PackageManager.PERMISSION_GRANTED) {
7335                    return null;
7336                }
7337            }
7338        }
7339
7340        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7341        if (perms != null) {
7342            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7343                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7344                    return null;
7345                }
7346            }
7347        }
7348
7349        String msg;
7350        if (!cpi.exported) {
7351            msg = "Permission Denial: opening provider " + cpi.name
7352                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7353                    + ", uid=" + callingUid + ") that is not exported from uid "
7354                    + cpi.applicationInfo.uid;
7355        } else {
7356            msg = "Permission Denial: opening provider " + cpi.name
7357                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7358                    + ", uid=" + callingUid + ") requires "
7359                    + cpi.readPermission + " or " + cpi.writePermission;
7360        }
7361        Slog.w(TAG, msg);
7362        return msg;
7363    }
7364
7365    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7366            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7367        if (r != null) {
7368            for (int i=0; i<r.conProviders.size(); i++) {
7369                ContentProviderConnection conn = r.conProviders.get(i);
7370                if (conn.provider == cpr) {
7371                    if (DEBUG_PROVIDER) Slog.v(TAG,
7372                            "Adding provider requested by "
7373                            + r.processName + " from process "
7374                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7375                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7376                    if (stable) {
7377                        conn.stableCount++;
7378                        conn.numStableIncs++;
7379                    } else {
7380                        conn.unstableCount++;
7381                        conn.numUnstableIncs++;
7382                    }
7383                    return conn;
7384                }
7385            }
7386            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7387            if (stable) {
7388                conn.stableCount = 1;
7389                conn.numStableIncs = 1;
7390            } else {
7391                conn.unstableCount = 1;
7392                conn.numUnstableIncs = 1;
7393            }
7394            cpr.connections.add(conn);
7395            r.conProviders.add(conn);
7396            return conn;
7397        }
7398        cpr.addExternalProcessHandleLocked(externalProcessToken);
7399        return null;
7400    }
7401
7402    boolean decProviderCountLocked(ContentProviderConnection conn,
7403            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7404        if (conn != null) {
7405            cpr = conn.provider;
7406            if (DEBUG_PROVIDER) Slog.v(TAG,
7407                    "Removing provider requested by "
7408                    + conn.client.processName + " from process "
7409                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7410                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7411            if (stable) {
7412                conn.stableCount--;
7413            } else {
7414                conn.unstableCount--;
7415            }
7416            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7417                cpr.connections.remove(conn);
7418                conn.client.conProviders.remove(conn);
7419                return true;
7420            }
7421            return false;
7422        }
7423        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7424        return false;
7425    }
7426
7427    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7428            String name, IBinder token, boolean stable, int userId) {
7429        ContentProviderRecord cpr;
7430        ContentProviderConnection conn = null;
7431        ProviderInfo cpi = null;
7432
7433        synchronized(this) {
7434            ProcessRecord r = null;
7435            if (caller != null) {
7436                r = getRecordForAppLocked(caller);
7437                if (r == null) {
7438                    throw new SecurityException(
7439                            "Unable to find app for caller " + caller
7440                          + " (pid=" + Binder.getCallingPid()
7441                          + ") when getting content provider " + name);
7442                }
7443            }
7444
7445            // First check if this content provider has been published...
7446            cpr = mProviderMap.getProviderByName(name, userId);
7447            boolean providerRunning = cpr != null;
7448            if (providerRunning) {
7449                cpi = cpr.info;
7450                String msg;
7451                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7452                    throw new SecurityException(msg);
7453                }
7454
7455                if (r != null && cpr.canRunHere(r)) {
7456                    // This provider has been published or is in the process
7457                    // of being published...  but it is also allowed to run
7458                    // in the caller's process, so don't make a connection
7459                    // and just let the caller instantiate its own instance.
7460                    ContentProviderHolder holder = cpr.newHolder(null);
7461                    // don't give caller the provider object, it needs
7462                    // to make its own.
7463                    holder.provider = null;
7464                    return holder;
7465                }
7466
7467                final long origId = Binder.clearCallingIdentity();
7468
7469                // In this case the provider instance already exists, so we can
7470                // return it right away.
7471                conn = incProviderCountLocked(r, cpr, token, stable);
7472                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7473                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7474                        // If this is a perceptible app accessing the provider,
7475                        // make sure to count it as being accessed and thus
7476                        // back up on the LRU list.  This is good because
7477                        // content providers are often expensive to start.
7478                        updateLruProcessLocked(cpr.proc, false, null);
7479                    }
7480                }
7481
7482                if (cpr.proc != null) {
7483                    if (false) {
7484                        if (cpr.name.flattenToShortString().equals(
7485                                "com.android.providers.calendar/.CalendarProvider2")) {
7486                            Slog.v(TAG, "****************** KILLING "
7487                                + cpr.name.flattenToShortString());
7488                            Process.killProcess(cpr.proc.pid);
7489                        }
7490                    }
7491                    boolean success = updateOomAdjLocked(cpr.proc);
7492                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7493                    // NOTE: there is still a race here where a signal could be
7494                    // pending on the process even though we managed to update its
7495                    // adj level.  Not sure what to do about this, but at least
7496                    // the race is now smaller.
7497                    if (!success) {
7498                        // Uh oh...  it looks like the provider's process
7499                        // has been killed on us.  We need to wait for a new
7500                        // process to be started, and make sure its death
7501                        // doesn't kill our process.
7502                        Slog.i(TAG,
7503                                "Existing provider " + cpr.name.flattenToShortString()
7504                                + " is crashing; detaching " + r);
7505                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7506                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7507                        if (!lastRef) {
7508                            // This wasn't the last ref our process had on
7509                            // the provider...  we have now been killed, bail.
7510                            return null;
7511                        }
7512                        providerRunning = false;
7513                        conn = null;
7514                    }
7515                }
7516
7517                Binder.restoreCallingIdentity(origId);
7518            }
7519
7520            boolean singleton;
7521            if (!providerRunning) {
7522                try {
7523                    cpi = AppGlobals.getPackageManager().
7524                        resolveContentProvider(name,
7525                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7526                } catch (RemoteException ex) {
7527                }
7528                if (cpi == null) {
7529                    return null;
7530                }
7531                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7532                        cpi.name, cpi.flags);
7533                if (singleton) {
7534                    userId = 0;
7535                }
7536                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7537
7538                String msg;
7539                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7540                    throw new SecurityException(msg);
7541                }
7542
7543                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7544                        && !cpi.processName.equals("system")) {
7545                    // If this content provider does not run in the system
7546                    // process, and the system is not yet ready to run other
7547                    // processes, then fail fast instead of hanging.
7548                    throw new IllegalArgumentException(
7549                            "Attempt to launch content provider before system ready");
7550                }
7551
7552                // Make sure that the user who owns this provider is started.  If not,
7553                // we don't want to allow it to run.
7554                if (mStartedUsers.get(userId) == null) {
7555                    Slog.w(TAG, "Unable to launch app "
7556                            + cpi.applicationInfo.packageName + "/"
7557                            + cpi.applicationInfo.uid + " for provider "
7558                            + name + ": user " + userId + " is stopped");
7559                    return null;
7560                }
7561
7562                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7563                cpr = mProviderMap.getProviderByClass(comp, userId);
7564                final boolean firstClass = cpr == null;
7565                if (firstClass) {
7566                    try {
7567                        ApplicationInfo ai =
7568                            AppGlobals.getPackageManager().
7569                                getApplicationInfo(
7570                                        cpi.applicationInfo.packageName,
7571                                        STOCK_PM_FLAGS, userId);
7572                        if (ai == null) {
7573                            Slog.w(TAG, "No package info for content provider "
7574                                    + cpi.name);
7575                            return null;
7576                        }
7577                        ai = getAppInfoForUser(ai, userId);
7578                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7579                    } catch (RemoteException ex) {
7580                        // pm is in same process, this will never happen.
7581                    }
7582                }
7583
7584                if (r != null && cpr.canRunHere(r)) {
7585                    // If this is a multiprocess provider, then just return its
7586                    // info and allow the caller to instantiate it.  Only do
7587                    // this if the provider is the same user as the caller's
7588                    // process, or can run as root (so can be in any process).
7589                    return cpr.newHolder(null);
7590                }
7591
7592                if (DEBUG_PROVIDER) {
7593                    RuntimeException e = new RuntimeException("here");
7594                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7595                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7596                }
7597
7598                // This is single process, and our app is now connecting to it.
7599                // See if we are already in the process of launching this
7600                // provider.
7601                final int N = mLaunchingProviders.size();
7602                int i;
7603                for (i=0; i<N; i++) {
7604                    if (mLaunchingProviders.get(i) == cpr) {
7605                        break;
7606                    }
7607                }
7608
7609                // If the provider is not already being launched, then get it
7610                // started.
7611                if (i >= N) {
7612                    final long origId = Binder.clearCallingIdentity();
7613
7614                    try {
7615                        // Content provider is now in use, its package can't be stopped.
7616                        try {
7617                            AppGlobals.getPackageManager().setPackageStoppedState(
7618                                    cpr.appInfo.packageName, false, userId);
7619                        } catch (RemoteException e) {
7620                        } catch (IllegalArgumentException e) {
7621                            Slog.w(TAG, "Failed trying to unstop package "
7622                                    + cpr.appInfo.packageName + ": " + e);
7623                        }
7624
7625                        // Use existing process if already started
7626                        ProcessRecord proc = getProcessRecordLocked(
7627                                cpi.processName, cpr.appInfo.uid, false);
7628                        if (proc != null && proc.thread != null) {
7629                            if (DEBUG_PROVIDER) {
7630                                Slog.d(TAG, "Installing in existing process " + proc);
7631                            }
7632                            proc.pubProviders.put(cpi.name, cpr);
7633                            try {
7634                                proc.thread.scheduleInstallProvider(cpi);
7635                            } catch (RemoteException e) {
7636                            }
7637                        } else {
7638                            proc = startProcessLocked(cpi.processName,
7639                                    cpr.appInfo, false, 0, "content provider",
7640                                    new ComponentName(cpi.applicationInfo.packageName,
7641                                            cpi.name), false, false, false);
7642                            if (proc == null) {
7643                                Slog.w(TAG, "Unable to launch app "
7644                                        + cpi.applicationInfo.packageName + "/"
7645                                        + cpi.applicationInfo.uid + " for provider "
7646                                        + name + ": process is bad");
7647                                return null;
7648                            }
7649                        }
7650                        cpr.launchingApp = proc;
7651                        mLaunchingProviders.add(cpr);
7652                    } finally {
7653                        Binder.restoreCallingIdentity(origId);
7654                    }
7655                }
7656
7657                // Make sure the provider is published (the same provider class
7658                // may be published under multiple names).
7659                if (firstClass) {
7660                    mProviderMap.putProviderByClass(comp, cpr);
7661                }
7662
7663                mProviderMap.putProviderByName(name, cpr);
7664                conn = incProviderCountLocked(r, cpr, token, stable);
7665                if (conn != null) {
7666                    conn.waiting = true;
7667                }
7668            }
7669        }
7670
7671        // Wait for the provider to be published...
7672        synchronized (cpr) {
7673            while (cpr.provider == null) {
7674                if (cpr.launchingApp == null) {
7675                    Slog.w(TAG, "Unable to launch app "
7676                            + cpi.applicationInfo.packageName + "/"
7677                            + cpi.applicationInfo.uid + " for provider "
7678                            + name + ": launching app became null");
7679                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7680                            UserHandle.getUserId(cpi.applicationInfo.uid),
7681                            cpi.applicationInfo.packageName,
7682                            cpi.applicationInfo.uid, name);
7683                    return null;
7684                }
7685                try {
7686                    if (DEBUG_MU) {
7687                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7688                                + cpr.launchingApp);
7689                    }
7690                    if (conn != null) {
7691                        conn.waiting = true;
7692                    }
7693                    cpr.wait();
7694                } catch (InterruptedException ex) {
7695                } finally {
7696                    if (conn != null) {
7697                        conn.waiting = false;
7698                    }
7699                }
7700            }
7701        }
7702        return cpr != null ? cpr.newHolder(conn) : null;
7703    }
7704
7705    public final ContentProviderHolder getContentProvider(
7706            IApplicationThread caller, String name, int userId, boolean stable) {
7707        enforceNotIsolatedCaller("getContentProvider");
7708        if (caller == null) {
7709            String msg = "null IApplicationThread when getting content provider "
7710                    + name;
7711            Slog.w(TAG, msg);
7712            throw new SecurityException(msg);
7713        }
7714
7715        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7716                false, true, "getContentProvider", null);
7717        return getContentProviderImpl(caller, name, null, stable, userId);
7718    }
7719
7720    public ContentProviderHolder getContentProviderExternal(
7721            String name, int userId, IBinder token) {
7722        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7723            "Do not have permission in call getContentProviderExternal()");
7724        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7725                false, true, "getContentProvider", null);
7726        return getContentProviderExternalUnchecked(name, token, userId);
7727    }
7728
7729    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7730            IBinder token, int userId) {
7731        return getContentProviderImpl(null, name, token, true, userId);
7732    }
7733
7734    /**
7735     * Drop a content provider from a ProcessRecord's bookkeeping
7736     */
7737    public void removeContentProvider(IBinder connection, boolean stable) {
7738        enforceNotIsolatedCaller("removeContentProvider");
7739        synchronized (this) {
7740            ContentProviderConnection conn;
7741            try {
7742                conn = (ContentProviderConnection)connection;
7743            } catch (ClassCastException e) {
7744                String msg ="removeContentProvider: " + connection
7745                        + " not a ContentProviderConnection";
7746                Slog.w(TAG, msg);
7747                throw new IllegalArgumentException(msg);
7748            }
7749            if (conn == null) {
7750                throw new NullPointerException("connection is null");
7751            }
7752            if (decProviderCountLocked(conn, null, null, stable)) {
7753                updateOomAdjLocked();
7754            }
7755        }
7756    }
7757
7758    public void removeContentProviderExternal(String name, IBinder token) {
7759        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7760            "Do not have permission in call removeContentProviderExternal()");
7761        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7762    }
7763
7764    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7765        synchronized (this) {
7766            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7767            if(cpr == null) {
7768                //remove from mProvidersByClass
7769                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7770                return;
7771            }
7772
7773            //update content provider record entry info
7774            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7775            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7776            if (localCpr.hasExternalProcessHandles()) {
7777                if (localCpr.removeExternalProcessHandleLocked(token)) {
7778                    updateOomAdjLocked();
7779                } else {
7780                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7781                            + " with no external reference for token: "
7782                            + token + ".");
7783                }
7784            } else {
7785                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7786                        + " with no external references.");
7787            }
7788        }
7789    }
7790
7791    public final void publishContentProviders(IApplicationThread caller,
7792            List<ContentProviderHolder> providers) {
7793        if (providers == null) {
7794            return;
7795        }
7796
7797        enforceNotIsolatedCaller("publishContentProviders");
7798        synchronized (this) {
7799            final ProcessRecord r = getRecordForAppLocked(caller);
7800            if (DEBUG_MU)
7801                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7802            if (r == null) {
7803                throw new SecurityException(
7804                        "Unable to find app for caller " + caller
7805                      + " (pid=" + Binder.getCallingPid()
7806                      + ") when publishing content providers");
7807            }
7808
7809            final long origId = Binder.clearCallingIdentity();
7810
7811            final int N = providers.size();
7812            for (int i=0; i<N; i++) {
7813                ContentProviderHolder src = providers.get(i);
7814                if (src == null || src.info == null || src.provider == null) {
7815                    continue;
7816                }
7817                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7818                if (DEBUG_MU)
7819                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7820                if (dst != null) {
7821                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7822                    mProviderMap.putProviderByClass(comp, dst);
7823                    String names[] = dst.info.authority.split(";");
7824                    for (int j = 0; j < names.length; j++) {
7825                        mProviderMap.putProviderByName(names[j], dst);
7826                    }
7827
7828                    int NL = mLaunchingProviders.size();
7829                    int j;
7830                    for (j=0; j<NL; j++) {
7831                        if (mLaunchingProviders.get(j) == dst) {
7832                            mLaunchingProviders.remove(j);
7833                            j--;
7834                            NL--;
7835                        }
7836                    }
7837                    synchronized (dst) {
7838                        dst.provider = src.provider;
7839                        dst.proc = r;
7840                        dst.notifyAll();
7841                    }
7842                    updateOomAdjLocked(r);
7843                }
7844            }
7845
7846            Binder.restoreCallingIdentity(origId);
7847        }
7848    }
7849
7850    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7851        ContentProviderConnection conn;
7852        try {
7853            conn = (ContentProviderConnection)connection;
7854        } catch (ClassCastException e) {
7855            String msg ="refContentProvider: " + connection
7856                    + " not a ContentProviderConnection";
7857            Slog.w(TAG, msg);
7858            throw new IllegalArgumentException(msg);
7859        }
7860        if (conn == null) {
7861            throw new NullPointerException("connection is null");
7862        }
7863
7864        synchronized (this) {
7865            if (stable > 0) {
7866                conn.numStableIncs += stable;
7867            }
7868            stable = conn.stableCount + stable;
7869            if (stable < 0) {
7870                throw new IllegalStateException("stableCount < 0: " + stable);
7871            }
7872
7873            if (unstable > 0) {
7874                conn.numUnstableIncs += unstable;
7875            }
7876            unstable = conn.unstableCount + unstable;
7877            if (unstable < 0) {
7878                throw new IllegalStateException("unstableCount < 0: " + unstable);
7879            }
7880
7881            if ((stable+unstable) <= 0) {
7882                throw new IllegalStateException("ref counts can't go to zero here: stable="
7883                        + stable + " unstable=" + unstable);
7884            }
7885            conn.stableCount = stable;
7886            conn.unstableCount = unstable;
7887            return !conn.dead;
7888        }
7889    }
7890
7891    public void unstableProviderDied(IBinder connection) {
7892        ContentProviderConnection conn;
7893        try {
7894            conn = (ContentProviderConnection)connection;
7895        } catch (ClassCastException e) {
7896            String msg ="refContentProvider: " + connection
7897                    + " not a ContentProviderConnection";
7898            Slog.w(TAG, msg);
7899            throw new IllegalArgumentException(msg);
7900        }
7901        if (conn == null) {
7902            throw new NullPointerException("connection is null");
7903        }
7904
7905        // Safely retrieve the content provider associated with the connection.
7906        IContentProvider provider;
7907        synchronized (this) {
7908            provider = conn.provider.provider;
7909        }
7910
7911        if (provider == null) {
7912            // Um, yeah, we're way ahead of you.
7913            return;
7914        }
7915
7916        // Make sure the caller is being honest with us.
7917        if (provider.asBinder().pingBinder()) {
7918            // Er, no, still looks good to us.
7919            synchronized (this) {
7920                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7921                        + " says " + conn + " died, but we don't agree");
7922                return;
7923            }
7924        }
7925
7926        // Well look at that!  It's dead!
7927        synchronized (this) {
7928            if (conn.provider.provider != provider) {
7929                // But something changed...  good enough.
7930                return;
7931            }
7932
7933            ProcessRecord proc = conn.provider.proc;
7934            if (proc == null || proc.thread == null) {
7935                // Seems like the process is already cleaned up.
7936                return;
7937            }
7938
7939            // As far as we're concerned, this is just like receiving a
7940            // death notification...  just a bit prematurely.
7941            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
7942                    + ") early provider death");
7943            final long ident = Binder.clearCallingIdentity();
7944            try {
7945                appDiedLocked(proc, proc.pid, proc.thread);
7946            } finally {
7947                Binder.restoreCallingIdentity(ident);
7948            }
7949        }
7950    }
7951
7952    @Override
7953    public void appNotRespondingViaProvider(IBinder connection) {
7954        enforceCallingPermission(
7955                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
7956
7957        final ContentProviderConnection conn = (ContentProviderConnection) connection;
7958        if (conn == null) {
7959            Slog.w(TAG, "ContentProviderConnection is null");
7960            return;
7961        }
7962
7963        final ProcessRecord host = conn.provider.proc;
7964        if (host == null) {
7965            Slog.w(TAG, "Failed to find hosting ProcessRecord");
7966            return;
7967        }
7968
7969        final long token = Binder.clearCallingIdentity();
7970        try {
7971            appNotResponding(host, null, null, false, "ContentProvider not responding");
7972        } finally {
7973            Binder.restoreCallingIdentity(token);
7974        }
7975    }
7976
7977    public static final void installSystemProviders() {
7978        List<ProviderInfo> providers;
7979        synchronized (sSelf) {
7980            ProcessRecord app = sSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7981            providers = sSelf.generateApplicationProvidersLocked(app);
7982            if (providers != null) {
7983                for (int i=providers.size()-1; i>=0; i--) {
7984                    ProviderInfo pi = (ProviderInfo)providers.get(i);
7985                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7986                        Slog.w(TAG, "Not installing system proc provider " + pi.name
7987                                + ": not system .apk");
7988                        providers.remove(i);
7989                    }
7990                }
7991            }
7992        }
7993        if (providers != null) {
7994            sSystemThread.installSystemProviders(providers);
7995        }
7996
7997        sSelf.mCoreSettingsObserver = new CoreSettingsObserver(sSelf);
7998
7999        sSelf.mUsageStatsService.monitorPackages();
8000    }
8001
8002    /**
8003     * Allows app to retrieve the MIME type of a URI without having permission
8004     * to access its content provider.
8005     *
8006     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8007     *
8008     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8009     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8010     */
8011    public String getProviderMimeType(Uri uri, int userId) {
8012        enforceNotIsolatedCaller("getProviderMimeType");
8013        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8014                userId, false, true, "getProviderMimeType", null);
8015        final String name = uri.getAuthority();
8016        final long ident = Binder.clearCallingIdentity();
8017        ContentProviderHolder holder = null;
8018
8019        try {
8020            holder = getContentProviderExternalUnchecked(name, null, userId);
8021            if (holder != null) {
8022                return holder.provider.getType(uri);
8023            }
8024        } catch (RemoteException e) {
8025            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8026            return null;
8027        } finally {
8028            if (holder != null) {
8029                removeContentProviderExternalUnchecked(name, null, userId);
8030            }
8031            Binder.restoreCallingIdentity(ident);
8032        }
8033
8034        return null;
8035    }
8036
8037    // =========================================================
8038    // GLOBAL MANAGEMENT
8039    // =========================================================
8040
8041    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8042            boolean isolated) {
8043        String proc = customProcess != null ? customProcess : info.processName;
8044        BatteryStatsImpl.Uid.Proc ps = null;
8045        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8046        int uid = info.uid;
8047        if (isolated) {
8048            int userId = UserHandle.getUserId(uid);
8049            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8050            while (true) {
8051                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8052                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8053                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8054                }
8055                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8056                mNextIsolatedProcessUid++;
8057                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8058                    // No process for this uid, use it.
8059                    break;
8060                }
8061                stepsLeft--;
8062                if (stepsLeft <= 0) {
8063                    return null;
8064                }
8065            }
8066        }
8067        return new ProcessRecord(stats, info, proc, uid);
8068    }
8069
8070    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8071        ProcessRecord app;
8072        if (!isolated) {
8073            app = getProcessRecordLocked(info.processName, info.uid, true);
8074        } else {
8075            app = null;
8076        }
8077
8078        if (app == null) {
8079            app = newProcessRecordLocked(info, null, isolated);
8080            mProcessNames.put(info.processName, app.uid, app);
8081            if (isolated) {
8082                mIsolatedProcesses.put(app.uid, app);
8083            }
8084            updateLruProcessLocked(app, false, null);
8085            updateOomAdjLocked();
8086        }
8087
8088        // This package really, really can not be stopped.
8089        try {
8090            AppGlobals.getPackageManager().setPackageStoppedState(
8091                    info.packageName, false, UserHandle.getUserId(app.uid));
8092        } catch (RemoteException e) {
8093        } catch (IllegalArgumentException e) {
8094            Slog.w(TAG, "Failed trying to unstop package "
8095                    + info.packageName + ": " + e);
8096        }
8097
8098        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8099                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8100            app.persistent = true;
8101            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8102        }
8103        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8104            mPersistentStartingProcesses.add(app);
8105            startProcessLocked(app, "added application", app.processName);
8106        }
8107
8108        return app;
8109    }
8110
8111    public void unhandledBack() {
8112        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8113                "unhandledBack()");
8114
8115        synchronized(this) {
8116            final long origId = Binder.clearCallingIdentity();
8117            try {
8118                getFocusedStack().unhandledBackLocked();
8119            } finally {
8120                Binder.restoreCallingIdentity(origId);
8121            }
8122        }
8123    }
8124
8125    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8126        enforceNotIsolatedCaller("openContentUri");
8127        final int userId = UserHandle.getCallingUserId();
8128        String name = uri.getAuthority();
8129        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8130        ParcelFileDescriptor pfd = null;
8131        if (cph != null) {
8132            // We record the binder invoker's uid in thread-local storage before
8133            // going to the content provider to open the file.  Later, in the code
8134            // that handles all permissions checks, we look for this uid and use
8135            // that rather than the Activity Manager's own uid.  The effect is that
8136            // we do the check against the caller's permissions even though it looks
8137            // to the content provider like the Activity Manager itself is making
8138            // the request.
8139            sCallerIdentity.set(new Identity(
8140                    Binder.getCallingPid(), Binder.getCallingUid()));
8141            try {
8142                pfd = cph.provider.openFile(null, uri, "r", null);
8143            } catch (FileNotFoundException e) {
8144                // do nothing; pfd will be returned null
8145            } finally {
8146                // Ensure that whatever happens, we clean up the identity state
8147                sCallerIdentity.remove();
8148            }
8149
8150            // We've got the fd now, so we're done with the provider.
8151            removeContentProviderExternalUnchecked(name, null, userId);
8152        } else {
8153            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8154        }
8155        return pfd;
8156    }
8157
8158    // Actually is sleeping or shutting down or whatever else in the future
8159    // is an inactive state.
8160    public boolean isSleepingOrShuttingDown() {
8161        return mSleeping || mShuttingDown;
8162    }
8163
8164    public void goingToSleep() {
8165        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8166                != PackageManager.PERMISSION_GRANTED) {
8167            throw new SecurityException("Requires permission "
8168                    + android.Manifest.permission.DEVICE_POWER);
8169        }
8170
8171        synchronized(this) {
8172            mWentToSleep = true;
8173            updateEventDispatchingLocked();
8174
8175            if (!mSleeping) {
8176                mSleeping = true;
8177                mStackSupervisor.goingToSleepLocked();
8178
8179                // Initialize the wake times of all processes.
8180                checkExcessivePowerUsageLocked(false);
8181                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8182                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8183                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8184            }
8185        }
8186    }
8187
8188    @Override
8189    public boolean shutdown(int timeout) {
8190        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8191                != PackageManager.PERMISSION_GRANTED) {
8192            throw new SecurityException("Requires permission "
8193                    + android.Manifest.permission.SHUTDOWN);
8194        }
8195
8196        boolean timedout = false;
8197
8198        synchronized(this) {
8199            mShuttingDown = true;
8200            updateEventDispatchingLocked();
8201            timedout = mStackSupervisor.shutdownLocked(timeout);
8202        }
8203
8204        mAppOpsService.shutdown();
8205        mUsageStatsService.shutdown();
8206        mBatteryStatsService.shutdown();
8207        synchronized (this) {
8208            mProcessStats.shutdownLocked();
8209        }
8210
8211        return timedout;
8212    }
8213
8214    public final void activitySlept(IBinder token) {
8215        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8216
8217        final long origId = Binder.clearCallingIdentity();
8218
8219        synchronized (this) {
8220            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8221            if (r != null) {
8222                mStackSupervisor.activitySleptLocked(r);
8223            }
8224        }
8225
8226        Binder.restoreCallingIdentity(origId);
8227    }
8228
8229    void logLockScreen(String msg) {
8230        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8231                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8232                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8233                mStackSupervisor.mDismissKeyguardOnNextActivity);
8234    }
8235
8236    private void comeOutOfSleepIfNeededLocked() {
8237        if (!mWentToSleep && !mLockScreenShown) {
8238            if (mSleeping) {
8239                mSleeping = false;
8240                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8241            }
8242        }
8243    }
8244
8245    public void wakingUp() {
8246        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8247                != PackageManager.PERMISSION_GRANTED) {
8248            throw new SecurityException("Requires permission "
8249                    + android.Manifest.permission.DEVICE_POWER);
8250        }
8251
8252        synchronized(this) {
8253            mWentToSleep = false;
8254            updateEventDispatchingLocked();
8255            comeOutOfSleepIfNeededLocked();
8256        }
8257    }
8258
8259    private void updateEventDispatchingLocked() {
8260        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8261    }
8262
8263    public void setLockScreenShown(boolean shown) {
8264        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8265                != PackageManager.PERMISSION_GRANTED) {
8266            throw new SecurityException("Requires permission "
8267                    + android.Manifest.permission.DEVICE_POWER);
8268        }
8269
8270        synchronized(this) {
8271            long ident = Binder.clearCallingIdentity();
8272            try {
8273                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8274                mLockScreenShown = shown;
8275                comeOutOfSleepIfNeededLocked();
8276            } finally {
8277                Binder.restoreCallingIdentity(ident);
8278            }
8279        }
8280    }
8281
8282    public void stopAppSwitches() {
8283        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8284                != PackageManager.PERMISSION_GRANTED) {
8285            throw new SecurityException("Requires permission "
8286                    + android.Manifest.permission.STOP_APP_SWITCHES);
8287        }
8288
8289        synchronized(this) {
8290            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8291                    + APP_SWITCH_DELAY_TIME;
8292            mDidAppSwitch = false;
8293            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8294            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8295            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8296        }
8297    }
8298
8299    public void resumeAppSwitches() {
8300        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8301                != PackageManager.PERMISSION_GRANTED) {
8302            throw new SecurityException("Requires permission "
8303                    + android.Manifest.permission.STOP_APP_SWITCHES);
8304        }
8305
8306        synchronized(this) {
8307            // Note that we don't execute any pending app switches... we will
8308            // let those wait until either the timeout, or the next start
8309            // activity request.
8310            mAppSwitchesAllowedTime = 0;
8311        }
8312    }
8313
8314    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8315            String name) {
8316        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8317            return true;
8318        }
8319
8320        final int perm = checkComponentPermission(
8321                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8322                callingUid, -1, true);
8323        if (perm == PackageManager.PERMISSION_GRANTED) {
8324            return true;
8325        }
8326
8327        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8328        return false;
8329    }
8330
8331    public void setDebugApp(String packageName, boolean waitForDebugger,
8332            boolean persistent) {
8333        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8334                "setDebugApp()");
8335
8336        long ident = Binder.clearCallingIdentity();
8337        try {
8338            // Note that this is not really thread safe if there are multiple
8339            // callers into it at the same time, but that's not a situation we
8340            // care about.
8341            if (persistent) {
8342                final ContentResolver resolver = mContext.getContentResolver();
8343                Settings.Global.putString(
8344                    resolver, Settings.Global.DEBUG_APP,
8345                    packageName);
8346                Settings.Global.putInt(
8347                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8348                    waitForDebugger ? 1 : 0);
8349            }
8350
8351            synchronized (this) {
8352                if (!persistent) {
8353                    mOrigDebugApp = mDebugApp;
8354                    mOrigWaitForDebugger = mWaitForDebugger;
8355                }
8356                mDebugApp = packageName;
8357                mWaitForDebugger = waitForDebugger;
8358                mDebugTransient = !persistent;
8359                if (packageName != null) {
8360                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8361                            UserHandle.USER_ALL, "set debug app");
8362                }
8363            }
8364        } finally {
8365            Binder.restoreCallingIdentity(ident);
8366        }
8367    }
8368
8369    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8370        synchronized (this) {
8371            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8372            if (!isDebuggable) {
8373                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8374                    throw new SecurityException("Process not debuggable: " + app.packageName);
8375                }
8376            }
8377
8378            mOpenGlTraceApp = processName;
8379        }
8380    }
8381
8382    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8383            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8384        synchronized (this) {
8385            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8386            if (!isDebuggable) {
8387                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8388                    throw new SecurityException("Process not debuggable: " + app.packageName);
8389                }
8390            }
8391            mProfileApp = processName;
8392            mProfileFile = profileFile;
8393            if (mProfileFd != null) {
8394                try {
8395                    mProfileFd.close();
8396                } catch (IOException e) {
8397                }
8398                mProfileFd = null;
8399            }
8400            mProfileFd = profileFd;
8401            mProfileType = 0;
8402            mAutoStopProfiler = autoStopProfiler;
8403        }
8404    }
8405
8406    @Override
8407    public void setAlwaysFinish(boolean enabled) {
8408        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8409                "setAlwaysFinish()");
8410
8411        Settings.Global.putInt(
8412                mContext.getContentResolver(),
8413                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8414
8415        synchronized (this) {
8416            mAlwaysFinishActivities = enabled;
8417        }
8418    }
8419
8420    @Override
8421    public void setActivityController(IActivityController controller) {
8422        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8423                "setActivityController()");
8424        synchronized (this) {
8425            mController = controller;
8426            Watchdog.getInstance().setActivityController(controller);
8427        }
8428    }
8429
8430    @Override
8431    public void setUserIsMonkey(boolean userIsMonkey) {
8432        synchronized (this) {
8433            synchronized (mPidsSelfLocked) {
8434                final int callingPid = Binder.getCallingPid();
8435                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8436                if (precessRecord == null) {
8437                    throw new SecurityException("Unknown process: " + callingPid);
8438                }
8439                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8440                    throw new SecurityException("Only an instrumentation process "
8441                            + "with a UiAutomation can call setUserIsMonkey");
8442                }
8443            }
8444            mUserIsMonkey = userIsMonkey;
8445        }
8446    }
8447
8448    @Override
8449    public boolean isUserAMonkey() {
8450        synchronized (this) {
8451            // If there is a controller also implies the user is a monkey.
8452            return (mUserIsMonkey || mController != null);
8453        }
8454    }
8455
8456    public void requestBugReport() {
8457        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8458        SystemProperties.set("ctl.start", "bugreport");
8459    }
8460
8461    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8462        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8463    }
8464
8465    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8466        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8467            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8468        }
8469        return KEY_DISPATCHING_TIMEOUT;
8470    }
8471
8472    @Override
8473    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8474        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8475                != PackageManager.PERMISSION_GRANTED) {
8476            throw new SecurityException("Requires permission "
8477                    + android.Manifest.permission.FILTER_EVENTS);
8478        }
8479        ProcessRecord proc;
8480        long timeout;
8481        synchronized (this) {
8482            synchronized (mPidsSelfLocked) {
8483                proc = mPidsSelfLocked.get(pid);
8484            }
8485            timeout = getInputDispatchingTimeoutLocked(proc);
8486        }
8487
8488        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8489            return -1;
8490        }
8491
8492        return timeout;
8493    }
8494
8495    /**
8496     * Handle input dispatching timeouts.
8497     * Returns whether input dispatching should be aborted or not.
8498     */
8499    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8500            final ActivityRecord activity, final ActivityRecord parent,
8501            final boolean aboveSystem, String reason) {
8502        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8503                != PackageManager.PERMISSION_GRANTED) {
8504            throw new SecurityException("Requires permission "
8505                    + android.Manifest.permission.FILTER_EVENTS);
8506        }
8507
8508        final String annotation;
8509        if (reason == null) {
8510            annotation = "Input dispatching timed out";
8511        } else {
8512            annotation = "Input dispatching timed out (" + reason + ")";
8513        }
8514
8515        if (proc != null) {
8516            synchronized (this) {
8517                if (proc.debugging) {
8518                    return false;
8519                }
8520
8521                if (mDidDexOpt) {
8522                    // Give more time since we were dexopting.
8523                    mDidDexOpt = false;
8524                    return false;
8525                }
8526
8527                if (proc.instrumentationClass != null) {
8528                    Bundle info = new Bundle();
8529                    info.putString("shortMsg", "keyDispatchingTimedOut");
8530                    info.putString("longMsg", annotation);
8531                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8532                    return true;
8533                }
8534            }
8535            mHandler.post(new Runnable() {
8536                @Override
8537                public void run() {
8538                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8539                }
8540            });
8541        }
8542
8543        return true;
8544    }
8545
8546    public Bundle getAssistContextExtras(int requestType) {
8547        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8548                "getAssistContextExtras()");
8549        PendingAssistExtras pae;
8550        Bundle extras = new Bundle();
8551        synchronized (this) {
8552            ActivityRecord activity = getFocusedStack().mResumedActivity;
8553            if (activity == null) {
8554                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8555                return null;
8556            }
8557            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8558            if (activity.app == null || activity.app.thread == null) {
8559                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8560                return extras;
8561            }
8562            if (activity.app.pid == Binder.getCallingPid()) {
8563                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8564                return extras;
8565            }
8566            pae = new PendingAssistExtras(activity);
8567            try {
8568                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8569                        requestType);
8570                mPendingAssistExtras.add(pae);
8571                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8572            } catch (RemoteException e) {
8573                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8574                return extras;
8575            }
8576        }
8577        synchronized (pae) {
8578            while (!pae.haveResult) {
8579                try {
8580                    pae.wait();
8581                } catch (InterruptedException e) {
8582                }
8583            }
8584            if (pae.result != null) {
8585                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8586            }
8587        }
8588        synchronized (this) {
8589            mPendingAssistExtras.remove(pae);
8590            mHandler.removeCallbacks(pae);
8591        }
8592        return extras;
8593    }
8594
8595    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8596        PendingAssistExtras pae = (PendingAssistExtras)token;
8597        synchronized (pae) {
8598            pae.result = extras;
8599            pae.haveResult = true;
8600            pae.notifyAll();
8601        }
8602    }
8603
8604    public void registerProcessObserver(IProcessObserver observer) {
8605        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8606                "registerProcessObserver()");
8607        synchronized (this) {
8608            mProcessObservers.register(observer);
8609        }
8610    }
8611
8612    @Override
8613    public void unregisterProcessObserver(IProcessObserver observer) {
8614        synchronized (this) {
8615            mProcessObservers.unregister(observer);
8616        }
8617    }
8618
8619    @Override
8620    public boolean convertFromTranslucent(IBinder token) {
8621        final long origId = Binder.clearCallingIdentity();
8622        try {
8623            synchronized (this) {
8624                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8625                if (r == null) {
8626                    return false;
8627                }
8628                if (r.changeWindowTranslucency(true)) {
8629                    mWindowManager.setAppFullscreen(token, true);
8630                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8631                    return true;
8632                }
8633                return false;
8634            }
8635        } finally {
8636            Binder.restoreCallingIdentity(origId);
8637        }
8638    }
8639
8640    @Override
8641    public boolean convertToTranslucent(IBinder token) {
8642        final long origId = Binder.clearCallingIdentity();
8643        try {
8644            synchronized (this) {
8645                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8646                if (r == null) {
8647                    return false;
8648                }
8649                if (r.changeWindowTranslucency(false)) {
8650                    r.task.stack.convertToTranslucent(r);
8651                    mWindowManager.setAppFullscreen(token, false);
8652                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8653                    return true;
8654                }
8655                return false;
8656            }
8657        } finally {
8658            Binder.restoreCallingIdentity(origId);
8659        }
8660    }
8661
8662    @Override
8663    public void setImmersive(IBinder token, boolean immersive) {
8664        synchronized(this) {
8665            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8666            if (r == null) {
8667                throw new IllegalArgumentException();
8668            }
8669            r.immersive = immersive;
8670
8671            // update associated state if we're frontmost
8672            if (r == mFocusedActivity) {
8673                if (DEBUG_IMMERSIVE) {
8674                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8675                }
8676                applyUpdateLockStateLocked(r);
8677            }
8678        }
8679    }
8680
8681    @Override
8682    public boolean isImmersive(IBinder token) {
8683        synchronized (this) {
8684            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8685            if (r == null) {
8686                throw new IllegalArgumentException();
8687            }
8688            return r.immersive;
8689        }
8690    }
8691
8692    public boolean isTopActivityImmersive() {
8693        enforceNotIsolatedCaller("startActivity");
8694        synchronized (this) {
8695            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8696            return (r != null) ? r.immersive : false;
8697        }
8698    }
8699
8700    public final void enterSafeMode() {
8701        synchronized(this) {
8702            // It only makes sense to do this before the system is ready
8703            // and started launching other packages.
8704            if (!mSystemReady) {
8705                try {
8706                    AppGlobals.getPackageManager().enterSafeMode();
8707                } catch (RemoteException e) {
8708                }
8709            }
8710        }
8711    }
8712
8713    public final void showSafeModeOverlay() {
8714        View v = LayoutInflater.from(mContext).inflate(
8715                com.android.internal.R.layout.safe_mode, null);
8716        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8717        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8718        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8719        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8720        lp.gravity = Gravity.BOTTOM | Gravity.START;
8721        lp.format = v.getBackground().getOpacity();
8722        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8723                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8724        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8725        ((WindowManager)mContext.getSystemService(
8726                Context.WINDOW_SERVICE)).addView(v, lp);
8727    }
8728
8729    public void noteWakeupAlarm(IIntentSender sender) {
8730        if (!(sender instanceof PendingIntentRecord)) {
8731            return;
8732        }
8733        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8734        synchronized (stats) {
8735            if (mBatteryStatsService.isOnBattery()) {
8736                mBatteryStatsService.enforceCallingPermission();
8737                PendingIntentRecord rec = (PendingIntentRecord)sender;
8738                int MY_UID = Binder.getCallingUid();
8739                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8740                BatteryStatsImpl.Uid.Pkg pkg =
8741                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8742                pkg.incWakeupsLocked();
8743            }
8744        }
8745    }
8746
8747    public boolean killPids(int[] pids, String pReason, boolean secure) {
8748        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8749            throw new SecurityException("killPids only available to the system");
8750        }
8751        String reason = (pReason == null) ? "Unknown" : pReason;
8752        // XXX Note: don't acquire main activity lock here, because the window
8753        // manager calls in with its locks held.
8754
8755        boolean killed = false;
8756        synchronized (mPidsSelfLocked) {
8757            int[] types = new int[pids.length];
8758            int worstType = 0;
8759            for (int i=0; i<pids.length; i++) {
8760                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8761                if (proc != null) {
8762                    int type = proc.setAdj;
8763                    types[i] = type;
8764                    if (type > worstType) {
8765                        worstType = type;
8766                    }
8767                }
8768            }
8769
8770            // If the worst oom_adj is somewhere in the cached proc LRU range,
8771            // then constrain it so we will kill all cached procs.
8772            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8773                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8774                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8775            }
8776
8777            // If this is not a secure call, don't let it kill processes that
8778            // are important.
8779            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8780                worstType = ProcessList.SERVICE_ADJ;
8781            }
8782
8783            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8784            for (int i=0; i<pids.length; i++) {
8785                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8786                if (proc == null) {
8787                    continue;
8788                }
8789                int adj = proc.setAdj;
8790                if (adj >= worstType && !proc.killedByAm) {
8791                    killUnneededProcessLocked(proc, reason);
8792                    killed = true;
8793                }
8794            }
8795        }
8796        return killed;
8797    }
8798
8799    @Override
8800    public void killUid(int uid, String reason) {
8801        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8802            throw new SecurityException("killUid only available to the system");
8803        }
8804        synchronized (this) {
8805            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8806                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8807                    reason != null ? reason : "kill uid");
8808        }
8809    }
8810
8811    @Override
8812    public boolean killProcessesBelowForeground(String reason) {
8813        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8814            throw new SecurityException("killProcessesBelowForeground() only available to system");
8815        }
8816
8817        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8818    }
8819
8820    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8821        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8822            throw new SecurityException("killProcessesBelowAdj() only available to system");
8823        }
8824
8825        boolean killed = false;
8826        synchronized (mPidsSelfLocked) {
8827            final int size = mPidsSelfLocked.size();
8828            for (int i = 0; i < size; i++) {
8829                final int pid = mPidsSelfLocked.keyAt(i);
8830                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8831                if (proc == null) continue;
8832
8833                final int adj = proc.setAdj;
8834                if (adj > belowAdj && !proc.killedByAm) {
8835                    killUnneededProcessLocked(proc, reason);
8836                    killed = true;
8837                }
8838            }
8839        }
8840        return killed;
8841    }
8842
8843    @Override
8844    public void hang(final IBinder who, boolean allowRestart) {
8845        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8846                != PackageManager.PERMISSION_GRANTED) {
8847            throw new SecurityException("Requires permission "
8848                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8849        }
8850
8851        final IBinder.DeathRecipient death = new DeathRecipient() {
8852            @Override
8853            public void binderDied() {
8854                synchronized (this) {
8855                    notifyAll();
8856                }
8857            }
8858        };
8859
8860        try {
8861            who.linkToDeath(death, 0);
8862        } catch (RemoteException e) {
8863            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8864            return;
8865        }
8866
8867        synchronized (this) {
8868            Watchdog.getInstance().setAllowRestart(allowRestart);
8869            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8870            synchronized (death) {
8871                while (who.isBinderAlive()) {
8872                    try {
8873                        death.wait();
8874                    } catch (InterruptedException e) {
8875                    }
8876                }
8877            }
8878            Watchdog.getInstance().setAllowRestart(true);
8879        }
8880    }
8881
8882    @Override
8883    public void restart() {
8884        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8885                != PackageManager.PERMISSION_GRANTED) {
8886            throw new SecurityException("Requires permission "
8887                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8888        }
8889
8890        Log.i(TAG, "Sending shutdown broadcast...");
8891
8892        BroadcastReceiver br = new BroadcastReceiver() {
8893            @Override public void onReceive(Context context, Intent intent) {
8894                // Now the broadcast is done, finish up the low-level shutdown.
8895                Log.i(TAG, "Shutting down activity manager...");
8896                shutdown(10000);
8897                Log.i(TAG, "Shutdown complete, restarting!");
8898                Process.killProcess(Process.myPid());
8899                System.exit(10);
8900            }
8901        };
8902
8903        // First send the high-level shut down broadcast.
8904        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8905        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8906        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8907        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8908        mContext.sendOrderedBroadcastAsUser(intent,
8909                UserHandle.ALL, null, br, mHandler, 0, null, null);
8910        */
8911        br.onReceive(mContext, intent);
8912    }
8913
8914    private long getLowRamTimeSinceIdle(long now) {
8915        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8916    }
8917
8918    @Override
8919    public void performIdleMaintenance() {
8920        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8921                != PackageManager.PERMISSION_GRANTED) {
8922            throw new SecurityException("Requires permission "
8923                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8924        }
8925
8926        synchronized (this) {
8927            final long now = SystemClock.uptimeMillis();
8928            final long timeSinceLastIdle = now - mLastIdleTime;
8929            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
8930            mLastIdleTime = now;
8931            mLowRamTimeSinceLastIdle = 0;
8932            if (mLowRamStartTime != 0) {
8933                mLowRamStartTime = now;
8934            }
8935
8936            StringBuilder sb = new StringBuilder(128);
8937            sb.append("Idle maintenance over ");
8938            TimeUtils.formatDuration(timeSinceLastIdle, sb);
8939            sb.append(" low RAM for ");
8940            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
8941            Slog.i(TAG, sb.toString());
8942
8943            // If at least 1/3 of our time since the last idle period has been spent
8944            // with RAM low, then we want to kill processes.
8945            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
8946
8947            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
8948                ProcessRecord proc = mLruProcesses.get(i);
8949                if (proc.notCachedSinceIdle) {
8950                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
8951                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
8952                        if (doKilling && proc.initialIdlePss != 0
8953                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
8954                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
8955                                    + " from " + proc.initialIdlePss + ")");
8956                        }
8957                    }
8958                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
8959                    proc.notCachedSinceIdle = true;
8960                    proc.initialIdlePss = 0;
8961                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
8962                            mSleeping, now);
8963                }
8964            }
8965
8966            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
8967            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
8968        }
8969    }
8970
8971    public final void startRunning(String pkg, String cls, String action,
8972            String data) {
8973        synchronized(this) {
8974            if (mStartRunning) {
8975                return;
8976            }
8977            mStartRunning = true;
8978            mTopComponent = pkg != null && cls != null
8979                    ? new ComponentName(pkg, cls) : null;
8980            mTopAction = action != null ? action : Intent.ACTION_MAIN;
8981            mTopData = data;
8982            if (!mSystemReady) {
8983                return;
8984            }
8985        }
8986
8987        systemReady(null);
8988    }
8989
8990    private void retrieveSettings() {
8991        final ContentResolver resolver = mContext.getContentResolver();
8992        String debugApp = Settings.Global.getString(
8993            resolver, Settings.Global.DEBUG_APP);
8994        boolean waitForDebugger = Settings.Global.getInt(
8995            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
8996        boolean alwaysFinishActivities = Settings.Global.getInt(
8997            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8998        boolean forceRtl = Settings.Global.getInt(
8999                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9000        // Transfer any global setting for forcing RTL layout, into a System Property
9001        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9002
9003        Configuration configuration = new Configuration();
9004        Settings.System.getConfiguration(resolver, configuration);
9005        if (forceRtl) {
9006            // This will take care of setting the correct layout direction flags
9007            configuration.setLayoutDirection(configuration.locale);
9008        }
9009
9010        synchronized (this) {
9011            mDebugApp = mOrigDebugApp = debugApp;
9012            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9013            mAlwaysFinishActivities = alwaysFinishActivities;
9014            // This happens before any activities are started, so we can
9015            // change mConfiguration in-place.
9016            updateConfigurationLocked(configuration, null, false, true);
9017            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9018        }
9019    }
9020
9021    public boolean testIsSystemReady() {
9022        // no need to synchronize(this) just to read & return the value
9023        return mSystemReady;
9024    }
9025
9026    private static File getCalledPreBootReceiversFile() {
9027        File dataDir = Environment.getDataDirectory();
9028        File systemDir = new File(dataDir, "system");
9029        File fname = new File(systemDir, "called_pre_boots.dat");
9030        return fname;
9031    }
9032
9033    static final int LAST_DONE_VERSION = 10000;
9034
9035    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9036        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9037        File file = getCalledPreBootReceiversFile();
9038        FileInputStream fis = null;
9039        try {
9040            fis = new FileInputStream(file);
9041            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9042            int fvers = dis.readInt();
9043            if (fvers == LAST_DONE_VERSION) {
9044                String vers = dis.readUTF();
9045                String codename = dis.readUTF();
9046                String build = dis.readUTF();
9047                if (android.os.Build.VERSION.RELEASE.equals(vers)
9048                        && android.os.Build.VERSION.CODENAME.equals(codename)
9049                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9050                    int num = dis.readInt();
9051                    while (num > 0) {
9052                        num--;
9053                        String pkg = dis.readUTF();
9054                        String cls = dis.readUTF();
9055                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9056                    }
9057                }
9058            }
9059        } catch (FileNotFoundException e) {
9060        } catch (IOException e) {
9061            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9062        } finally {
9063            if (fis != null) {
9064                try {
9065                    fis.close();
9066                } catch (IOException e) {
9067                }
9068            }
9069        }
9070        return lastDoneReceivers;
9071    }
9072
9073    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9074        File file = getCalledPreBootReceiversFile();
9075        FileOutputStream fos = null;
9076        DataOutputStream dos = null;
9077        try {
9078            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9079            fos = new FileOutputStream(file);
9080            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9081            dos.writeInt(LAST_DONE_VERSION);
9082            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9083            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9084            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9085            dos.writeInt(list.size());
9086            for (int i=0; i<list.size(); i++) {
9087                dos.writeUTF(list.get(i).getPackageName());
9088                dos.writeUTF(list.get(i).getClassName());
9089            }
9090        } catch (IOException e) {
9091            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9092            file.delete();
9093        } finally {
9094            FileUtils.sync(fos);
9095            if (dos != null) {
9096                try {
9097                    dos.close();
9098                } catch (IOException e) {
9099                    // TODO Auto-generated catch block
9100                    e.printStackTrace();
9101                }
9102            }
9103        }
9104    }
9105
9106    public void systemReady(final Runnable goingCallback) {
9107        synchronized(this) {
9108            if (mSystemReady) {
9109                if (goingCallback != null) goingCallback.run();
9110                return;
9111            }
9112
9113            // Check to see if there are any update receivers to run.
9114            if (!mDidUpdate) {
9115                if (mWaitingUpdate) {
9116                    return;
9117                }
9118                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9119                List<ResolveInfo> ris = null;
9120                try {
9121                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9122                            intent, null, 0, 0);
9123                } catch (RemoteException e) {
9124                }
9125                if (ris != null) {
9126                    for (int i=ris.size()-1; i>=0; i--) {
9127                        if ((ris.get(i).activityInfo.applicationInfo.flags
9128                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9129                            ris.remove(i);
9130                        }
9131                    }
9132                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9133
9134                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9135
9136                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9137                    for (int i=0; i<ris.size(); i++) {
9138                        ActivityInfo ai = ris.get(i).activityInfo;
9139                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9140                        if (lastDoneReceivers.contains(comp)) {
9141                            ris.remove(i);
9142                            i--;
9143                        }
9144                    }
9145
9146                    final int[] users = getUsersLocked();
9147                    for (int i=0; i<ris.size(); i++) {
9148                        ActivityInfo ai = ris.get(i).activityInfo;
9149                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9150                        doneReceivers.add(comp);
9151                        intent.setComponent(comp);
9152                        for (int j=0; j<users.length; j++) {
9153                            IIntentReceiver finisher = null;
9154                            if (i == ris.size()-1 && j == users.length-1) {
9155                                finisher = new IIntentReceiver.Stub() {
9156                                    public void performReceive(Intent intent, int resultCode,
9157                                            String data, Bundle extras, boolean ordered,
9158                                            boolean sticky, int sendingUser) {
9159                                        // The raw IIntentReceiver interface is called
9160                                        // with the AM lock held, so redispatch to
9161                                        // execute our code without the lock.
9162                                        mHandler.post(new Runnable() {
9163                                            public void run() {
9164                                                synchronized (ActivityManagerService.this) {
9165                                                    mDidUpdate = true;
9166                                                }
9167                                                writeLastDonePreBootReceivers(doneReceivers);
9168                                                showBootMessage(mContext.getText(
9169                                                        R.string.android_upgrading_complete),
9170                                                        false);
9171                                                systemReady(goingCallback);
9172                                            }
9173                                        });
9174                                    }
9175                                };
9176                            }
9177                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9178                                    + " for user " + users[j]);
9179                            broadcastIntentLocked(null, null, intent, null, finisher,
9180                                    0, null, null, null, AppOpsManager.OP_NONE,
9181                                    true, false, MY_PID, Process.SYSTEM_UID,
9182                                    users[j]);
9183                            if (finisher != null) {
9184                                mWaitingUpdate = true;
9185                            }
9186                        }
9187                    }
9188                }
9189                if (mWaitingUpdate) {
9190                    return;
9191                }
9192                mDidUpdate = true;
9193            }
9194
9195            mAppOpsService.systemReady();
9196            mSystemReady = true;
9197            if (!mStartRunning) {
9198                return;
9199            }
9200        }
9201
9202        ArrayList<ProcessRecord> procsToKill = null;
9203        synchronized(mPidsSelfLocked) {
9204            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9205                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9206                if (!isAllowedWhileBooting(proc.info)){
9207                    if (procsToKill == null) {
9208                        procsToKill = new ArrayList<ProcessRecord>();
9209                    }
9210                    procsToKill.add(proc);
9211                }
9212            }
9213        }
9214
9215        synchronized(this) {
9216            if (procsToKill != null) {
9217                for (int i=procsToKill.size()-1; i>=0; i--) {
9218                    ProcessRecord proc = procsToKill.get(i);
9219                    Slog.i(TAG, "Removing system update proc: " + proc);
9220                    removeProcessLocked(proc, true, false, "system update done");
9221                }
9222            }
9223
9224            // Now that we have cleaned up any update processes, we
9225            // are ready to start launching real processes and know that
9226            // we won't trample on them any more.
9227            mProcessesReady = true;
9228        }
9229
9230        Slog.i(TAG, "System now ready");
9231        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9232            SystemClock.uptimeMillis());
9233
9234        synchronized(this) {
9235            // Make sure we have no pre-ready processes sitting around.
9236
9237            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9238                ResolveInfo ri = mContext.getPackageManager()
9239                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9240                                STOCK_PM_FLAGS);
9241                CharSequence errorMsg = null;
9242                if (ri != null) {
9243                    ActivityInfo ai = ri.activityInfo;
9244                    ApplicationInfo app = ai.applicationInfo;
9245                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9246                        mTopAction = Intent.ACTION_FACTORY_TEST;
9247                        mTopData = null;
9248                        mTopComponent = new ComponentName(app.packageName,
9249                                ai.name);
9250                    } else {
9251                        errorMsg = mContext.getResources().getText(
9252                                com.android.internal.R.string.factorytest_not_system);
9253                    }
9254                } else {
9255                    errorMsg = mContext.getResources().getText(
9256                            com.android.internal.R.string.factorytest_no_action);
9257                }
9258                if (errorMsg != null) {
9259                    mTopAction = null;
9260                    mTopData = null;
9261                    mTopComponent = null;
9262                    Message msg = Message.obtain();
9263                    msg.what = SHOW_FACTORY_ERROR_MSG;
9264                    msg.getData().putCharSequence("msg", errorMsg);
9265                    mHandler.sendMessage(msg);
9266                }
9267            }
9268        }
9269
9270        retrieveSettings();
9271
9272        synchronized (this) {
9273            readGrantedUriPermissionsLocked();
9274        }
9275
9276        if (goingCallback != null) goingCallback.run();
9277
9278        synchronized (this) {
9279            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9280                try {
9281                    List apps = AppGlobals.getPackageManager().
9282                        getPersistentApplications(STOCK_PM_FLAGS);
9283                    if (apps != null) {
9284                        int N = apps.size();
9285                        int i;
9286                        for (i=0; i<N; i++) {
9287                            ApplicationInfo info
9288                                = (ApplicationInfo)apps.get(i);
9289                            if (info != null &&
9290                                    !info.packageName.equals("android")) {
9291                                addAppLocked(info, false);
9292                            }
9293                        }
9294                    }
9295                } catch (RemoteException ex) {
9296                    // pm is in same process, this will never happen.
9297                }
9298            }
9299
9300            // Start up initial activity.
9301            mBooting = true;
9302
9303            try {
9304                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9305                    Message msg = Message.obtain();
9306                    msg.what = SHOW_UID_ERROR_MSG;
9307                    mHandler.sendMessage(msg);
9308                }
9309            } catch (RemoteException e) {
9310            }
9311
9312            long ident = Binder.clearCallingIdentity();
9313            try {
9314                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9315                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9316                        | Intent.FLAG_RECEIVER_FOREGROUND);
9317                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9318                broadcastIntentLocked(null, null, intent,
9319                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9320                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9321                intent = new Intent(Intent.ACTION_USER_STARTING);
9322                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9323                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9324                broadcastIntentLocked(null, null, intent,
9325                        null, new IIntentReceiver.Stub() {
9326                            @Override
9327                            public void performReceive(Intent intent, int resultCode, String data,
9328                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9329                                    throws RemoteException {
9330                            }
9331                        }, 0, null, null,
9332                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9333                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9334            } finally {
9335                Binder.restoreCallingIdentity(ident);
9336            }
9337            mStackSupervisor.resumeTopActivitiesLocked();
9338            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9339        }
9340    }
9341
9342    private boolean makeAppCrashingLocked(ProcessRecord app,
9343            String shortMsg, String longMsg, String stackTrace) {
9344        app.crashing = true;
9345        app.crashingReport = generateProcessError(app,
9346                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9347        startAppProblemLocked(app);
9348        app.stopFreezingAllLocked();
9349        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9350    }
9351
9352    private void makeAppNotRespondingLocked(ProcessRecord app,
9353            String activity, String shortMsg, String longMsg) {
9354        app.notResponding = true;
9355        app.notRespondingReport = generateProcessError(app,
9356                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9357                activity, shortMsg, longMsg, null);
9358        startAppProblemLocked(app);
9359        app.stopFreezingAllLocked();
9360    }
9361
9362    /**
9363     * Generate a process error record, suitable for attachment to a ProcessRecord.
9364     *
9365     * @param app The ProcessRecord in which the error occurred.
9366     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9367     *                      ActivityManager.AppErrorStateInfo
9368     * @param activity The activity associated with the crash, if known.
9369     * @param shortMsg Short message describing the crash.
9370     * @param longMsg Long message describing the crash.
9371     * @param stackTrace Full crash stack trace, may be null.
9372     *
9373     * @return Returns a fully-formed AppErrorStateInfo record.
9374     */
9375    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9376            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9377        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9378
9379        report.condition = condition;
9380        report.processName = app.processName;
9381        report.pid = app.pid;
9382        report.uid = app.info.uid;
9383        report.tag = activity;
9384        report.shortMsg = shortMsg;
9385        report.longMsg = longMsg;
9386        report.stackTrace = stackTrace;
9387
9388        return report;
9389    }
9390
9391    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9392        synchronized (this) {
9393            app.crashing = false;
9394            app.crashingReport = null;
9395            app.notResponding = false;
9396            app.notRespondingReport = null;
9397            if (app.anrDialog == fromDialog) {
9398                app.anrDialog = null;
9399            }
9400            if (app.waitDialog == fromDialog) {
9401                app.waitDialog = null;
9402            }
9403            if (app.pid > 0 && app.pid != MY_PID) {
9404                handleAppCrashLocked(app, null, null, null);
9405                killUnneededProcessLocked(app, "user request after error");
9406            }
9407        }
9408    }
9409
9410    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9411            String stackTrace) {
9412        long now = SystemClock.uptimeMillis();
9413
9414        Long crashTime;
9415        if (!app.isolated) {
9416            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9417        } else {
9418            crashTime = null;
9419        }
9420        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9421            // This process loses!
9422            Slog.w(TAG, "Process " + app.info.processName
9423                    + " has crashed too many times: killing!");
9424            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9425                    app.userId, app.info.processName, app.uid);
9426            mStackSupervisor.handleAppCrashLocked(app);
9427            if (!app.persistent) {
9428                // We don't want to start this process again until the user
9429                // explicitly does so...  but for persistent process, we really
9430                // need to keep it running.  If a persistent process is actually
9431                // repeatedly crashing, then badness for everyone.
9432                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9433                        app.info.processName);
9434                if (!app.isolated) {
9435                    // XXX We don't have a way to mark isolated processes
9436                    // as bad, since they don't have a peristent identity.
9437                    mBadProcesses.put(app.info.processName, app.uid,
9438                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9439                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9440                }
9441                app.bad = true;
9442                app.removed = true;
9443                // Don't let services in this process be restarted and potentially
9444                // annoy the user repeatedly.  Unless it is persistent, since those
9445                // processes run critical code.
9446                removeProcessLocked(app, false, false, "crash");
9447                mStackSupervisor.resumeTopActivitiesLocked();
9448                return false;
9449            }
9450            mStackSupervisor.resumeTopActivitiesLocked();
9451        } else {
9452            mStackSupervisor.finishTopRunningActivityLocked(app);
9453        }
9454
9455        // Bump up the crash count of any services currently running in the proc.
9456        for (int i=app.services.size()-1; i>=0; i--) {
9457            // Any services running in the application need to be placed
9458            // back in the pending list.
9459            ServiceRecord sr = app.services.valueAt(i);
9460            sr.crashCount++;
9461        }
9462
9463        // If the crashing process is what we consider to be the "home process" and it has been
9464        // replaced by a third-party app, clear the package preferred activities from packages
9465        // with a home activity running in the process to prevent a repeatedly crashing app
9466        // from blocking the user to manually clear the list.
9467        final ArrayList<ActivityRecord> activities = app.activities;
9468        if (app == mHomeProcess && activities.size() > 0
9469                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9470            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9471                final ActivityRecord r = activities.get(activityNdx);
9472                if (r.isHomeActivity()) {
9473                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9474                    try {
9475                        ActivityThread.getPackageManager()
9476                                .clearPackagePreferredActivities(r.packageName);
9477                    } catch (RemoteException c) {
9478                        // pm is in same process, this will never happen.
9479                    }
9480                }
9481            }
9482        }
9483
9484        if (!app.isolated) {
9485            // XXX Can't keep track of crash times for isolated processes,
9486            // because they don't have a perisistent identity.
9487            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9488        }
9489
9490        return true;
9491    }
9492
9493    void startAppProblemLocked(ProcessRecord app) {
9494        if (app.userId == mCurrentUserId) {
9495            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9496                    mContext, app.info.packageName, app.info.flags);
9497        } else {
9498            // If this app is not running under the current user, then we
9499            // can't give it a report button because that would require
9500            // launching the report UI under a different user.
9501            app.errorReportReceiver = null;
9502        }
9503        skipCurrentReceiverLocked(app);
9504    }
9505
9506    void skipCurrentReceiverLocked(ProcessRecord app) {
9507        for (BroadcastQueue queue : mBroadcastQueues) {
9508            queue.skipCurrentReceiverLocked(app);
9509        }
9510    }
9511
9512    /**
9513     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9514     * The application process will exit immediately after this call returns.
9515     * @param app object of the crashing app, null for the system server
9516     * @param crashInfo describing the exception
9517     */
9518    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9519        ProcessRecord r = findAppProcess(app, "Crash");
9520        final String processName = app == null ? "system_server"
9521                : (r == null ? "unknown" : r.processName);
9522
9523        handleApplicationCrashInner("crash", r, processName, crashInfo);
9524    }
9525
9526    /* Native crash reporting uses this inner version because it needs to be somewhat
9527     * decoupled from the AM-managed cleanup lifecycle
9528     */
9529    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9530            ApplicationErrorReport.CrashInfo crashInfo) {
9531        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9532                UserHandle.getUserId(Binder.getCallingUid()), processName,
9533                r == null ? -1 : r.info.flags,
9534                crashInfo.exceptionClassName,
9535                crashInfo.exceptionMessage,
9536                crashInfo.throwFileName,
9537                crashInfo.throwLineNumber);
9538
9539        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9540
9541        crashApplication(r, crashInfo);
9542    }
9543
9544    public void handleApplicationStrictModeViolation(
9545            IBinder app,
9546            int violationMask,
9547            StrictMode.ViolationInfo info) {
9548        ProcessRecord r = findAppProcess(app, "StrictMode");
9549        if (r == null) {
9550            return;
9551        }
9552
9553        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9554            Integer stackFingerprint = info.hashCode();
9555            boolean logIt = true;
9556            synchronized (mAlreadyLoggedViolatedStacks) {
9557                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9558                    logIt = false;
9559                    // TODO: sub-sample into EventLog for these, with
9560                    // the info.durationMillis?  Then we'd get
9561                    // the relative pain numbers, without logging all
9562                    // the stack traces repeatedly.  We'd want to do
9563                    // likewise in the client code, which also does
9564                    // dup suppression, before the Binder call.
9565                } else {
9566                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9567                        mAlreadyLoggedViolatedStacks.clear();
9568                    }
9569                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9570                }
9571            }
9572            if (logIt) {
9573                logStrictModeViolationToDropBox(r, info);
9574            }
9575        }
9576
9577        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9578            AppErrorResult result = new AppErrorResult();
9579            synchronized (this) {
9580                final long origId = Binder.clearCallingIdentity();
9581
9582                Message msg = Message.obtain();
9583                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9584                HashMap<String, Object> data = new HashMap<String, Object>();
9585                data.put("result", result);
9586                data.put("app", r);
9587                data.put("violationMask", violationMask);
9588                data.put("info", info);
9589                msg.obj = data;
9590                mHandler.sendMessage(msg);
9591
9592                Binder.restoreCallingIdentity(origId);
9593            }
9594            int res = result.get();
9595            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9596        }
9597    }
9598
9599    // Depending on the policy in effect, there could be a bunch of
9600    // these in quick succession so we try to batch these together to
9601    // minimize disk writes, number of dropbox entries, and maximize
9602    // compression, by having more fewer, larger records.
9603    private void logStrictModeViolationToDropBox(
9604            ProcessRecord process,
9605            StrictMode.ViolationInfo info) {
9606        if (info == null) {
9607            return;
9608        }
9609        final boolean isSystemApp = process == null ||
9610                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9611                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9612        final String processName = process == null ? "unknown" : process.processName;
9613        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9614        final DropBoxManager dbox = (DropBoxManager)
9615                mContext.getSystemService(Context.DROPBOX_SERVICE);
9616
9617        // Exit early if the dropbox isn't configured to accept this report type.
9618        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9619
9620        boolean bufferWasEmpty;
9621        boolean needsFlush;
9622        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9623        synchronized (sb) {
9624            bufferWasEmpty = sb.length() == 0;
9625            appendDropBoxProcessHeaders(process, processName, sb);
9626            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9627            sb.append("System-App: ").append(isSystemApp).append("\n");
9628            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9629            if (info.violationNumThisLoop != 0) {
9630                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9631            }
9632            if (info.numAnimationsRunning != 0) {
9633                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9634            }
9635            if (info.broadcastIntentAction != null) {
9636                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9637            }
9638            if (info.durationMillis != -1) {
9639                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9640            }
9641            if (info.numInstances != -1) {
9642                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9643            }
9644            if (info.tags != null) {
9645                for (String tag : info.tags) {
9646                    sb.append("Span-Tag: ").append(tag).append("\n");
9647                }
9648            }
9649            sb.append("\n");
9650            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9651                sb.append(info.crashInfo.stackTrace);
9652            }
9653            sb.append("\n");
9654
9655            // Only buffer up to ~64k.  Various logging bits truncate
9656            // things at 128k.
9657            needsFlush = (sb.length() > 64 * 1024);
9658        }
9659
9660        // Flush immediately if the buffer's grown too large, or this
9661        // is a non-system app.  Non-system apps are isolated with a
9662        // different tag & policy and not batched.
9663        //
9664        // Batching is useful during internal testing with
9665        // StrictMode settings turned up high.  Without batching,
9666        // thousands of separate files could be created on boot.
9667        if (!isSystemApp || needsFlush) {
9668            new Thread("Error dump: " + dropboxTag) {
9669                @Override
9670                public void run() {
9671                    String report;
9672                    synchronized (sb) {
9673                        report = sb.toString();
9674                        sb.delete(0, sb.length());
9675                        sb.trimToSize();
9676                    }
9677                    if (report.length() != 0) {
9678                        dbox.addText(dropboxTag, report);
9679                    }
9680                }
9681            }.start();
9682            return;
9683        }
9684
9685        // System app batching:
9686        if (!bufferWasEmpty) {
9687            // An existing dropbox-writing thread is outstanding, so
9688            // we don't need to start it up.  The existing thread will
9689            // catch the buffer appends we just did.
9690            return;
9691        }
9692
9693        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9694        // (After this point, we shouldn't access AMS internal data structures.)
9695        new Thread("Error dump: " + dropboxTag) {
9696            @Override
9697            public void run() {
9698                // 5 second sleep to let stacks arrive and be batched together
9699                try {
9700                    Thread.sleep(5000);  // 5 seconds
9701                } catch (InterruptedException e) {}
9702
9703                String errorReport;
9704                synchronized (mStrictModeBuffer) {
9705                    errorReport = mStrictModeBuffer.toString();
9706                    if (errorReport.length() == 0) {
9707                        return;
9708                    }
9709                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9710                    mStrictModeBuffer.trimToSize();
9711                }
9712                dbox.addText(dropboxTag, errorReport);
9713            }
9714        }.start();
9715    }
9716
9717    /**
9718     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9719     * @param app object of the crashing app, null for the system server
9720     * @param tag reported by the caller
9721     * @param crashInfo describing the context of the error
9722     * @return true if the process should exit immediately (WTF is fatal)
9723     */
9724    public boolean handleApplicationWtf(IBinder app, String tag,
9725            ApplicationErrorReport.CrashInfo crashInfo) {
9726        ProcessRecord r = findAppProcess(app, "WTF");
9727        final String processName = app == null ? "system_server"
9728                : (r == null ? "unknown" : r.processName);
9729
9730        EventLog.writeEvent(EventLogTags.AM_WTF,
9731                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9732                processName,
9733                r == null ? -1 : r.info.flags,
9734                tag, crashInfo.exceptionMessage);
9735
9736        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9737
9738        if (r != null && r.pid != Process.myPid() &&
9739                Settings.Global.getInt(mContext.getContentResolver(),
9740                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9741            crashApplication(r, crashInfo);
9742            return true;
9743        } else {
9744            return false;
9745        }
9746    }
9747
9748    /**
9749     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9750     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9751     */
9752    private ProcessRecord findAppProcess(IBinder app, String reason) {
9753        if (app == null) {
9754            return null;
9755        }
9756
9757        synchronized (this) {
9758            final int NP = mProcessNames.getMap().size();
9759            for (int ip=0; ip<NP; ip++) {
9760                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9761                final int NA = apps.size();
9762                for (int ia=0; ia<NA; ia++) {
9763                    ProcessRecord p = apps.valueAt(ia);
9764                    if (p.thread != null && p.thread.asBinder() == app) {
9765                        return p;
9766                    }
9767                }
9768            }
9769
9770            Slog.w(TAG, "Can't find mystery application for " + reason
9771                    + " from pid=" + Binder.getCallingPid()
9772                    + " uid=" + Binder.getCallingUid() + ": " + app);
9773            return null;
9774        }
9775    }
9776
9777    /**
9778     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9779     * to append various headers to the dropbox log text.
9780     */
9781    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9782            StringBuilder sb) {
9783        // Watchdog thread ends up invoking this function (with
9784        // a null ProcessRecord) to add the stack file to dropbox.
9785        // Do not acquire a lock on this (am) in such cases, as it
9786        // could cause a potential deadlock, if and when watchdog
9787        // is invoked due to unavailability of lock on am and it
9788        // would prevent watchdog from killing system_server.
9789        if (process == null) {
9790            sb.append("Process: ").append(processName).append("\n");
9791            return;
9792        }
9793        // Note: ProcessRecord 'process' is guarded by the service
9794        // instance.  (notably process.pkgList, which could otherwise change
9795        // concurrently during execution of this method)
9796        synchronized (this) {
9797            sb.append("Process: ").append(processName).append("\n");
9798            int flags = process.info.flags;
9799            IPackageManager pm = AppGlobals.getPackageManager();
9800            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9801            for (int ip=0; ip<process.pkgList.size(); ip++) {
9802                String pkg = process.pkgList.keyAt(ip);
9803                sb.append("Package: ").append(pkg);
9804                try {
9805                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9806                    if (pi != null) {
9807                        sb.append(" v").append(pi.versionCode);
9808                        if (pi.versionName != null) {
9809                            sb.append(" (").append(pi.versionName).append(")");
9810                        }
9811                    }
9812                } catch (RemoteException e) {
9813                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9814                }
9815                sb.append("\n");
9816            }
9817        }
9818    }
9819
9820    private static String processClass(ProcessRecord process) {
9821        if (process == null || process.pid == MY_PID) {
9822            return "system_server";
9823        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9824            return "system_app";
9825        } else {
9826            return "data_app";
9827        }
9828    }
9829
9830    /**
9831     * Write a description of an error (crash, WTF, ANR) to the drop box.
9832     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9833     * @param process which caused the error, null means the system server
9834     * @param activity which triggered the error, null if unknown
9835     * @param parent activity related to the error, null if unknown
9836     * @param subject line related to the error, null if absent
9837     * @param report in long form describing the error, null if absent
9838     * @param logFile to include in the report, null if none
9839     * @param crashInfo giving an application stack trace, null if absent
9840     */
9841    public void addErrorToDropBox(String eventType,
9842            ProcessRecord process, String processName, ActivityRecord activity,
9843            ActivityRecord parent, String subject,
9844            final String report, final File logFile,
9845            final ApplicationErrorReport.CrashInfo crashInfo) {
9846        // NOTE -- this must never acquire the ActivityManagerService lock,
9847        // otherwise the watchdog may be prevented from resetting the system.
9848
9849        final String dropboxTag = processClass(process) + "_" + eventType;
9850        final DropBoxManager dbox = (DropBoxManager)
9851                mContext.getSystemService(Context.DROPBOX_SERVICE);
9852
9853        // Exit early if the dropbox isn't configured to accept this report type.
9854        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9855
9856        final StringBuilder sb = new StringBuilder(1024);
9857        appendDropBoxProcessHeaders(process, processName, sb);
9858        if (activity != null) {
9859            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9860        }
9861        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9862            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9863        }
9864        if (parent != null && parent != activity) {
9865            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9866        }
9867        if (subject != null) {
9868            sb.append("Subject: ").append(subject).append("\n");
9869        }
9870        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9871        if (Debug.isDebuggerConnected()) {
9872            sb.append("Debugger: Connected\n");
9873        }
9874        sb.append("\n");
9875
9876        // Do the rest in a worker thread to avoid blocking the caller on I/O
9877        // (After this point, we shouldn't access AMS internal data structures.)
9878        Thread worker = new Thread("Error dump: " + dropboxTag) {
9879            @Override
9880            public void run() {
9881                if (report != null) {
9882                    sb.append(report);
9883                }
9884                if (logFile != null) {
9885                    try {
9886                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9887                                    "\n\n[[TRUNCATED]]"));
9888                    } catch (IOException e) {
9889                        Slog.e(TAG, "Error reading " + logFile, e);
9890                    }
9891                }
9892                if (crashInfo != null && crashInfo.stackTrace != null) {
9893                    sb.append(crashInfo.stackTrace);
9894                }
9895
9896                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9897                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9898                if (lines > 0) {
9899                    sb.append("\n");
9900
9901                    // Merge several logcat streams, and take the last N lines
9902                    InputStreamReader input = null;
9903                    try {
9904                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9905                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9906                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9907
9908                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9909                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9910                        input = new InputStreamReader(logcat.getInputStream());
9911
9912                        int num;
9913                        char[] buf = new char[8192];
9914                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9915                    } catch (IOException e) {
9916                        Slog.e(TAG, "Error running logcat", e);
9917                    } finally {
9918                        if (input != null) try { input.close(); } catch (IOException e) {}
9919                    }
9920                }
9921
9922                dbox.addText(dropboxTag, sb.toString());
9923            }
9924        };
9925
9926        if (process == null) {
9927            // If process is null, we are being called from some internal code
9928            // and may be about to die -- run this synchronously.
9929            worker.run();
9930        } else {
9931            worker.start();
9932        }
9933    }
9934
9935    /**
9936     * Bring up the "unexpected error" dialog box for a crashing app.
9937     * Deal with edge cases (intercepts from instrumented applications,
9938     * ActivityController, error intent receivers, that sort of thing).
9939     * @param r the application crashing
9940     * @param crashInfo describing the failure
9941     */
9942    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
9943        long timeMillis = System.currentTimeMillis();
9944        String shortMsg = crashInfo.exceptionClassName;
9945        String longMsg = crashInfo.exceptionMessage;
9946        String stackTrace = crashInfo.stackTrace;
9947        if (shortMsg != null && longMsg != null) {
9948            longMsg = shortMsg + ": " + longMsg;
9949        } else if (shortMsg != null) {
9950            longMsg = shortMsg;
9951        }
9952
9953        AppErrorResult result = new AppErrorResult();
9954        synchronized (this) {
9955            if (mController != null) {
9956                try {
9957                    String name = r != null ? r.processName : null;
9958                    int pid = r != null ? r.pid : Binder.getCallingPid();
9959                    if (!mController.appCrashed(name, pid,
9960                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
9961                        Slog.w(TAG, "Force-killing crashed app " + name
9962                                + " at watcher's request");
9963                        Process.killProcess(pid);
9964                        return;
9965                    }
9966                } catch (RemoteException e) {
9967                    mController = null;
9968                    Watchdog.getInstance().setActivityController(null);
9969                }
9970            }
9971
9972            final long origId = Binder.clearCallingIdentity();
9973
9974            // If this process is running instrumentation, finish it.
9975            if (r != null && r.instrumentationClass != null) {
9976                Slog.w(TAG, "Error in app " + r.processName
9977                      + " running instrumentation " + r.instrumentationClass + ":");
9978                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
9979                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
9980                Bundle info = new Bundle();
9981                info.putString("shortMsg", shortMsg);
9982                info.putString("longMsg", longMsg);
9983                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
9984                Binder.restoreCallingIdentity(origId);
9985                return;
9986            }
9987
9988            // If we can't identify the process or it's already exceeded its crash quota,
9989            // quit right away without showing a crash dialog.
9990            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
9991                Binder.restoreCallingIdentity(origId);
9992                return;
9993            }
9994
9995            Message msg = Message.obtain();
9996            msg.what = SHOW_ERROR_MSG;
9997            HashMap data = new HashMap();
9998            data.put("result", result);
9999            data.put("app", r);
10000            msg.obj = data;
10001            mHandler.sendMessage(msg);
10002
10003            Binder.restoreCallingIdentity(origId);
10004        }
10005
10006        int res = result.get();
10007
10008        Intent appErrorIntent = null;
10009        synchronized (this) {
10010            if (r != null && !r.isolated) {
10011                // XXX Can't keep track of crash time for isolated processes,
10012                // since they don't have a persistent identity.
10013                mProcessCrashTimes.put(r.info.processName, r.uid,
10014                        SystemClock.uptimeMillis());
10015            }
10016            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10017                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10018            }
10019        }
10020
10021        if (appErrorIntent != null) {
10022            try {
10023                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10024            } catch (ActivityNotFoundException e) {
10025                Slog.w(TAG, "bug report receiver dissappeared", e);
10026            }
10027        }
10028    }
10029
10030    Intent createAppErrorIntentLocked(ProcessRecord r,
10031            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10032        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10033        if (report == null) {
10034            return null;
10035        }
10036        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10037        result.setComponent(r.errorReportReceiver);
10038        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10039        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10040        return result;
10041    }
10042
10043    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10044            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10045        if (r.errorReportReceiver == null) {
10046            return null;
10047        }
10048
10049        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10050            return null;
10051        }
10052
10053        ApplicationErrorReport report = new ApplicationErrorReport();
10054        report.packageName = r.info.packageName;
10055        report.installerPackageName = r.errorReportReceiver.getPackageName();
10056        report.processName = r.processName;
10057        report.time = timeMillis;
10058        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10059
10060        if (r.crashing || r.forceCrashReport) {
10061            report.type = ApplicationErrorReport.TYPE_CRASH;
10062            report.crashInfo = crashInfo;
10063        } else if (r.notResponding) {
10064            report.type = ApplicationErrorReport.TYPE_ANR;
10065            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10066
10067            report.anrInfo.activity = r.notRespondingReport.tag;
10068            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10069            report.anrInfo.info = r.notRespondingReport.longMsg;
10070        }
10071
10072        return report;
10073    }
10074
10075    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10076        enforceNotIsolatedCaller("getProcessesInErrorState");
10077        // assume our apps are happy - lazy create the list
10078        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10079
10080        final boolean allUsers = ActivityManager.checkUidPermission(
10081                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10082                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10083        int userId = UserHandle.getUserId(Binder.getCallingUid());
10084
10085        synchronized (this) {
10086
10087            // iterate across all processes
10088            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10089                ProcessRecord app = mLruProcesses.get(i);
10090                if (!allUsers && app.userId != userId) {
10091                    continue;
10092                }
10093                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10094                    // This one's in trouble, so we'll generate a report for it
10095                    // crashes are higher priority (in case there's a crash *and* an anr)
10096                    ActivityManager.ProcessErrorStateInfo report = null;
10097                    if (app.crashing) {
10098                        report = app.crashingReport;
10099                    } else if (app.notResponding) {
10100                        report = app.notRespondingReport;
10101                    }
10102
10103                    if (report != null) {
10104                        if (errList == null) {
10105                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10106                        }
10107                        errList.add(report);
10108                    } else {
10109                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10110                                " crashing = " + app.crashing +
10111                                " notResponding = " + app.notResponding);
10112                    }
10113                }
10114            }
10115        }
10116
10117        return errList;
10118    }
10119
10120    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10121        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10122            if (currApp != null) {
10123                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10124            }
10125            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10126        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10127            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10128        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10129            if (currApp != null) {
10130                currApp.lru = 0;
10131            }
10132            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10133        } else if (adj >= ProcessList.SERVICE_ADJ) {
10134            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10135        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10136            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10137        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10138            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10139        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10140            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10141        } else {
10142            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10143        }
10144    }
10145
10146    private void fillInProcMemInfo(ProcessRecord app,
10147            ActivityManager.RunningAppProcessInfo outInfo) {
10148        outInfo.pid = app.pid;
10149        outInfo.uid = app.info.uid;
10150        if (mHeavyWeightProcess == app) {
10151            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10152        }
10153        if (app.persistent) {
10154            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10155        }
10156        if (app.activities.size() > 0) {
10157            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10158        }
10159        outInfo.lastTrimLevel = app.trimMemoryLevel;
10160        int adj = app.curAdj;
10161        outInfo.importance = oomAdjToImportance(adj, outInfo);
10162        outInfo.importanceReasonCode = app.adjTypeCode;
10163    }
10164
10165    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10166        enforceNotIsolatedCaller("getRunningAppProcesses");
10167        // Lazy instantiation of list
10168        List<ActivityManager.RunningAppProcessInfo> runList = null;
10169        final boolean allUsers = ActivityManager.checkUidPermission(
10170                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10171                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10172        int userId = UserHandle.getUserId(Binder.getCallingUid());
10173        synchronized (this) {
10174            // Iterate across all processes
10175            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10176                ProcessRecord app = mLruProcesses.get(i);
10177                if (!allUsers && app.userId != userId) {
10178                    continue;
10179                }
10180                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10181                    // Generate process state info for running application
10182                    ActivityManager.RunningAppProcessInfo currApp =
10183                        new ActivityManager.RunningAppProcessInfo(app.processName,
10184                                app.pid, app.getPackageList());
10185                    fillInProcMemInfo(app, currApp);
10186                    if (app.adjSource instanceof ProcessRecord) {
10187                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10188                        currApp.importanceReasonImportance = oomAdjToImportance(
10189                                app.adjSourceOom, null);
10190                    } else if (app.adjSource instanceof ActivityRecord) {
10191                        ActivityRecord r = (ActivityRecord)app.adjSource;
10192                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10193                    }
10194                    if (app.adjTarget instanceof ComponentName) {
10195                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10196                    }
10197                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10198                    //        + " lru=" + currApp.lru);
10199                    if (runList == null) {
10200                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10201                    }
10202                    runList.add(currApp);
10203                }
10204            }
10205        }
10206        return runList;
10207    }
10208
10209    public List<ApplicationInfo> getRunningExternalApplications() {
10210        enforceNotIsolatedCaller("getRunningExternalApplications");
10211        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10212        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10213        if (runningApps != null && runningApps.size() > 0) {
10214            Set<String> extList = new HashSet<String>();
10215            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10216                if (app.pkgList != null) {
10217                    for (String pkg : app.pkgList) {
10218                        extList.add(pkg);
10219                    }
10220                }
10221            }
10222            IPackageManager pm = AppGlobals.getPackageManager();
10223            for (String pkg : extList) {
10224                try {
10225                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10226                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10227                        retList.add(info);
10228                    }
10229                } catch (RemoteException e) {
10230                }
10231            }
10232        }
10233        return retList;
10234    }
10235
10236    @Override
10237    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10238        enforceNotIsolatedCaller("getMyMemoryState");
10239        synchronized (this) {
10240            ProcessRecord proc;
10241            synchronized (mPidsSelfLocked) {
10242                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10243            }
10244            fillInProcMemInfo(proc, outInfo);
10245        }
10246    }
10247
10248    @Override
10249    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10250        if (checkCallingPermission(android.Manifest.permission.DUMP)
10251                != PackageManager.PERMISSION_GRANTED) {
10252            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10253                    + Binder.getCallingPid()
10254                    + ", uid=" + Binder.getCallingUid()
10255                    + " without permission "
10256                    + android.Manifest.permission.DUMP);
10257            return;
10258        }
10259
10260        boolean dumpAll = false;
10261        boolean dumpClient = false;
10262        String dumpPackage = null;
10263
10264        int opti = 0;
10265        while (opti < args.length) {
10266            String opt = args[opti];
10267            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10268                break;
10269            }
10270            opti++;
10271            if ("-a".equals(opt)) {
10272                dumpAll = true;
10273            } else if ("-c".equals(opt)) {
10274                dumpClient = true;
10275            } else if ("-h".equals(opt)) {
10276                pw.println("Activity manager dump options:");
10277                pw.println("  [-a] [-c] [-h] [cmd] ...");
10278                pw.println("  cmd may be one of:");
10279                pw.println("    a[ctivities]: activity stack state");
10280                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10281                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10282                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10283                pw.println("    o[om]: out of memory management");
10284                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10285                pw.println("    provider [COMP_SPEC]: provider client-side state");
10286                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10287                pw.println("    service [COMP_SPEC]: service client-side state");
10288                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10289                pw.println("    all: dump all activities");
10290                pw.println("    top: dump the top activity");
10291                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10292                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10293                pw.println("    a partial substring in a component name, a");
10294                pw.println("    hex object identifier.");
10295                pw.println("  -a: include all available server state.");
10296                pw.println("  -c: include client state.");
10297                return;
10298            } else {
10299                pw.println("Unknown argument: " + opt + "; use -h for help");
10300            }
10301        }
10302
10303        long origId = Binder.clearCallingIdentity();
10304        boolean more = false;
10305        // Is the caller requesting to dump a particular piece of data?
10306        if (opti < args.length) {
10307            String cmd = args[opti];
10308            opti++;
10309            if ("activities".equals(cmd) || "a".equals(cmd)) {
10310                synchronized (this) {
10311                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10312                }
10313            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10314                String[] newArgs;
10315                String name;
10316                if (opti >= args.length) {
10317                    name = null;
10318                    newArgs = EMPTY_STRING_ARRAY;
10319                } else {
10320                    name = args[opti];
10321                    opti++;
10322                    newArgs = new String[args.length - opti];
10323                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10324                            args.length - opti);
10325                }
10326                synchronized (this) {
10327                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10328                }
10329            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10330                String[] newArgs;
10331                String name;
10332                if (opti >= args.length) {
10333                    name = null;
10334                    newArgs = EMPTY_STRING_ARRAY;
10335                } else {
10336                    name = args[opti];
10337                    opti++;
10338                    newArgs = new String[args.length - opti];
10339                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10340                            args.length - opti);
10341                }
10342                synchronized (this) {
10343                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10344                }
10345            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10346                String[] newArgs;
10347                String name;
10348                if (opti >= args.length) {
10349                    name = null;
10350                    newArgs = EMPTY_STRING_ARRAY;
10351                } else {
10352                    name = args[opti];
10353                    opti++;
10354                    newArgs = new String[args.length - opti];
10355                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10356                            args.length - opti);
10357                }
10358                synchronized (this) {
10359                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10360                }
10361            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10362                synchronized (this) {
10363                    dumpOomLocked(fd, pw, args, opti, true);
10364                }
10365            } else if ("provider".equals(cmd)) {
10366                String[] newArgs;
10367                String name;
10368                if (opti >= args.length) {
10369                    name = null;
10370                    newArgs = EMPTY_STRING_ARRAY;
10371                } else {
10372                    name = args[opti];
10373                    opti++;
10374                    newArgs = new String[args.length - opti];
10375                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10376                }
10377                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10378                    pw.println("No providers match: " + name);
10379                    pw.println("Use -h for help.");
10380                }
10381            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10382                synchronized (this) {
10383                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10384                }
10385            } else if ("service".equals(cmd)) {
10386                String[] newArgs;
10387                String name;
10388                if (opti >= args.length) {
10389                    name = null;
10390                    newArgs = EMPTY_STRING_ARRAY;
10391                } else {
10392                    name = args[opti];
10393                    opti++;
10394                    newArgs = new String[args.length - opti];
10395                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10396                            args.length - opti);
10397                }
10398                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10399                    pw.println("No services match: " + name);
10400                    pw.println("Use -h for help.");
10401                }
10402            } else if ("package".equals(cmd)) {
10403                String[] newArgs;
10404                if (opti >= args.length) {
10405                    pw.println("package: no package name specified");
10406                    pw.println("Use -h for help.");
10407                } else {
10408                    dumpPackage = args[opti];
10409                    opti++;
10410                    newArgs = new String[args.length - opti];
10411                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10412                            args.length - opti);
10413                    args = newArgs;
10414                    opti = 0;
10415                    more = true;
10416                }
10417            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10418                synchronized (this) {
10419                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10420                }
10421            } else {
10422                // Dumping a single activity?
10423                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10424                    pw.println("Bad activity command, or no activities match: " + cmd);
10425                    pw.println("Use -h for help.");
10426                }
10427            }
10428            if (!more) {
10429                Binder.restoreCallingIdentity(origId);
10430                return;
10431            }
10432        }
10433
10434        // No piece of data specified, dump everything.
10435        synchronized (this) {
10436            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10437            pw.println();
10438            if (dumpAll) {
10439                pw.println("-------------------------------------------------------------------------------");
10440            }
10441            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10442            pw.println();
10443            if (dumpAll) {
10444                pw.println("-------------------------------------------------------------------------------");
10445            }
10446            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10447            pw.println();
10448            if (dumpAll) {
10449                pw.println("-------------------------------------------------------------------------------");
10450            }
10451            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10452            pw.println();
10453            if (dumpAll) {
10454                pw.println("-------------------------------------------------------------------------------");
10455            }
10456            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10457            pw.println();
10458            if (dumpAll) {
10459                pw.println("-------------------------------------------------------------------------------");
10460            }
10461            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10462        }
10463        Binder.restoreCallingIdentity(origId);
10464    }
10465
10466    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10467            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10468        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10469
10470        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10471                dumpPackage);
10472        boolean needSep = printedAnything;
10473
10474        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10475                dumpPackage, needSep, "  mFocusedActivity: ");
10476        if (printed) {
10477            printedAnything = true;
10478            needSep = false;
10479        }
10480
10481        if (dumpPackage == null) {
10482            if (needSep) {
10483                pw.println();
10484            }
10485            needSep = true;
10486            printedAnything = true;
10487            mStackSupervisor.dump(pw, "  ");
10488        }
10489
10490        if (mRecentTasks.size() > 0) {
10491            boolean printedHeader = false;
10492
10493            final int N = mRecentTasks.size();
10494            for (int i=0; i<N; i++) {
10495                TaskRecord tr = mRecentTasks.get(i);
10496                if (dumpPackage != null) {
10497                    if (tr.realActivity == null ||
10498                            !dumpPackage.equals(tr.realActivity)) {
10499                        continue;
10500                    }
10501                }
10502                if (!printedHeader) {
10503                    if (needSep) {
10504                        pw.println();
10505                    }
10506                    pw.println("  Recent tasks:");
10507                    printedHeader = true;
10508                    printedAnything = true;
10509                }
10510                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10511                        pw.println(tr);
10512                if (dumpAll) {
10513                    mRecentTasks.get(i).dump(pw, "    ");
10514                }
10515            }
10516        }
10517
10518        if (!printedAnything) {
10519            pw.println("  (nothing)");
10520        }
10521    }
10522
10523    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10524            int opti, boolean dumpAll, String dumpPackage) {
10525        boolean needSep = false;
10526        boolean printedAnything = false;
10527        int numPers = 0;
10528
10529        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10530
10531        if (dumpAll) {
10532            final int NP = mProcessNames.getMap().size();
10533            for (int ip=0; ip<NP; ip++) {
10534                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10535                final int NA = procs.size();
10536                for (int ia=0; ia<NA; ia++) {
10537                    ProcessRecord r = procs.valueAt(ia);
10538                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10539                        continue;
10540                    }
10541                    if (!needSep) {
10542                        pw.println("  All known processes:");
10543                        needSep = true;
10544                        printedAnything = true;
10545                    }
10546                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10547                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10548                        pw.print(" "); pw.println(r);
10549                    r.dump(pw, "    ");
10550                    if (r.persistent) {
10551                        numPers++;
10552                    }
10553                }
10554            }
10555        }
10556
10557        if (mIsolatedProcesses.size() > 0) {
10558            boolean printed = false;
10559            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10560                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10561                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10562                    continue;
10563                }
10564                if (!printed) {
10565                    if (needSep) {
10566                        pw.println();
10567                    }
10568                    pw.println("  Isolated process list (sorted by uid):");
10569                    printedAnything = true;
10570                    printed = true;
10571                    needSep = true;
10572                }
10573                pw.println(String.format("%sIsolated #%2d: %s",
10574                        "    ", i, r.toString()));
10575            }
10576        }
10577
10578        if (mLruProcesses.size() > 0) {
10579            if (needSep) {
10580                pw.println();
10581            }
10582            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10583                    pw.print(" total, non-act at ");
10584                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10585                    pw.print(", non-svc at ");
10586                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10587                    pw.println("):");
10588            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10589            needSep = true;
10590            printedAnything = true;
10591        }
10592
10593        if (dumpAll || dumpPackage != null) {
10594            synchronized (mPidsSelfLocked) {
10595                boolean printed = false;
10596                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10597                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10598                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10599                        continue;
10600                    }
10601                    if (!printed) {
10602                        if (needSep) pw.println();
10603                        needSep = true;
10604                        pw.println("  PID mappings:");
10605                        printed = true;
10606                        printedAnything = true;
10607                    }
10608                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10609                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10610                }
10611            }
10612        }
10613
10614        if (mForegroundProcesses.size() > 0) {
10615            synchronized (mPidsSelfLocked) {
10616                boolean printed = false;
10617                for (int i=0; i<mForegroundProcesses.size(); i++) {
10618                    ProcessRecord r = mPidsSelfLocked.get(
10619                            mForegroundProcesses.valueAt(i).pid);
10620                    if (dumpPackage != null && (r == null
10621                            || !r.pkgList.containsKey(dumpPackage))) {
10622                        continue;
10623                    }
10624                    if (!printed) {
10625                        if (needSep) pw.println();
10626                        needSep = true;
10627                        pw.println("  Foreground Processes:");
10628                        printed = true;
10629                        printedAnything = true;
10630                    }
10631                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10632                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10633                }
10634            }
10635        }
10636
10637        if (mPersistentStartingProcesses.size() > 0) {
10638            if (needSep) pw.println();
10639            needSep = true;
10640            printedAnything = true;
10641            pw.println("  Persisent processes that are starting:");
10642            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10643                    "Starting Norm", "Restarting PERS", dumpPackage);
10644        }
10645
10646        if (mRemovedProcesses.size() > 0) {
10647            if (needSep) pw.println();
10648            needSep = true;
10649            printedAnything = true;
10650            pw.println("  Processes that are being removed:");
10651            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10652                    "Removed Norm", "Removed PERS", dumpPackage);
10653        }
10654
10655        if (mProcessesOnHold.size() > 0) {
10656            if (needSep) pw.println();
10657            needSep = true;
10658            printedAnything = true;
10659            pw.println("  Processes that are on old until the system is ready:");
10660            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10661                    "OnHold Norm", "OnHold PERS", dumpPackage);
10662        }
10663
10664        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10665
10666        if (mProcessCrashTimes.getMap().size() > 0) {
10667            boolean printed = false;
10668            long now = SystemClock.uptimeMillis();
10669            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10670            final int NP = pmap.size();
10671            for (int ip=0; ip<NP; ip++) {
10672                String pname = pmap.keyAt(ip);
10673                SparseArray<Long> uids = pmap.valueAt(ip);
10674                final int N = uids.size();
10675                for (int i=0; i<N; i++) {
10676                    int puid = uids.keyAt(i);
10677                    ProcessRecord r = mProcessNames.get(pname, puid);
10678                    if (dumpPackage != null && (r == null
10679                            || !r.pkgList.containsKey(dumpPackage))) {
10680                        continue;
10681                    }
10682                    if (!printed) {
10683                        if (needSep) pw.println();
10684                        needSep = true;
10685                        pw.println("  Time since processes crashed:");
10686                        printed = true;
10687                        printedAnything = true;
10688                    }
10689                    pw.print("    Process "); pw.print(pname);
10690                            pw.print(" uid "); pw.print(puid);
10691                            pw.print(": last crashed ");
10692                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10693                            pw.println(" ago");
10694                }
10695            }
10696        }
10697
10698        if (mBadProcesses.getMap().size() > 0) {
10699            boolean printed = false;
10700            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10701            final int NP = pmap.size();
10702            for (int ip=0; ip<NP; ip++) {
10703                String pname = pmap.keyAt(ip);
10704                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10705                final int N = uids.size();
10706                for (int i=0; i<N; i++) {
10707                    int puid = uids.keyAt(i);
10708                    ProcessRecord r = mProcessNames.get(pname, puid);
10709                    if (dumpPackage != null && (r == null
10710                            || !r.pkgList.containsKey(dumpPackage))) {
10711                        continue;
10712                    }
10713                    if (!printed) {
10714                        if (needSep) pw.println();
10715                        needSep = true;
10716                        pw.println("  Bad processes:");
10717                        printedAnything = true;
10718                    }
10719                    BadProcessInfo info = uids.valueAt(i);
10720                    pw.print("    Bad process "); pw.print(pname);
10721                            pw.print(" uid "); pw.print(puid);
10722                            pw.print(": crashed at time "); pw.println(info.time);
10723                    if (info.shortMsg != null) {
10724                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10725                    }
10726                    if (info.longMsg != null) {
10727                        pw.print("      Long msg: "); pw.println(info.longMsg);
10728                    }
10729                    if (info.stack != null) {
10730                        pw.println("      Stack:");
10731                        int lastPos = 0;
10732                        for (int pos=0; pos<info.stack.length(); pos++) {
10733                            if (info.stack.charAt(pos) == '\n') {
10734                                pw.print("        ");
10735                                pw.write(info.stack, lastPos, pos-lastPos);
10736                                pw.println();
10737                                lastPos = pos+1;
10738                            }
10739                        }
10740                        if (lastPos < info.stack.length()) {
10741                            pw.print("        ");
10742                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10743                            pw.println();
10744                        }
10745                    }
10746                }
10747            }
10748        }
10749
10750        if (dumpPackage == null) {
10751            pw.println();
10752            needSep = false;
10753            pw.println("  mStartedUsers:");
10754            for (int i=0; i<mStartedUsers.size(); i++) {
10755                UserStartedState uss = mStartedUsers.valueAt(i);
10756                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10757                        pw.print(": "); uss.dump("", pw);
10758            }
10759            pw.print("  mStartedUserArray: [");
10760            for (int i=0; i<mStartedUserArray.length; i++) {
10761                if (i > 0) pw.print(", ");
10762                pw.print(mStartedUserArray[i]);
10763            }
10764            pw.println("]");
10765            pw.print("  mUserLru: [");
10766            for (int i=0; i<mUserLru.size(); i++) {
10767                if (i > 0) pw.print(", ");
10768                pw.print(mUserLru.get(i));
10769            }
10770            pw.println("]");
10771            if (dumpAll) {
10772                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10773            }
10774        }
10775        if (mHomeProcess != null && (dumpPackage == null
10776                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10777            if (needSep) {
10778                pw.println();
10779                needSep = false;
10780            }
10781            pw.println("  mHomeProcess: " + mHomeProcess);
10782        }
10783        if (mPreviousProcess != null && (dumpPackage == null
10784                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10785            if (needSep) {
10786                pw.println();
10787                needSep = false;
10788            }
10789            pw.println("  mPreviousProcess: " + mPreviousProcess);
10790        }
10791        if (dumpAll) {
10792            StringBuilder sb = new StringBuilder(128);
10793            sb.append("  mPreviousProcessVisibleTime: ");
10794            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10795            pw.println(sb);
10796        }
10797        if (mHeavyWeightProcess != null && (dumpPackage == null
10798                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10799            if (needSep) {
10800                pw.println();
10801                needSep = false;
10802            }
10803            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10804        }
10805        if (dumpPackage == null) {
10806            pw.println("  mConfiguration: " + mConfiguration);
10807        }
10808        if (dumpAll) {
10809            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10810            if (mCompatModePackages.getPackages().size() > 0) {
10811                boolean printed = false;
10812                for (Map.Entry<String, Integer> entry
10813                        : mCompatModePackages.getPackages().entrySet()) {
10814                    String pkg = entry.getKey();
10815                    int mode = entry.getValue();
10816                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10817                        continue;
10818                    }
10819                    if (!printed) {
10820                        pw.println("  mScreenCompatPackages:");
10821                        printed = true;
10822                    }
10823                    pw.print("    "); pw.print(pkg); pw.print(": ");
10824                            pw.print(mode); pw.println();
10825                }
10826            }
10827        }
10828        if (dumpPackage == null) {
10829            if (mSleeping || mWentToSleep || mLockScreenShown) {
10830                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10831                        + " mLockScreenShown " + mLockScreenShown);
10832            }
10833            if (mShuttingDown) {
10834                pw.println("  mShuttingDown=" + mShuttingDown);
10835            }
10836        }
10837        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10838                || mOrigWaitForDebugger) {
10839            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10840                    || dumpPackage.equals(mOrigDebugApp)) {
10841                if (needSep) {
10842                    pw.println();
10843                    needSep = false;
10844                }
10845                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10846                        + " mDebugTransient=" + mDebugTransient
10847                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10848            }
10849        }
10850        if (mOpenGlTraceApp != null) {
10851            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10852                if (needSep) {
10853                    pw.println();
10854                    needSep = false;
10855                }
10856                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10857            }
10858        }
10859        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10860                || mProfileFd != null) {
10861            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10862                if (needSep) {
10863                    pw.println();
10864                    needSep = false;
10865                }
10866                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10867                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10868                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10869                        + mAutoStopProfiler);
10870            }
10871        }
10872        if (dumpPackage == null) {
10873            if (mAlwaysFinishActivities || mController != null) {
10874                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10875                        + " mController=" + mController);
10876            }
10877            if (dumpAll) {
10878                pw.println("  Total persistent processes: " + numPers);
10879                pw.println("  mStartRunning=" + mStartRunning
10880                        + " mProcessesReady=" + mProcessesReady
10881                        + " mSystemReady=" + mSystemReady);
10882                pw.println("  mBooting=" + mBooting
10883                        + " mBooted=" + mBooted
10884                        + " mFactoryTest=" + mFactoryTest);
10885                pw.print("  mLastPowerCheckRealtime=");
10886                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10887                        pw.println("");
10888                pw.print("  mLastPowerCheckUptime=");
10889                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10890                        pw.println("");
10891                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10892                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10893                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10894                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10895                        + " (" + mLruProcesses.size() + " total)"
10896                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10897                        + " mNumServiceProcs=" + mNumServiceProcs
10898                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10899                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10900                        + " mLastMemoryLevel" + mLastMemoryLevel
10901                        + " mLastNumProcesses" + mLastNumProcesses);
10902                long now = SystemClock.uptimeMillis();
10903                pw.print("  mLastIdleTime=");
10904                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10905                        pw.print(" mLowRamSinceLastIdle=");
10906                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10907                        pw.println();
10908            }
10909        }
10910
10911        if (!printedAnything) {
10912            pw.println("  (nothing)");
10913        }
10914    }
10915
10916    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10917            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10918        if (mProcessesToGc.size() > 0) {
10919            boolean printed = false;
10920            long now = SystemClock.uptimeMillis();
10921            for (int i=0; i<mProcessesToGc.size(); i++) {
10922                ProcessRecord proc = mProcessesToGc.get(i);
10923                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10924                    continue;
10925                }
10926                if (!printed) {
10927                    if (needSep) pw.println();
10928                    needSep = true;
10929                    pw.println("  Processes that are waiting to GC:");
10930                    printed = true;
10931                }
10932                pw.print("    Process "); pw.println(proc);
10933                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
10934                        pw.print(", last gced=");
10935                        pw.print(now-proc.lastRequestedGc);
10936                        pw.print(" ms ago, last lowMem=");
10937                        pw.print(now-proc.lastLowMemory);
10938                        pw.println(" ms ago");
10939
10940            }
10941        }
10942        return needSep;
10943    }
10944
10945    void printOomLevel(PrintWriter pw, String name, int adj) {
10946        pw.print("    ");
10947        if (adj >= 0) {
10948            pw.print(' ');
10949            if (adj < 10) pw.print(' ');
10950        } else {
10951            if (adj > -10) pw.print(' ');
10952        }
10953        pw.print(adj);
10954        pw.print(": ");
10955        pw.print(name);
10956        pw.print(" (");
10957        pw.print(mProcessList.getMemLevel(adj)/1024);
10958        pw.println(" kB)");
10959    }
10960
10961    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10962            int opti, boolean dumpAll) {
10963        boolean needSep = false;
10964
10965        if (mLruProcesses.size() > 0) {
10966            if (needSep) pw.println();
10967            needSep = true;
10968            pw.println("  OOM levels:");
10969            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
10970            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
10971            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
10972            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
10973            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
10974            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
10975            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
10976            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
10977            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
10978            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
10979            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
10980            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
10981            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
10982
10983            if (needSep) pw.println();
10984            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
10985                    pw.print(" total, non-act at ");
10986                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10987                    pw.print(", non-svc at ");
10988                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10989                    pw.println("):");
10990            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
10991            needSep = true;
10992        }
10993
10994        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
10995
10996        pw.println();
10997        pw.println("  mHomeProcess: " + mHomeProcess);
10998        pw.println("  mPreviousProcess: " + mPreviousProcess);
10999        if (mHeavyWeightProcess != null) {
11000            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11001        }
11002
11003        return true;
11004    }
11005
11006    /**
11007     * There are three ways to call this:
11008     *  - no provider specified: dump all the providers
11009     *  - a flattened component name that matched an existing provider was specified as the
11010     *    first arg: dump that one provider
11011     *  - the first arg isn't the flattened component name of an existing provider:
11012     *    dump all providers whose component contains the first arg as a substring
11013     */
11014    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11015            int opti, boolean dumpAll) {
11016        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11017    }
11018
11019    static class ItemMatcher {
11020        ArrayList<ComponentName> components;
11021        ArrayList<String> strings;
11022        ArrayList<Integer> objects;
11023        boolean all;
11024
11025        ItemMatcher() {
11026            all = true;
11027        }
11028
11029        void build(String name) {
11030            ComponentName componentName = ComponentName.unflattenFromString(name);
11031            if (componentName != null) {
11032                if (components == null) {
11033                    components = new ArrayList<ComponentName>();
11034                }
11035                components.add(componentName);
11036                all = false;
11037            } else {
11038                int objectId = 0;
11039                // Not a '/' separated full component name; maybe an object ID?
11040                try {
11041                    objectId = Integer.parseInt(name, 16);
11042                    if (objects == null) {
11043                        objects = new ArrayList<Integer>();
11044                    }
11045                    objects.add(objectId);
11046                    all = false;
11047                } catch (RuntimeException e) {
11048                    // Not an integer; just do string match.
11049                    if (strings == null) {
11050                        strings = new ArrayList<String>();
11051                    }
11052                    strings.add(name);
11053                    all = false;
11054                }
11055            }
11056        }
11057
11058        int build(String[] args, int opti) {
11059            for (; opti<args.length; opti++) {
11060                String name = args[opti];
11061                if ("--".equals(name)) {
11062                    return opti+1;
11063                }
11064                build(name);
11065            }
11066            return opti;
11067        }
11068
11069        boolean match(Object object, ComponentName comp) {
11070            if (all) {
11071                return true;
11072            }
11073            if (components != null) {
11074                for (int i=0; i<components.size(); i++) {
11075                    if (components.get(i).equals(comp)) {
11076                        return true;
11077                    }
11078                }
11079            }
11080            if (objects != null) {
11081                for (int i=0; i<objects.size(); i++) {
11082                    if (System.identityHashCode(object) == objects.get(i)) {
11083                        return true;
11084                    }
11085                }
11086            }
11087            if (strings != null) {
11088                String flat = comp.flattenToString();
11089                for (int i=0; i<strings.size(); i++) {
11090                    if (flat.contains(strings.get(i))) {
11091                        return true;
11092                    }
11093                }
11094            }
11095            return false;
11096        }
11097    }
11098
11099    /**
11100     * There are three things that cmd can be:
11101     *  - a flattened component name that matches an existing activity
11102     *  - the cmd arg isn't the flattened component name of an existing activity:
11103     *    dump all activity whose component contains the cmd as a substring
11104     *  - A hex number of the ActivityRecord object instance.
11105     */
11106    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11107            int opti, boolean dumpAll) {
11108        ArrayList<ActivityRecord> activities;
11109
11110        synchronized (this) {
11111            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11112        }
11113
11114        if (activities.size() <= 0) {
11115            return false;
11116        }
11117
11118        String[] newArgs = new String[args.length - opti];
11119        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11120
11121        TaskRecord lastTask = null;
11122        boolean needSep = false;
11123        for (int i=activities.size()-1; i>=0; i--) {
11124            ActivityRecord r = activities.get(i);
11125            if (needSep) {
11126                pw.println();
11127            }
11128            needSep = true;
11129            synchronized (this) {
11130                if (lastTask != r.task) {
11131                    lastTask = r.task;
11132                    pw.print("TASK "); pw.print(lastTask.affinity);
11133                            pw.print(" id="); pw.println(lastTask.taskId);
11134                    if (dumpAll) {
11135                        lastTask.dump(pw, "  ");
11136                    }
11137                }
11138            }
11139            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11140        }
11141        return true;
11142    }
11143
11144    /**
11145     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11146     * there is a thread associated with the activity.
11147     */
11148    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11149            final ActivityRecord r, String[] args, boolean dumpAll) {
11150        String innerPrefix = prefix + "  ";
11151        synchronized (this) {
11152            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11153                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11154                    pw.print(" pid=");
11155                    if (r.app != null) pw.println(r.app.pid);
11156                    else pw.println("(not running)");
11157            if (dumpAll) {
11158                r.dump(pw, innerPrefix);
11159            }
11160        }
11161        if (r.app != null && r.app.thread != null) {
11162            // flush anything that is already in the PrintWriter since the thread is going
11163            // to write to the file descriptor directly
11164            pw.flush();
11165            try {
11166                TransferPipe tp = new TransferPipe();
11167                try {
11168                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11169                            r.appToken, innerPrefix, args);
11170                    tp.go(fd);
11171                } finally {
11172                    tp.kill();
11173                }
11174            } catch (IOException e) {
11175                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11176            } catch (RemoteException e) {
11177                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11178            }
11179        }
11180    }
11181
11182    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11183            int opti, boolean dumpAll, String dumpPackage) {
11184        boolean needSep = false;
11185        boolean onlyHistory = false;
11186        boolean printedAnything = false;
11187
11188        if ("history".equals(dumpPackage)) {
11189            if (opti < args.length && "-s".equals(args[opti])) {
11190                dumpAll = false;
11191            }
11192            onlyHistory = true;
11193            dumpPackage = null;
11194        }
11195
11196        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11197        if (!onlyHistory && dumpAll) {
11198            if (mRegisteredReceivers.size() > 0) {
11199                boolean printed = false;
11200                Iterator it = mRegisteredReceivers.values().iterator();
11201                while (it.hasNext()) {
11202                    ReceiverList r = (ReceiverList)it.next();
11203                    if (dumpPackage != null && (r.app == null ||
11204                            !dumpPackage.equals(r.app.info.packageName))) {
11205                        continue;
11206                    }
11207                    if (!printed) {
11208                        pw.println("  Registered Receivers:");
11209                        needSep = true;
11210                        printed = true;
11211                        printedAnything = true;
11212                    }
11213                    pw.print("  * "); pw.println(r);
11214                    r.dump(pw, "    ");
11215                }
11216            }
11217
11218            if (mReceiverResolver.dump(pw, needSep ?
11219                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11220                    "    ", dumpPackage, false)) {
11221                needSep = true;
11222                printedAnything = true;
11223            }
11224        }
11225
11226        for (BroadcastQueue q : mBroadcastQueues) {
11227            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11228            printedAnything |= needSep;
11229        }
11230
11231        needSep = true;
11232
11233        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11234            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11235                if (needSep) {
11236                    pw.println();
11237                }
11238                needSep = true;
11239                printedAnything = true;
11240                pw.print("  Sticky broadcasts for user ");
11241                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11242                StringBuilder sb = new StringBuilder(128);
11243                for (Map.Entry<String, ArrayList<Intent>> ent
11244                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11245                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11246                    if (dumpAll) {
11247                        pw.println(":");
11248                        ArrayList<Intent> intents = ent.getValue();
11249                        final int N = intents.size();
11250                        for (int i=0; i<N; i++) {
11251                            sb.setLength(0);
11252                            sb.append("    Intent: ");
11253                            intents.get(i).toShortString(sb, false, true, false, false);
11254                            pw.println(sb.toString());
11255                            Bundle bundle = intents.get(i).getExtras();
11256                            if (bundle != null) {
11257                                pw.print("      ");
11258                                pw.println(bundle.toString());
11259                            }
11260                        }
11261                    } else {
11262                        pw.println("");
11263                    }
11264                }
11265            }
11266        }
11267
11268        if (!onlyHistory && dumpAll) {
11269            pw.println();
11270            for (BroadcastQueue queue : mBroadcastQueues) {
11271                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11272                        + queue.mBroadcastsScheduled);
11273            }
11274            pw.println("  mHandler:");
11275            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11276            needSep = true;
11277            printedAnything = true;
11278        }
11279
11280        if (!printedAnything) {
11281            pw.println("  (nothing)");
11282        }
11283    }
11284
11285    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11286            int opti, boolean dumpAll, String dumpPackage) {
11287        boolean needSep;
11288        boolean printedAnything = false;
11289
11290        ItemMatcher matcher = new ItemMatcher();
11291        matcher.build(args, opti);
11292
11293        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11294
11295        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11296        printedAnything |= needSep;
11297
11298        if (mLaunchingProviders.size() > 0) {
11299            boolean printed = false;
11300            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11301                ContentProviderRecord r = mLaunchingProviders.get(i);
11302                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11303                    continue;
11304                }
11305                if (!printed) {
11306                    if (needSep) pw.println();
11307                    needSep = true;
11308                    pw.println("  Launching content providers:");
11309                    printed = true;
11310                    printedAnything = true;
11311                }
11312                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11313                        pw.println(r);
11314            }
11315        }
11316
11317        if (mGrantedUriPermissions.size() > 0) {
11318            boolean printed = false;
11319            int dumpUid = -2;
11320            if (dumpPackage != null) {
11321                try {
11322                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11323                } catch (NameNotFoundException e) {
11324                    dumpUid = -1;
11325                }
11326            }
11327            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11328                int uid = mGrantedUriPermissions.keyAt(i);
11329                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11330                    continue;
11331                }
11332                ArrayMap<Uri, UriPermission> perms
11333                        = mGrantedUriPermissions.valueAt(i);
11334                if (!printed) {
11335                    if (needSep) pw.println();
11336                    needSep = true;
11337                    pw.println("  Granted Uri Permissions:");
11338                    printed = true;
11339                    printedAnything = true;
11340                }
11341                pw.print("  * UID "); pw.print(uid);
11342                        pw.println(" holds:");
11343                for (UriPermission perm : perms.values()) {
11344                    pw.print("    "); pw.println(perm);
11345                    if (dumpAll) {
11346                        perm.dump(pw, "      ");
11347                    }
11348                }
11349            }
11350        }
11351
11352        if (!printedAnything) {
11353            pw.println("  (nothing)");
11354        }
11355    }
11356
11357    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11358            int opti, boolean dumpAll, String dumpPackage) {
11359        boolean printed = false;
11360
11361        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11362
11363        if (mIntentSenderRecords.size() > 0) {
11364            Iterator<WeakReference<PendingIntentRecord>> it
11365                    = mIntentSenderRecords.values().iterator();
11366            while (it.hasNext()) {
11367                WeakReference<PendingIntentRecord> ref = it.next();
11368                PendingIntentRecord rec = ref != null ? ref.get(): null;
11369                if (dumpPackage != null && (rec == null
11370                        || !dumpPackage.equals(rec.key.packageName))) {
11371                    continue;
11372                }
11373                printed = true;
11374                if (rec != null) {
11375                    pw.print("  * "); pw.println(rec);
11376                    if (dumpAll) {
11377                        rec.dump(pw, "    ");
11378                    }
11379                } else {
11380                    pw.print("  * "); pw.println(ref);
11381                }
11382            }
11383        }
11384
11385        if (!printed) {
11386            pw.println("  (nothing)");
11387        }
11388    }
11389
11390    private static final int dumpProcessList(PrintWriter pw,
11391            ActivityManagerService service, List list,
11392            String prefix, String normalLabel, String persistentLabel,
11393            String dumpPackage) {
11394        int numPers = 0;
11395        final int N = list.size()-1;
11396        for (int i=N; i>=0; i--) {
11397            ProcessRecord r = (ProcessRecord)list.get(i);
11398            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11399                continue;
11400            }
11401            pw.println(String.format("%s%s #%2d: %s",
11402                    prefix, (r.persistent ? persistentLabel : normalLabel),
11403                    i, r.toString()));
11404            if (r.persistent) {
11405                numPers++;
11406            }
11407        }
11408        return numPers;
11409    }
11410
11411    private static final boolean dumpProcessOomList(PrintWriter pw,
11412            ActivityManagerService service, List<ProcessRecord> origList,
11413            String prefix, String normalLabel, String persistentLabel,
11414            boolean inclDetails, String dumpPackage) {
11415
11416        ArrayList<Pair<ProcessRecord, Integer>> list
11417                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11418        for (int i=0; i<origList.size(); i++) {
11419            ProcessRecord r = origList.get(i);
11420            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11421                continue;
11422            }
11423            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11424        }
11425
11426        if (list.size() <= 0) {
11427            return false;
11428        }
11429
11430        Comparator<Pair<ProcessRecord, Integer>> comparator
11431                = new Comparator<Pair<ProcessRecord, Integer>>() {
11432            @Override
11433            public int compare(Pair<ProcessRecord, Integer> object1,
11434                    Pair<ProcessRecord, Integer> object2) {
11435                if (object1.first.setAdj != object2.first.setAdj) {
11436                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11437                }
11438                if (object1.second.intValue() != object2.second.intValue()) {
11439                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11440                }
11441                return 0;
11442            }
11443        };
11444
11445        Collections.sort(list, comparator);
11446
11447        final long curRealtime = SystemClock.elapsedRealtime();
11448        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11449        final long curUptime = SystemClock.uptimeMillis();
11450        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11451
11452        for (int i=list.size()-1; i>=0; i--) {
11453            ProcessRecord r = list.get(i).first;
11454            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11455            char schedGroup;
11456            switch (r.setSchedGroup) {
11457                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11458                    schedGroup = 'B';
11459                    break;
11460                case Process.THREAD_GROUP_DEFAULT:
11461                    schedGroup = 'F';
11462                    break;
11463                default:
11464                    schedGroup = '?';
11465                    break;
11466            }
11467            char foreground;
11468            if (r.foregroundActivities) {
11469                foreground = 'A';
11470            } else if (r.foregroundServices) {
11471                foreground = 'S';
11472            } else {
11473                foreground = ' ';
11474            }
11475            String procState = ProcessList.makeProcStateString(r.curProcState);
11476            pw.print(prefix);
11477            pw.print(r.persistent ? persistentLabel : normalLabel);
11478            pw.print(" #");
11479            int num = (origList.size()-1)-list.get(i).second;
11480            if (num < 10) pw.print(' ');
11481            pw.print(num);
11482            pw.print(": ");
11483            pw.print(oomAdj);
11484            pw.print(' ');
11485            pw.print(schedGroup);
11486            pw.print('/');
11487            pw.print(foreground);
11488            pw.print('/');
11489            pw.print(procState);
11490            pw.print(" trm:");
11491            if (r.trimMemoryLevel < 10) pw.print(' ');
11492            pw.print(r.trimMemoryLevel);
11493            pw.print(' ');
11494            pw.print(r.toShortString());
11495            pw.print(" (");
11496            pw.print(r.adjType);
11497            pw.println(')');
11498            if (r.adjSource != null || r.adjTarget != null) {
11499                pw.print(prefix);
11500                pw.print("    ");
11501                if (r.adjTarget instanceof ComponentName) {
11502                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11503                } else if (r.adjTarget != null) {
11504                    pw.print(r.adjTarget.toString());
11505                } else {
11506                    pw.print("{null}");
11507                }
11508                pw.print("<=");
11509                if (r.adjSource instanceof ProcessRecord) {
11510                    pw.print("Proc{");
11511                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11512                    pw.println("}");
11513                } else if (r.adjSource != null) {
11514                    pw.println(r.adjSource.toString());
11515                } else {
11516                    pw.println("{null}");
11517                }
11518            }
11519            if (inclDetails) {
11520                pw.print(prefix);
11521                pw.print("    ");
11522                pw.print("oom: max="); pw.print(r.maxAdj);
11523                pw.print(" curRaw="); pw.print(r.curRawAdj);
11524                pw.print(" setRaw="); pw.print(r.setRawAdj);
11525                pw.print(" cur="); pw.print(r.curAdj);
11526                pw.print(" set="); pw.println(r.setAdj);
11527                pw.print(prefix);
11528                pw.print("    ");
11529                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11530                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11531                pw.print(" lastPss="); pw.print(r.lastPss);
11532                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11533                pw.print(prefix);
11534                pw.print("    ");
11535                pw.print("keeping="); pw.print(r.keeping);
11536                pw.print(" cached="); pw.print(r.cached);
11537                pw.print(" empty="); pw.print(r.empty);
11538                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11539
11540                if (!r.keeping) {
11541                    if (r.lastWakeTime != 0) {
11542                        long wtime;
11543                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11544                        synchronized (stats) {
11545                            wtime = stats.getProcessWakeTime(r.info.uid,
11546                                    r.pid, curRealtime);
11547                        }
11548                        long timeUsed = wtime - r.lastWakeTime;
11549                        pw.print(prefix);
11550                        pw.print("    ");
11551                        pw.print("keep awake over ");
11552                        TimeUtils.formatDuration(realtimeSince, pw);
11553                        pw.print(" used ");
11554                        TimeUtils.formatDuration(timeUsed, pw);
11555                        pw.print(" (");
11556                        pw.print((timeUsed*100)/realtimeSince);
11557                        pw.println("%)");
11558                    }
11559                    if (r.lastCpuTime != 0) {
11560                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11561                        pw.print(prefix);
11562                        pw.print("    ");
11563                        pw.print("run cpu over ");
11564                        TimeUtils.formatDuration(uptimeSince, pw);
11565                        pw.print(" used ");
11566                        TimeUtils.formatDuration(timeUsed, pw);
11567                        pw.print(" (");
11568                        pw.print((timeUsed*100)/uptimeSince);
11569                        pw.println("%)");
11570                    }
11571                }
11572            }
11573        }
11574        return true;
11575    }
11576
11577    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11578        ArrayList<ProcessRecord> procs;
11579        synchronized (this) {
11580            if (args != null && args.length > start
11581                    && args[start].charAt(0) != '-') {
11582                procs = new ArrayList<ProcessRecord>();
11583                int pid = -1;
11584                try {
11585                    pid = Integer.parseInt(args[start]);
11586                } catch (NumberFormatException e) {
11587                }
11588                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11589                    ProcessRecord proc = mLruProcesses.get(i);
11590                    if (proc.pid == pid) {
11591                        procs.add(proc);
11592                    } else if (proc.processName.equals(args[start])) {
11593                        procs.add(proc);
11594                    }
11595                }
11596                if (procs.size() <= 0) {
11597                    return null;
11598                }
11599            } else {
11600                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11601            }
11602        }
11603        return procs;
11604    }
11605
11606    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11607            PrintWriter pw, String[] args) {
11608        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11609        if (procs == null) {
11610            pw.println("No process found for: " + args[0]);
11611            return;
11612        }
11613
11614        long uptime = SystemClock.uptimeMillis();
11615        long realtime = SystemClock.elapsedRealtime();
11616        pw.println("Applications Graphics Acceleration Info:");
11617        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11618
11619        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11620            ProcessRecord r = procs.get(i);
11621            if (r.thread != null) {
11622                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11623                pw.flush();
11624                try {
11625                    TransferPipe tp = new TransferPipe();
11626                    try {
11627                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11628                        tp.go(fd);
11629                    } finally {
11630                        tp.kill();
11631                    }
11632                } catch (IOException e) {
11633                    pw.println("Failure while dumping the app: " + r);
11634                    pw.flush();
11635                } catch (RemoteException e) {
11636                    pw.println("Got a RemoteException while dumping the app " + r);
11637                    pw.flush();
11638                }
11639            }
11640        }
11641    }
11642
11643    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11644        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11645        if (procs == null) {
11646            pw.println("No process found for: " + args[0]);
11647            return;
11648        }
11649
11650        pw.println("Applications Database Info:");
11651
11652        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11653            ProcessRecord r = procs.get(i);
11654            if (r.thread != null) {
11655                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11656                pw.flush();
11657                try {
11658                    TransferPipe tp = new TransferPipe();
11659                    try {
11660                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11661                        tp.go(fd);
11662                    } finally {
11663                        tp.kill();
11664                    }
11665                } catch (IOException e) {
11666                    pw.println("Failure while dumping the app: " + r);
11667                    pw.flush();
11668                } catch (RemoteException e) {
11669                    pw.println("Got a RemoteException while dumping the app " + r);
11670                    pw.flush();
11671                }
11672            }
11673        }
11674    }
11675
11676    final static class MemItem {
11677        final boolean isProc;
11678        final String label;
11679        final String shortLabel;
11680        final long pss;
11681        final int id;
11682        final boolean hasActivities;
11683        ArrayList<MemItem> subitems;
11684
11685        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11686                boolean _hasActivities) {
11687            isProc = true;
11688            label = _label;
11689            shortLabel = _shortLabel;
11690            pss = _pss;
11691            id = _id;
11692            hasActivities = _hasActivities;
11693        }
11694
11695        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11696            isProc = false;
11697            label = _label;
11698            shortLabel = _shortLabel;
11699            pss = _pss;
11700            id = _id;
11701            hasActivities = false;
11702        }
11703    }
11704
11705    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11706            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11707        if (sort && !isCompact) {
11708            Collections.sort(items, new Comparator<MemItem>() {
11709                @Override
11710                public int compare(MemItem lhs, MemItem rhs) {
11711                    if (lhs.pss < rhs.pss) {
11712                        return 1;
11713                    } else if (lhs.pss > rhs.pss) {
11714                        return -1;
11715                    }
11716                    return 0;
11717                }
11718            });
11719        }
11720
11721        for (int i=0; i<items.size(); i++) {
11722            MemItem mi = items.get(i);
11723            if (!isCompact) {
11724                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11725            } else if (mi.isProc) {
11726                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11727                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11728                pw.println(mi.hasActivities ? ",a" : ",e");
11729            } else {
11730                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11731                pw.println(mi.pss);
11732            }
11733            if (mi.subitems != null) {
11734                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11735                        true, isCompact);
11736            }
11737        }
11738    }
11739
11740    // These are in KB.
11741    static final long[] DUMP_MEM_BUCKETS = new long[] {
11742        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11743        120*1024, 160*1024, 200*1024,
11744        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11745        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11746    };
11747
11748    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11749            boolean stackLike) {
11750        int start = label.lastIndexOf('.');
11751        if (start >= 0) start++;
11752        else start = 0;
11753        int end = label.length();
11754        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11755            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11756                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11757                out.append(bucket);
11758                out.append(stackLike ? "MB." : "MB ");
11759                out.append(label, start, end);
11760                return;
11761            }
11762        }
11763        out.append(memKB/1024);
11764        out.append(stackLike ? "MB." : "MB ");
11765        out.append(label, start, end);
11766    }
11767
11768    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11769            ProcessList.NATIVE_ADJ,
11770            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11771            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11772            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11773            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11774            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11775    };
11776    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11777            "Native",
11778            "System", "Persistent", "Foreground",
11779            "Visible", "Perceptible",
11780            "Heavy Weight", "Backup",
11781            "A Services", "Home",
11782            "Previous", "B Services", "Cached"
11783    };
11784    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11785            "native",
11786            "sys", "pers", "fore",
11787            "vis", "percept",
11788            "heavy", "backup",
11789            "servicea", "home",
11790            "prev", "serviceb", "cached"
11791    };
11792
11793    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11794            long realtime, boolean isCheckinRequest, boolean isCompact) {
11795        if (isCheckinRequest || isCompact) {
11796            // short checkin version
11797            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11798        } else {
11799            pw.println("Applications Memory Usage (kB):");
11800            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11801        }
11802    }
11803
11804    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11805            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11806        boolean dumpDetails = false;
11807        boolean dumpFullDetails = false;
11808        boolean dumpDalvik = false;
11809        boolean oomOnly = false;
11810        boolean isCompact = false;
11811        boolean localOnly = false;
11812
11813        int opti = 0;
11814        while (opti < args.length) {
11815            String opt = args[opti];
11816            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11817                break;
11818            }
11819            opti++;
11820            if ("-a".equals(opt)) {
11821                dumpDetails = true;
11822                dumpFullDetails = true;
11823                dumpDalvik = true;
11824            } else if ("-d".equals(opt)) {
11825                dumpDalvik = true;
11826            } else if ("-c".equals(opt)) {
11827                isCompact = true;
11828            } else if ("--oom".equals(opt)) {
11829                oomOnly = true;
11830            } else if ("--local".equals(opt)) {
11831                localOnly = true;
11832            } else if ("-h".equals(opt)) {
11833                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11834                pw.println("  -a: include all available information for each process.");
11835                pw.println("  -d: include dalvik details when dumping process details.");
11836                pw.println("  -c: dump in a compact machine-parseable representation.");
11837                pw.println("  --oom: only show processes organized by oom adj.");
11838                pw.println("  --local: only collect details locally, don't call process.");
11839                pw.println("If [process] is specified it can be the name or ");
11840                pw.println("pid of a specific process to dump.");
11841                return;
11842            } else {
11843                pw.println("Unknown argument: " + opt + "; use -h for help");
11844            }
11845        }
11846
11847        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11848        long uptime = SystemClock.uptimeMillis();
11849        long realtime = SystemClock.elapsedRealtime();
11850        final long[] tmpLong = new long[1];
11851
11852        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11853        if (procs == null) {
11854            // No Java processes.  Maybe they want to print a native process.
11855            if (args != null && args.length > opti
11856                    && args[opti].charAt(0) != '-') {
11857                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11858                        = new ArrayList<ProcessCpuTracker.Stats>();
11859                updateCpuStatsNow();
11860                int findPid = -1;
11861                try {
11862                    findPid = Integer.parseInt(args[opti]);
11863                } catch (NumberFormatException e) {
11864                }
11865                synchronized (mProcessCpuThread) {
11866                    final int N = mProcessCpuTracker.countStats();
11867                    for (int i=0; i<N; i++) {
11868                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11869                        if (st.pid == findPid || (st.baseName != null
11870                                && st.baseName.equals(args[opti]))) {
11871                            nativeProcs.add(st);
11872                        }
11873                    }
11874                }
11875                if (nativeProcs.size() > 0) {
11876                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11877                            isCompact);
11878                    Debug.MemoryInfo mi = null;
11879                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11880                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11881                        final int pid = r.pid;
11882                        if (!isCheckinRequest && dumpDetails) {
11883                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11884                        }
11885                        if (mi == null) {
11886                            mi = new Debug.MemoryInfo();
11887                        }
11888                        if (dumpDetails || (!brief && !oomOnly)) {
11889                            Debug.getMemoryInfo(pid, mi);
11890                        } else {
11891                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11892                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11893                        }
11894                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11895                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11896                        if (isCheckinRequest) {
11897                            pw.println();
11898                        }
11899                    }
11900                    return;
11901                }
11902            }
11903            pw.println("No process found for: " + args[opti]);
11904            return;
11905        }
11906
11907        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11908            dumpDetails = true;
11909        }
11910
11911        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11912
11913        String[] innerArgs = new String[args.length-opti];
11914        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11915
11916        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11917        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11918        long nativePss=0, dalvikPss=0, otherPss=0;
11919        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11920
11921        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11922        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11923                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11924
11925        long totalPss = 0;
11926        long cachedPss = 0;
11927
11928        Debug.MemoryInfo mi = null;
11929        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11930            final ProcessRecord r = procs.get(i);
11931            final IApplicationThread thread;
11932            final int pid;
11933            final int oomAdj;
11934            final boolean hasActivities;
11935            synchronized (this) {
11936                thread = r.thread;
11937                pid = r.pid;
11938                oomAdj = r.getSetAdjWithServices();
11939                hasActivities = r.activities.size() > 0;
11940            }
11941            if (thread != null) {
11942                if (!isCheckinRequest && dumpDetails) {
11943                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
11944                }
11945                if (mi == null) {
11946                    mi = new Debug.MemoryInfo();
11947                }
11948                if (dumpDetails || (!brief && !oomOnly)) {
11949                    Debug.getMemoryInfo(pid, mi);
11950                } else {
11951                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11952                    mi.dalvikPrivateDirty = (int)tmpLong[0];
11953                }
11954                if (dumpDetails) {
11955                    if (localOnly) {
11956                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11957                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
11958                        if (isCheckinRequest) {
11959                            pw.println();
11960                        }
11961                    } else {
11962                        try {
11963                            pw.flush();
11964                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
11965                                    dumpDalvik, innerArgs);
11966                        } catch (RemoteException e) {
11967                            if (!isCheckinRequest) {
11968                                pw.println("Got RemoteException!");
11969                                pw.flush();
11970                            }
11971                        }
11972                    }
11973                }
11974
11975                final long myTotalPss = mi.getTotalPss();
11976                final long myTotalUss = mi.getTotalUss();
11977
11978                synchronized (this) {
11979                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
11980                        // Record this for posterity if the process has been stable.
11981                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
11982                    }
11983                }
11984
11985                if (!isCheckinRequest && mi != null) {
11986                    totalPss += myTotalPss;
11987                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
11988                            (hasActivities ? " / activities)" : ")"),
11989                            r.processName, myTotalPss, pid, hasActivities);
11990                    procMems.add(pssItem);
11991                    procMemsMap.put(pid, pssItem);
11992
11993                    nativePss += mi.nativePss;
11994                    dalvikPss += mi.dalvikPss;
11995                    otherPss += mi.otherPss;
11996                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
11997                        long mem = mi.getOtherPss(j);
11998                        miscPss[j] += mem;
11999                        otherPss -= mem;
12000                    }
12001
12002                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12003                        cachedPss += myTotalPss;
12004                    }
12005
12006                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12007                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12008                                || oomIndex == (oomPss.length-1)) {
12009                            oomPss[oomIndex] += myTotalPss;
12010                            if (oomProcs[oomIndex] == null) {
12011                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12012                            }
12013                            oomProcs[oomIndex].add(pssItem);
12014                            break;
12015                        }
12016                    }
12017                }
12018            }
12019        }
12020
12021        if (!isCheckinRequest && procs.size() > 1) {
12022            // If we are showing aggregations, also look for native processes to
12023            // include so that our aggregations are more accurate.
12024            updateCpuStatsNow();
12025            synchronized (mProcessCpuThread) {
12026                final int N = mProcessCpuTracker.countStats();
12027                for (int i=0; i<N; i++) {
12028                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12029                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12030                        if (mi == null) {
12031                            mi = new Debug.MemoryInfo();
12032                        }
12033                        if (!brief && !oomOnly) {
12034                            Debug.getMemoryInfo(st.pid, mi);
12035                        } else {
12036                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12037                            mi.nativePrivateDirty = (int)tmpLong[0];
12038                        }
12039
12040                        final long myTotalPss = mi.getTotalPss();
12041                        totalPss += myTotalPss;
12042
12043                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12044                                st.name, myTotalPss, st.pid, false);
12045                        procMems.add(pssItem);
12046
12047                        nativePss += mi.nativePss;
12048                        dalvikPss += mi.dalvikPss;
12049                        otherPss += mi.otherPss;
12050                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12051                            long mem = mi.getOtherPss(j);
12052                            miscPss[j] += mem;
12053                            otherPss -= mem;
12054                        }
12055                        oomPss[0] += myTotalPss;
12056                        if (oomProcs[0] == null) {
12057                            oomProcs[0] = new ArrayList<MemItem>();
12058                        }
12059                        oomProcs[0].add(pssItem);
12060                    }
12061                }
12062            }
12063
12064            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12065
12066            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12067            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12068            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12069            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12070                String label = Debug.MemoryInfo.getOtherLabel(j);
12071                catMems.add(new MemItem(label, label, miscPss[j], j));
12072            }
12073
12074            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12075            for (int j=0; j<oomPss.length; j++) {
12076                if (oomPss[j] != 0) {
12077                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12078                            : DUMP_MEM_OOM_LABEL[j];
12079                    MemItem item = new MemItem(label, label, oomPss[j],
12080                            DUMP_MEM_OOM_ADJ[j]);
12081                    item.subitems = oomProcs[j];
12082                    oomMems.add(item);
12083                }
12084            }
12085
12086            if (!brief && !oomOnly && !isCompact) {
12087                pw.println();
12088                pw.println("Total PSS by process:");
12089                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12090                pw.println();
12091            }
12092            if (!isCompact) {
12093                pw.println("Total PSS by OOM adjustment:");
12094            }
12095            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12096            if (!brief && !oomOnly) {
12097                PrintWriter out = categoryPw != null ? categoryPw : pw;
12098                if (!isCompact) {
12099                    out.println();
12100                    out.println("Total PSS by category:");
12101                }
12102                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12103            }
12104            if (!isCompact) {
12105                pw.println();
12106            }
12107            MemInfoReader memInfo = new MemInfoReader();
12108            memInfo.readMemInfo();
12109            if (!brief) {
12110                if (!isCompact) {
12111                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12112                    pw.println(" kB");
12113                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12114                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12115                            pw.print(cachedPss); pw.print(" cached pss + ");
12116                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12117                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12118                } else {
12119                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12120                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12121                            + memInfo.getFreeSizeKb()); pw.print(",");
12122                    pw.println(totalPss - cachedPss);
12123                }
12124            }
12125            if (!isCompact) {
12126                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12127                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12128                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12129                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12130                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12131                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12132                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12133                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12134                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12135                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12136                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12137            }
12138            if (!brief) {
12139                if (memInfo.getZramTotalSizeKb() != 0) {
12140                    if (!isCompact) {
12141                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12142                                pw.print(" kB physical used for ");
12143                                pw.print(memInfo.getSwapTotalSizeKb()
12144                                        - memInfo.getSwapFreeSizeKb());
12145                                pw.print(" kB in swap (");
12146                                pw.print(memInfo.getSwapTotalSizeKb());
12147                                pw.println(" kB total swap)");
12148                    } else {
12149                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12150                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12151                                pw.println(memInfo.getSwapFreeSizeKb());
12152                    }
12153                }
12154                final int[] SINGLE_LONG_FORMAT = new int[] {
12155                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12156                };
12157                long[] longOut = new long[1];
12158                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12159                        SINGLE_LONG_FORMAT, null, longOut, null);
12160                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12161                longOut[0] = 0;
12162                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12163                        SINGLE_LONG_FORMAT, null, longOut, null);
12164                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12165                longOut[0] = 0;
12166                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12167                        SINGLE_LONG_FORMAT, null, longOut, null);
12168                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12169                longOut[0] = 0;
12170                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12171                        SINGLE_LONG_FORMAT, null, longOut, null);
12172                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12173                if (!isCompact) {
12174                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12175                        pw.print("      KSM: "); pw.print(sharing);
12176                                pw.print(" kB saved from shared ");
12177                                pw.print(shared); pw.println(" kB");
12178                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12179                                pw.print(voltile); pw.println(" kB volatile");
12180                    }
12181                    pw.print("   Tuning: ");
12182                    pw.print(ActivityManager.staticGetMemoryClass());
12183                    pw.print(" (large ");
12184                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12185                    pw.print("), oom ");
12186                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12187                    pw.print(" kB");
12188                    pw.print(", restore limit ");
12189                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12190                    pw.print(" kB");
12191                    if (ActivityManager.isLowRamDeviceStatic()) {
12192                        pw.print(" (low-ram)");
12193                    }
12194                    if (ActivityManager.isHighEndGfx()) {
12195                        pw.print(" (high-end-gfx)");
12196                    }
12197                    pw.println();
12198                } else {
12199                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12200                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12201                    pw.println(voltile);
12202                    pw.print("tuning,");
12203                    pw.print(ActivityManager.staticGetMemoryClass());
12204                    pw.print(',');
12205                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12206                    pw.print(',');
12207                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12208                    if (ActivityManager.isLowRamDeviceStatic()) {
12209                        pw.print(",low-ram");
12210                    }
12211                    if (ActivityManager.isHighEndGfx()) {
12212                        pw.print(",high-end-gfx");
12213                    }
12214                    pw.println();
12215                }
12216            }
12217        }
12218    }
12219
12220    /**
12221     * Searches array of arguments for the specified string
12222     * @param args array of argument strings
12223     * @param value value to search for
12224     * @return true if the value is contained in the array
12225     */
12226    private static boolean scanArgs(String[] args, String value) {
12227        if (args != null) {
12228            for (String arg : args) {
12229                if (value.equals(arg)) {
12230                    return true;
12231                }
12232            }
12233        }
12234        return false;
12235    }
12236
12237    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12238            ContentProviderRecord cpr, boolean always) {
12239        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12240
12241        if (!inLaunching || always) {
12242            synchronized (cpr) {
12243                cpr.launchingApp = null;
12244                cpr.notifyAll();
12245            }
12246            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12247            String names[] = cpr.info.authority.split(";");
12248            for (int j = 0; j < names.length; j++) {
12249                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12250            }
12251        }
12252
12253        for (int i=0; i<cpr.connections.size(); i++) {
12254            ContentProviderConnection conn = cpr.connections.get(i);
12255            if (conn.waiting) {
12256                // If this connection is waiting for the provider, then we don't
12257                // need to mess with its process unless we are always removing
12258                // or for some reason the provider is not currently launching.
12259                if (inLaunching && !always) {
12260                    continue;
12261                }
12262            }
12263            ProcessRecord capp = conn.client;
12264            conn.dead = true;
12265            if (conn.stableCount > 0) {
12266                if (!capp.persistent && capp.thread != null
12267                        && capp.pid != 0
12268                        && capp.pid != MY_PID) {
12269                    killUnneededProcessLocked(capp, "depends on provider "
12270                            + cpr.name.flattenToShortString()
12271                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12272                }
12273            } else if (capp.thread != null && conn.provider.provider != null) {
12274                try {
12275                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12276                } catch (RemoteException e) {
12277                }
12278                // In the protocol here, we don't expect the client to correctly
12279                // clean up this connection, we'll just remove it.
12280                cpr.connections.remove(i);
12281                conn.client.conProviders.remove(conn);
12282            }
12283        }
12284
12285        if (inLaunching && always) {
12286            mLaunchingProviders.remove(cpr);
12287        }
12288        return inLaunching;
12289    }
12290
12291    /**
12292     * Main code for cleaning up a process when it has gone away.  This is
12293     * called both as a result of the process dying, or directly when stopping
12294     * a process when running in single process mode.
12295     */
12296    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12297            boolean restarting, boolean allowRestart, int index) {
12298        if (index >= 0) {
12299            removeLruProcessLocked(app);
12300            ProcessList.remove(app.pid);
12301        }
12302
12303        mProcessesToGc.remove(app);
12304        mPendingPssProcesses.remove(app);
12305
12306        // Dismiss any open dialogs.
12307        if (app.crashDialog != null && !app.forceCrashReport) {
12308            app.crashDialog.dismiss();
12309            app.crashDialog = null;
12310        }
12311        if (app.anrDialog != null) {
12312            app.anrDialog.dismiss();
12313            app.anrDialog = null;
12314        }
12315        if (app.waitDialog != null) {
12316            app.waitDialog.dismiss();
12317            app.waitDialog = null;
12318        }
12319
12320        app.crashing = false;
12321        app.notResponding = false;
12322
12323        app.resetPackageList(mProcessStats);
12324        app.unlinkDeathRecipient();
12325        app.makeInactive(mProcessStats);
12326        app.forcingToForeground = null;
12327        app.foregroundServices = false;
12328        app.foregroundActivities = false;
12329        app.hasShownUi = false;
12330        app.hasAboveClient = false;
12331
12332        mServices.killServicesLocked(app, allowRestart);
12333
12334        boolean restart = false;
12335
12336        // Remove published content providers.
12337        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12338            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12339            final boolean always = app.bad || !allowRestart;
12340            if (removeDyingProviderLocked(app, cpr, always) || always) {
12341                // We left the provider in the launching list, need to
12342                // restart it.
12343                restart = true;
12344            }
12345
12346            cpr.provider = null;
12347            cpr.proc = null;
12348        }
12349        app.pubProviders.clear();
12350
12351        // Take care of any launching providers waiting for this process.
12352        if (checkAppInLaunchingProvidersLocked(app, false)) {
12353            restart = true;
12354        }
12355
12356        // Unregister from connected content providers.
12357        if (!app.conProviders.isEmpty()) {
12358            for (int i=0; i<app.conProviders.size(); i++) {
12359                ContentProviderConnection conn = app.conProviders.get(i);
12360                conn.provider.connections.remove(conn);
12361            }
12362            app.conProviders.clear();
12363        }
12364
12365        // At this point there may be remaining entries in mLaunchingProviders
12366        // where we were the only one waiting, so they are no longer of use.
12367        // Look for these and clean up if found.
12368        // XXX Commented out for now.  Trying to figure out a way to reproduce
12369        // the actual situation to identify what is actually going on.
12370        if (false) {
12371            for (int i=0; i<mLaunchingProviders.size(); i++) {
12372                ContentProviderRecord cpr = (ContentProviderRecord)
12373                        mLaunchingProviders.get(i);
12374                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12375                    synchronized (cpr) {
12376                        cpr.launchingApp = null;
12377                        cpr.notifyAll();
12378                    }
12379                }
12380            }
12381        }
12382
12383        skipCurrentReceiverLocked(app);
12384
12385        // Unregister any receivers.
12386        for (int i=app.receivers.size()-1; i>=0; i--) {
12387            removeReceiverLocked(app.receivers.valueAt(i));
12388        }
12389        app.receivers.clear();
12390
12391        // If the app is undergoing backup, tell the backup manager about it
12392        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12393            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12394                    + mBackupTarget.appInfo + " died during backup");
12395            try {
12396                IBackupManager bm = IBackupManager.Stub.asInterface(
12397                        ServiceManager.getService(Context.BACKUP_SERVICE));
12398                bm.agentDisconnected(app.info.packageName);
12399            } catch (RemoteException e) {
12400                // can't happen; backup manager is local
12401            }
12402        }
12403
12404        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12405            ProcessChangeItem item = mPendingProcessChanges.get(i);
12406            if (item.pid == app.pid) {
12407                mPendingProcessChanges.remove(i);
12408                mAvailProcessChanges.add(item);
12409            }
12410        }
12411        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12412
12413        // If the caller is restarting this app, then leave it in its
12414        // current lists and let the caller take care of it.
12415        if (restarting) {
12416            return;
12417        }
12418
12419        if (!app.persistent || app.isolated) {
12420            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12421                    "Removing non-persistent process during cleanup: " + app);
12422            mProcessNames.remove(app.processName, app.uid);
12423            mIsolatedProcesses.remove(app.uid);
12424            if (mHeavyWeightProcess == app) {
12425                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12426                        mHeavyWeightProcess.userId, 0));
12427                mHeavyWeightProcess = null;
12428            }
12429        } else if (!app.removed) {
12430            // This app is persistent, so we need to keep its record around.
12431            // If it is not already on the pending app list, add it there
12432            // and start a new process for it.
12433            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12434                mPersistentStartingProcesses.add(app);
12435                restart = true;
12436            }
12437        }
12438        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12439                "Clean-up removing on hold: " + app);
12440        mProcessesOnHold.remove(app);
12441
12442        if (app == mHomeProcess) {
12443            mHomeProcess = null;
12444        }
12445        if (app == mPreviousProcess) {
12446            mPreviousProcess = null;
12447        }
12448
12449        if (restart && !app.isolated) {
12450            // We have components that still need to be running in the
12451            // process, so re-launch it.
12452            mProcessNames.put(app.processName, app.uid, app);
12453            startProcessLocked(app, "restart", app.processName);
12454        } else if (app.pid > 0 && app.pid != MY_PID) {
12455            // Goodbye!
12456            synchronized (mPidsSelfLocked) {
12457                mPidsSelfLocked.remove(app.pid);
12458                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12459            }
12460            app.setPid(0);
12461        }
12462    }
12463
12464    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12465        // Look through the content providers we are waiting to have launched,
12466        // and if any run in this process then either schedule a restart of
12467        // the process or kill the client waiting for it if this process has
12468        // gone bad.
12469        int NL = mLaunchingProviders.size();
12470        boolean restart = false;
12471        for (int i=0; i<NL; i++) {
12472            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12473            if (cpr.launchingApp == app) {
12474                if (!alwaysBad && !app.bad) {
12475                    restart = true;
12476                } else {
12477                    removeDyingProviderLocked(app, cpr, true);
12478                    // cpr should have been removed from mLaunchingProviders
12479                    NL = mLaunchingProviders.size();
12480                    i--;
12481                }
12482            }
12483        }
12484        return restart;
12485    }
12486
12487    // =========================================================
12488    // SERVICES
12489    // =========================================================
12490
12491    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12492            int flags) {
12493        enforceNotIsolatedCaller("getServices");
12494        synchronized (this) {
12495            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12496        }
12497    }
12498
12499    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12500        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12501        synchronized (this) {
12502            return mServices.getRunningServiceControlPanelLocked(name);
12503        }
12504    }
12505
12506    public ComponentName startService(IApplicationThread caller, Intent service,
12507            String resolvedType, int userId) {
12508        enforceNotIsolatedCaller("startService");
12509        // Refuse possible leaked file descriptors
12510        if (service != null && service.hasFileDescriptors() == true) {
12511            throw new IllegalArgumentException("File descriptors passed in Intent");
12512        }
12513
12514        if (DEBUG_SERVICE)
12515            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12516        synchronized(this) {
12517            final int callingPid = Binder.getCallingPid();
12518            final int callingUid = Binder.getCallingUid();
12519            final long origId = Binder.clearCallingIdentity();
12520            ComponentName res = mServices.startServiceLocked(caller, service,
12521                    resolvedType, callingPid, callingUid, userId);
12522            Binder.restoreCallingIdentity(origId);
12523            return res;
12524        }
12525    }
12526
12527    ComponentName startServiceInPackage(int uid,
12528            Intent service, String resolvedType, int userId) {
12529        synchronized(this) {
12530            if (DEBUG_SERVICE)
12531                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12532            final long origId = Binder.clearCallingIdentity();
12533            ComponentName res = mServices.startServiceLocked(null, service,
12534                    resolvedType, -1, uid, userId);
12535            Binder.restoreCallingIdentity(origId);
12536            return res;
12537        }
12538    }
12539
12540    public int stopService(IApplicationThread caller, Intent service,
12541            String resolvedType, int userId) {
12542        enforceNotIsolatedCaller("stopService");
12543        // Refuse possible leaked file descriptors
12544        if (service != null && service.hasFileDescriptors() == true) {
12545            throw new IllegalArgumentException("File descriptors passed in Intent");
12546        }
12547
12548        synchronized(this) {
12549            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12550        }
12551    }
12552
12553    public IBinder peekService(Intent service, String resolvedType) {
12554        enforceNotIsolatedCaller("peekService");
12555        // Refuse possible leaked file descriptors
12556        if (service != null && service.hasFileDescriptors() == true) {
12557            throw new IllegalArgumentException("File descriptors passed in Intent");
12558        }
12559        synchronized(this) {
12560            return mServices.peekServiceLocked(service, resolvedType);
12561        }
12562    }
12563
12564    public boolean stopServiceToken(ComponentName className, IBinder token,
12565            int startId) {
12566        synchronized(this) {
12567            return mServices.stopServiceTokenLocked(className, token, startId);
12568        }
12569    }
12570
12571    public void setServiceForeground(ComponentName className, IBinder token,
12572            int id, Notification notification, boolean removeNotification) {
12573        synchronized(this) {
12574            mServices.setServiceForegroundLocked(className, token, id, notification,
12575                    removeNotification);
12576        }
12577    }
12578
12579    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12580            boolean requireFull, String name, String callerPackage) {
12581        final int callingUserId = UserHandle.getUserId(callingUid);
12582        if (callingUserId != userId) {
12583            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12584                if ((requireFull || checkComponentPermission(
12585                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12586                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12587                        && checkComponentPermission(
12588                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12589                                callingPid, callingUid, -1, true)
12590                                != PackageManager.PERMISSION_GRANTED) {
12591                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12592                        // In this case, they would like to just execute as their
12593                        // owner user instead of failing.
12594                        userId = callingUserId;
12595                    } else {
12596                        StringBuilder builder = new StringBuilder(128);
12597                        builder.append("Permission Denial: ");
12598                        builder.append(name);
12599                        if (callerPackage != null) {
12600                            builder.append(" from ");
12601                            builder.append(callerPackage);
12602                        }
12603                        builder.append(" asks to run as user ");
12604                        builder.append(userId);
12605                        builder.append(" but is calling from user ");
12606                        builder.append(UserHandle.getUserId(callingUid));
12607                        builder.append("; this requires ");
12608                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12609                        if (!requireFull) {
12610                            builder.append(" or ");
12611                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12612                        }
12613                        String msg = builder.toString();
12614                        Slog.w(TAG, msg);
12615                        throw new SecurityException(msg);
12616                    }
12617                }
12618            }
12619            if (userId == UserHandle.USER_CURRENT
12620                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12621                // Note that we may be accessing this outside of a lock...
12622                // shouldn't be a big deal, if this is being called outside
12623                // of a locked context there is intrinsically a race with
12624                // the value the caller will receive and someone else changing it.
12625                userId = mCurrentUserId;
12626            }
12627            if (!allowAll && userId < 0) {
12628                throw new IllegalArgumentException(
12629                        "Call does not support special user #" + userId);
12630            }
12631        }
12632        return userId;
12633    }
12634
12635    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12636            String className, int flags) {
12637        boolean result = false;
12638        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12639            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12640                if (ActivityManager.checkUidPermission(
12641                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12642                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12643                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12644                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12645                            + " requests FLAG_SINGLE_USER, but app does not hold "
12646                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12647                    Slog.w(TAG, msg);
12648                    throw new SecurityException(msg);
12649                }
12650                result = true;
12651            }
12652        } else if (componentProcessName == aInfo.packageName) {
12653            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12654        } else if ("system".equals(componentProcessName)) {
12655            result = true;
12656        }
12657        if (DEBUG_MU) {
12658            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12659                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12660        }
12661        return result;
12662    }
12663
12664    public int bindService(IApplicationThread caller, IBinder token,
12665            Intent service, String resolvedType,
12666            IServiceConnection connection, int flags, int userId) {
12667        enforceNotIsolatedCaller("bindService");
12668        // Refuse possible leaked file descriptors
12669        if (service != null && service.hasFileDescriptors() == true) {
12670            throw new IllegalArgumentException("File descriptors passed in Intent");
12671        }
12672
12673        synchronized(this) {
12674            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12675                    connection, flags, userId);
12676        }
12677    }
12678
12679    public boolean unbindService(IServiceConnection connection) {
12680        synchronized (this) {
12681            return mServices.unbindServiceLocked(connection);
12682        }
12683    }
12684
12685    public void publishService(IBinder token, Intent intent, IBinder service) {
12686        // Refuse possible leaked file descriptors
12687        if (intent != null && intent.hasFileDescriptors() == true) {
12688            throw new IllegalArgumentException("File descriptors passed in Intent");
12689        }
12690
12691        synchronized(this) {
12692            if (!(token instanceof ServiceRecord)) {
12693                throw new IllegalArgumentException("Invalid service token");
12694            }
12695            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12696        }
12697    }
12698
12699    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12700        // Refuse possible leaked file descriptors
12701        if (intent != null && intent.hasFileDescriptors() == true) {
12702            throw new IllegalArgumentException("File descriptors passed in Intent");
12703        }
12704
12705        synchronized(this) {
12706            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12707        }
12708    }
12709
12710    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12711        synchronized(this) {
12712            if (!(token instanceof ServiceRecord)) {
12713                throw new IllegalArgumentException("Invalid service token");
12714            }
12715            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12716        }
12717    }
12718
12719    // =========================================================
12720    // BACKUP AND RESTORE
12721    // =========================================================
12722
12723    // Cause the target app to be launched if necessary and its backup agent
12724    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12725    // activity manager to announce its creation.
12726    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12727        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12728        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12729
12730        synchronized(this) {
12731            // !!! TODO: currently no check here that we're already bound
12732            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12733            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12734            synchronized (stats) {
12735                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12736            }
12737
12738            // Backup agent is now in use, its package can't be stopped.
12739            try {
12740                AppGlobals.getPackageManager().setPackageStoppedState(
12741                        app.packageName, false, UserHandle.getUserId(app.uid));
12742            } catch (RemoteException e) {
12743            } catch (IllegalArgumentException e) {
12744                Slog.w(TAG, "Failed trying to unstop package "
12745                        + app.packageName + ": " + e);
12746            }
12747
12748            BackupRecord r = new BackupRecord(ss, app, backupMode);
12749            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12750                    ? new ComponentName(app.packageName, app.backupAgentName)
12751                    : new ComponentName("android", "FullBackupAgent");
12752            // startProcessLocked() returns existing proc's record if it's already running
12753            ProcessRecord proc = startProcessLocked(app.processName, app,
12754                    false, 0, "backup", hostingName, false, false, false);
12755            if (proc == null) {
12756                Slog.e(TAG, "Unable to start backup agent process " + r);
12757                return false;
12758            }
12759
12760            r.app = proc;
12761            mBackupTarget = r;
12762            mBackupAppName = app.packageName;
12763
12764            // Try not to kill the process during backup
12765            updateOomAdjLocked(proc);
12766
12767            // If the process is already attached, schedule the creation of the backup agent now.
12768            // If it is not yet live, this will be done when it attaches to the framework.
12769            if (proc.thread != null) {
12770                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12771                try {
12772                    proc.thread.scheduleCreateBackupAgent(app,
12773                            compatibilityInfoForPackageLocked(app), backupMode);
12774                } catch (RemoteException e) {
12775                    // Will time out on the backup manager side
12776                }
12777            } else {
12778                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12779            }
12780            // Invariants: at this point, the target app process exists and the application
12781            // is either already running or in the process of coming up.  mBackupTarget and
12782            // mBackupAppName describe the app, so that when it binds back to the AM we
12783            // know that it's scheduled for a backup-agent operation.
12784        }
12785
12786        return true;
12787    }
12788
12789    @Override
12790    public void clearPendingBackup() {
12791        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12792        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12793
12794        synchronized (this) {
12795            mBackupTarget = null;
12796            mBackupAppName = null;
12797        }
12798    }
12799
12800    // A backup agent has just come up
12801    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12802        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12803                + " = " + agent);
12804
12805        synchronized(this) {
12806            if (!agentPackageName.equals(mBackupAppName)) {
12807                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12808                return;
12809            }
12810        }
12811
12812        long oldIdent = Binder.clearCallingIdentity();
12813        try {
12814            IBackupManager bm = IBackupManager.Stub.asInterface(
12815                    ServiceManager.getService(Context.BACKUP_SERVICE));
12816            bm.agentConnected(agentPackageName, agent);
12817        } catch (RemoteException e) {
12818            // can't happen; the backup manager service is local
12819        } catch (Exception e) {
12820            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12821            e.printStackTrace();
12822        } finally {
12823            Binder.restoreCallingIdentity(oldIdent);
12824        }
12825    }
12826
12827    // done with this agent
12828    public void unbindBackupAgent(ApplicationInfo appInfo) {
12829        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12830        if (appInfo == null) {
12831            Slog.w(TAG, "unbind backup agent for null app");
12832            return;
12833        }
12834
12835        synchronized(this) {
12836            try {
12837                if (mBackupAppName == null) {
12838                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12839                    return;
12840                }
12841
12842                if (!mBackupAppName.equals(appInfo.packageName)) {
12843                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12844                    return;
12845                }
12846
12847                // Not backing this app up any more; reset its OOM adjustment
12848                final ProcessRecord proc = mBackupTarget.app;
12849                updateOomAdjLocked(proc);
12850
12851                // If the app crashed during backup, 'thread' will be null here
12852                if (proc.thread != null) {
12853                    try {
12854                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12855                                compatibilityInfoForPackageLocked(appInfo));
12856                    } catch (Exception e) {
12857                        Slog.e(TAG, "Exception when unbinding backup agent:");
12858                        e.printStackTrace();
12859                    }
12860                }
12861            } finally {
12862                mBackupTarget = null;
12863                mBackupAppName = null;
12864            }
12865        }
12866    }
12867    // =========================================================
12868    // BROADCASTS
12869    // =========================================================
12870
12871    private final List getStickiesLocked(String action, IntentFilter filter,
12872            List cur, int userId) {
12873        final ContentResolver resolver = mContext.getContentResolver();
12874        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12875        if (stickies == null) {
12876            return cur;
12877        }
12878        final ArrayList<Intent> list = stickies.get(action);
12879        if (list == null) {
12880            return cur;
12881        }
12882        int N = list.size();
12883        for (int i=0; i<N; i++) {
12884            Intent intent = list.get(i);
12885            if (filter.match(resolver, intent, true, TAG) >= 0) {
12886                if (cur == null) {
12887                    cur = new ArrayList<Intent>();
12888                }
12889                cur.add(intent);
12890            }
12891        }
12892        return cur;
12893    }
12894
12895    boolean isPendingBroadcastProcessLocked(int pid) {
12896        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12897                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12898    }
12899
12900    void skipPendingBroadcastLocked(int pid) {
12901            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12902            for (BroadcastQueue queue : mBroadcastQueues) {
12903                queue.skipPendingBroadcastLocked(pid);
12904            }
12905    }
12906
12907    // The app just attached; send any pending broadcasts that it should receive
12908    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12909        boolean didSomething = false;
12910        for (BroadcastQueue queue : mBroadcastQueues) {
12911            didSomething |= queue.sendPendingBroadcastsLocked(app);
12912        }
12913        return didSomething;
12914    }
12915
12916    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12917            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
12918        enforceNotIsolatedCaller("registerReceiver");
12919        int callingUid;
12920        int callingPid;
12921        synchronized(this) {
12922            ProcessRecord callerApp = null;
12923            if (caller != null) {
12924                callerApp = getRecordForAppLocked(caller);
12925                if (callerApp == null) {
12926                    throw new SecurityException(
12927                            "Unable to find app for caller " + caller
12928                            + " (pid=" + Binder.getCallingPid()
12929                            + ") when registering receiver " + receiver);
12930                }
12931                if (callerApp.info.uid != Process.SYSTEM_UID &&
12932                        !callerApp.pkgList.containsKey(callerPackage) &&
12933                        !"android".equals(callerPackage)) {
12934                    throw new SecurityException("Given caller package " + callerPackage
12935                            + " is not running in process " + callerApp);
12936                }
12937                callingUid = callerApp.info.uid;
12938                callingPid = callerApp.pid;
12939            } else {
12940                callerPackage = null;
12941                callingUid = Binder.getCallingUid();
12942                callingPid = Binder.getCallingPid();
12943            }
12944
12945            userId = this.handleIncomingUser(callingPid, callingUid, userId,
12946                    true, true, "registerReceiver", callerPackage);
12947
12948            List allSticky = null;
12949
12950            // Look for any matching sticky broadcasts...
12951            Iterator actions = filter.actionsIterator();
12952            if (actions != null) {
12953                while (actions.hasNext()) {
12954                    String action = (String)actions.next();
12955                    allSticky = getStickiesLocked(action, filter, allSticky,
12956                            UserHandle.USER_ALL);
12957                    allSticky = getStickiesLocked(action, filter, allSticky,
12958                            UserHandle.getUserId(callingUid));
12959                }
12960            } else {
12961                allSticky = getStickiesLocked(null, filter, allSticky,
12962                        UserHandle.USER_ALL);
12963                allSticky = getStickiesLocked(null, filter, allSticky,
12964                        UserHandle.getUserId(callingUid));
12965            }
12966
12967            // The first sticky in the list is returned directly back to
12968            // the client.
12969            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12970
12971            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12972                    + ": " + sticky);
12973
12974            if (receiver == null) {
12975                return sticky;
12976            }
12977
12978            ReceiverList rl
12979                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12980            if (rl == null) {
12981                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
12982                        userId, receiver);
12983                if (rl.app != null) {
12984                    rl.app.receivers.add(rl);
12985                } else {
12986                    try {
12987                        receiver.asBinder().linkToDeath(rl, 0);
12988                    } catch (RemoteException e) {
12989                        return sticky;
12990                    }
12991                    rl.linkedToDeath = true;
12992                }
12993                mRegisteredReceivers.put(receiver.asBinder(), rl);
12994            } else if (rl.uid != callingUid) {
12995                throw new IllegalArgumentException(
12996                        "Receiver requested to register for uid " + callingUid
12997                        + " was previously registered for uid " + rl.uid);
12998            } else if (rl.pid != callingPid) {
12999                throw new IllegalArgumentException(
13000                        "Receiver requested to register for pid " + callingPid
13001                        + " was previously registered for pid " + rl.pid);
13002            } else if (rl.userId != userId) {
13003                throw new IllegalArgumentException(
13004                        "Receiver requested to register for user " + userId
13005                        + " was previously registered for user " + rl.userId);
13006            }
13007            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13008                    permission, callingUid, userId);
13009            rl.add(bf);
13010            if (!bf.debugCheck()) {
13011                Slog.w(TAG, "==> For Dynamic broadast");
13012            }
13013            mReceiverResolver.addFilter(bf);
13014
13015            // Enqueue broadcasts for all existing stickies that match
13016            // this filter.
13017            if (allSticky != null) {
13018                ArrayList receivers = new ArrayList();
13019                receivers.add(bf);
13020
13021                int N = allSticky.size();
13022                for (int i=0; i<N; i++) {
13023                    Intent intent = (Intent)allSticky.get(i);
13024                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13025                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13026                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13027                            null, null, false, true, true, -1);
13028                    queue.enqueueParallelBroadcastLocked(r);
13029                    queue.scheduleBroadcastsLocked();
13030                }
13031            }
13032
13033            return sticky;
13034        }
13035    }
13036
13037    public void unregisterReceiver(IIntentReceiver receiver) {
13038        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13039
13040        final long origId = Binder.clearCallingIdentity();
13041        try {
13042            boolean doTrim = false;
13043
13044            synchronized(this) {
13045                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13046                if (rl != null) {
13047                    if (rl.curBroadcast != null) {
13048                        BroadcastRecord r = rl.curBroadcast;
13049                        final boolean doNext = finishReceiverLocked(
13050                                receiver.asBinder(), r.resultCode, r.resultData,
13051                                r.resultExtras, r.resultAbort);
13052                        if (doNext) {
13053                            doTrim = true;
13054                            r.queue.processNextBroadcast(false);
13055                        }
13056                    }
13057
13058                    if (rl.app != null) {
13059                        rl.app.receivers.remove(rl);
13060                    }
13061                    removeReceiverLocked(rl);
13062                    if (rl.linkedToDeath) {
13063                        rl.linkedToDeath = false;
13064                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13065                    }
13066                }
13067            }
13068
13069            // If we actually concluded any broadcasts, we might now be able
13070            // to trim the recipients' apps from our working set
13071            if (doTrim) {
13072                trimApplications();
13073                return;
13074            }
13075
13076        } finally {
13077            Binder.restoreCallingIdentity(origId);
13078        }
13079    }
13080
13081    void removeReceiverLocked(ReceiverList rl) {
13082        mRegisteredReceivers.remove(rl.receiver.asBinder());
13083        int N = rl.size();
13084        for (int i=0; i<N; i++) {
13085            mReceiverResolver.removeFilter(rl.get(i));
13086        }
13087    }
13088
13089    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13090        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13091            ProcessRecord r = mLruProcesses.get(i);
13092            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13093                try {
13094                    r.thread.dispatchPackageBroadcast(cmd, packages);
13095                } catch (RemoteException ex) {
13096                }
13097            }
13098        }
13099    }
13100
13101    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13102            int[] users) {
13103        List<ResolveInfo> receivers = null;
13104        try {
13105            HashSet<ComponentName> singleUserReceivers = null;
13106            boolean scannedFirstReceivers = false;
13107            for (int user : users) {
13108                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13109                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13110                if (user != 0 && newReceivers != null) {
13111                    // If this is not the primary user, we need to check for
13112                    // any receivers that should be filtered out.
13113                    for (int i=0; i<newReceivers.size(); i++) {
13114                        ResolveInfo ri = newReceivers.get(i);
13115                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13116                            newReceivers.remove(i);
13117                            i--;
13118                        }
13119                    }
13120                }
13121                if (newReceivers != null && newReceivers.size() == 0) {
13122                    newReceivers = null;
13123                }
13124                if (receivers == null) {
13125                    receivers = newReceivers;
13126                } else if (newReceivers != null) {
13127                    // We need to concatenate the additional receivers
13128                    // found with what we have do far.  This would be easy,
13129                    // but we also need to de-dup any receivers that are
13130                    // singleUser.
13131                    if (!scannedFirstReceivers) {
13132                        // Collect any single user receivers we had already retrieved.
13133                        scannedFirstReceivers = true;
13134                        for (int i=0; i<receivers.size(); i++) {
13135                            ResolveInfo ri = receivers.get(i);
13136                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13137                                ComponentName cn = new ComponentName(
13138                                        ri.activityInfo.packageName, ri.activityInfo.name);
13139                                if (singleUserReceivers == null) {
13140                                    singleUserReceivers = new HashSet<ComponentName>();
13141                                }
13142                                singleUserReceivers.add(cn);
13143                            }
13144                        }
13145                    }
13146                    // Add the new results to the existing results, tracking
13147                    // and de-dupping single user receivers.
13148                    for (int i=0; i<newReceivers.size(); i++) {
13149                        ResolveInfo ri = newReceivers.get(i);
13150                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13151                            ComponentName cn = new ComponentName(
13152                                    ri.activityInfo.packageName, ri.activityInfo.name);
13153                            if (singleUserReceivers == null) {
13154                                singleUserReceivers = new HashSet<ComponentName>();
13155                            }
13156                            if (!singleUserReceivers.contains(cn)) {
13157                                singleUserReceivers.add(cn);
13158                                receivers.add(ri);
13159                            }
13160                        } else {
13161                            receivers.add(ri);
13162                        }
13163                    }
13164                }
13165            }
13166        } catch (RemoteException ex) {
13167            // pm is in same process, this will never happen.
13168        }
13169        return receivers;
13170    }
13171
13172    private final int broadcastIntentLocked(ProcessRecord callerApp,
13173            String callerPackage, Intent intent, String resolvedType,
13174            IIntentReceiver resultTo, int resultCode, String resultData,
13175            Bundle map, String requiredPermission, int appOp,
13176            boolean ordered, boolean sticky, int callingPid, int callingUid,
13177            int userId) {
13178        intent = new Intent(intent);
13179
13180        // By default broadcasts do not go to stopped apps.
13181        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13182
13183        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13184            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13185            + " ordered=" + ordered + " userid=" + userId);
13186        if ((resultTo != null) && !ordered) {
13187            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13188        }
13189
13190        userId = handleIncomingUser(callingPid, callingUid, userId,
13191                true, false, "broadcast", callerPackage);
13192
13193        // Make sure that the user who is receiving this broadcast is started.
13194        // If not, we will just skip it.
13195        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13196            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13197                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13198                Slog.w(TAG, "Skipping broadcast of " + intent
13199                        + ": user " + userId + " is stopped");
13200                return ActivityManager.BROADCAST_SUCCESS;
13201            }
13202        }
13203
13204        /*
13205         * Prevent non-system code (defined here to be non-persistent
13206         * processes) from sending protected broadcasts.
13207         */
13208        int callingAppId = UserHandle.getAppId(callingUid);
13209        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13210            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13211            callingUid == 0) {
13212            // Always okay.
13213        } else if (callerApp == null || !callerApp.persistent) {
13214            try {
13215                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13216                        intent.getAction())) {
13217                    String msg = "Permission Denial: not allowed to send broadcast "
13218                            + intent.getAction() + " from pid="
13219                            + callingPid + ", uid=" + callingUid;
13220                    Slog.w(TAG, msg);
13221                    throw new SecurityException(msg);
13222                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13223                    // Special case for compatibility: we don't want apps to send this,
13224                    // but historically it has not been protected and apps may be using it
13225                    // to poke their own app widget.  So, instead of making it protected,
13226                    // just limit it to the caller.
13227                    if (callerApp == null) {
13228                        String msg = "Permission Denial: not allowed to send broadcast "
13229                                + intent.getAction() + " from unknown caller.";
13230                        Slog.w(TAG, msg);
13231                        throw new SecurityException(msg);
13232                    } else if (intent.getComponent() != null) {
13233                        // They are good enough to send to an explicit component...  verify
13234                        // it is being sent to the calling app.
13235                        if (!intent.getComponent().getPackageName().equals(
13236                                callerApp.info.packageName)) {
13237                            String msg = "Permission Denial: not allowed to send broadcast "
13238                                    + intent.getAction() + " to "
13239                                    + intent.getComponent().getPackageName() + " from "
13240                                    + callerApp.info.packageName;
13241                            Slog.w(TAG, msg);
13242                            throw new SecurityException(msg);
13243                        }
13244                    } else {
13245                        // Limit broadcast to their own package.
13246                        intent.setPackage(callerApp.info.packageName);
13247                    }
13248                }
13249            } catch (RemoteException e) {
13250                Slog.w(TAG, "Remote exception", e);
13251                return ActivityManager.BROADCAST_SUCCESS;
13252            }
13253        }
13254
13255        // Handle special intents: if this broadcast is from the package
13256        // manager about a package being removed, we need to remove all of
13257        // its activities from the history stack.
13258        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13259                intent.getAction());
13260        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13261                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13262                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13263                || uidRemoved) {
13264            if (checkComponentPermission(
13265                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13266                    callingPid, callingUid, -1, true)
13267                    == PackageManager.PERMISSION_GRANTED) {
13268                if (uidRemoved) {
13269                    final Bundle intentExtras = intent.getExtras();
13270                    final int uid = intentExtras != null
13271                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13272                    if (uid >= 0) {
13273                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13274                        synchronized (bs) {
13275                            bs.removeUidStatsLocked(uid);
13276                        }
13277                        mAppOpsService.uidRemoved(uid);
13278                    }
13279                } else {
13280                    // If resources are unavailable just force stop all
13281                    // those packages and flush the attribute cache as well.
13282                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13283                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13284                        if (list != null && (list.length > 0)) {
13285                            for (String pkg : list) {
13286                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
13287                                        "storage unmount");
13288                            }
13289                            sendPackageBroadcastLocked(
13290                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13291                        }
13292                    } else {
13293                        Uri data = intent.getData();
13294                        String ssp;
13295                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13296                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13297                                    intent.getAction());
13298                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13299                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13300                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13301                                        false, userId, removed ? "pkg removed" : "pkg changed");
13302                            }
13303                            if (removed) {
13304                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13305                                        new String[] {ssp}, userId);
13306                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13307                                    mAppOpsService.packageRemoved(
13308                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13309
13310                                    // Remove all permissions granted from/to this package
13311                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13312                                }
13313                            }
13314                        }
13315                    }
13316                }
13317            } else {
13318                String msg = "Permission Denial: " + intent.getAction()
13319                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13320                        + ", uid=" + callingUid + ")"
13321                        + " requires "
13322                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13323                Slog.w(TAG, msg);
13324                throw new SecurityException(msg);
13325            }
13326
13327        // Special case for adding a package: by default turn on compatibility
13328        // mode.
13329        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13330            Uri data = intent.getData();
13331            String ssp;
13332            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13333                mCompatModePackages.handlePackageAddedLocked(ssp,
13334                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13335            }
13336        }
13337
13338        /*
13339         * If this is the time zone changed action, queue up a message that will reset the timezone
13340         * of all currently running processes. This message will get queued up before the broadcast
13341         * happens.
13342         */
13343        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13344            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13345        }
13346
13347        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13348            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13349        }
13350
13351        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13352            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13353            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13354        }
13355
13356        // Add to the sticky list if requested.
13357        if (sticky) {
13358            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13359                    callingPid, callingUid)
13360                    != PackageManager.PERMISSION_GRANTED) {
13361                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13362                        + callingPid + ", uid=" + callingUid
13363                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13364                Slog.w(TAG, msg);
13365                throw new SecurityException(msg);
13366            }
13367            if (requiredPermission != null) {
13368                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13369                        + " and enforce permission " + requiredPermission);
13370                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13371            }
13372            if (intent.getComponent() != null) {
13373                throw new SecurityException(
13374                        "Sticky broadcasts can't target a specific component");
13375            }
13376            // We use userId directly here, since the "all" target is maintained
13377            // as a separate set of sticky broadcasts.
13378            if (userId != UserHandle.USER_ALL) {
13379                // But first, if this is not a broadcast to all users, then
13380                // make sure it doesn't conflict with an existing broadcast to
13381                // all users.
13382                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13383                        UserHandle.USER_ALL);
13384                if (stickies != null) {
13385                    ArrayList<Intent> list = stickies.get(intent.getAction());
13386                    if (list != null) {
13387                        int N = list.size();
13388                        int i;
13389                        for (i=0; i<N; i++) {
13390                            if (intent.filterEquals(list.get(i))) {
13391                                throw new IllegalArgumentException(
13392                                        "Sticky broadcast " + intent + " for user "
13393                                        + userId + " conflicts with existing global broadcast");
13394                            }
13395                        }
13396                    }
13397                }
13398            }
13399            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13400            if (stickies == null) {
13401                stickies = new ArrayMap<String, ArrayList<Intent>>();
13402                mStickyBroadcasts.put(userId, stickies);
13403            }
13404            ArrayList<Intent> list = stickies.get(intent.getAction());
13405            if (list == null) {
13406                list = new ArrayList<Intent>();
13407                stickies.put(intent.getAction(), list);
13408            }
13409            int N = list.size();
13410            int i;
13411            for (i=0; i<N; i++) {
13412                if (intent.filterEquals(list.get(i))) {
13413                    // This sticky already exists, replace it.
13414                    list.set(i, new Intent(intent));
13415                    break;
13416                }
13417            }
13418            if (i >= N) {
13419                list.add(new Intent(intent));
13420            }
13421        }
13422
13423        int[] users;
13424        if (userId == UserHandle.USER_ALL) {
13425            // Caller wants broadcast to go to all started users.
13426            users = mStartedUserArray;
13427        } else {
13428            // Caller wants broadcast to go to one specific user.
13429            users = new int[] {userId};
13430        }
13431
13432        // Figure out who all will receive this broadcast.
13433        List receivers = null;
13434        List<BroadcastFilter> registeredReceivers = null;
13435        // Need to resolve the intent to interested receivers...
13436        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13437                 == 0) {
13438            receivers = collectReceiverComponents(intent, resolvedType, users);
13439        }
13440        if (intent.getComponent() == null) {
13441            registeredReceivers = mReceiverResolver.queryIntent(intent,
13442                    resolvedType, false, userId);
13443        }
13444
13445        final boolean replacePending =
13446                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13447
13448        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13449                + " replacePending=" + replacePending);
13450
13451        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13452        if (!ordered && NR > 0) {
13453            // If we are not serializing this broadcast, then send the
13454            // registered receivers separately so they don't wait for the
13455            // components to be launched.
13456            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13457            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13458                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13459                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13460                    ordered, sticky, false, userId);
13461            if (DEBUG_BROADCAST) Slog.v(
13462                    TAG, "Enqueueing parallel broadcast " + r);
13463            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13464            if (!replaced) {
13465                queue.enqueueParallelBroadcastLocked(r);
13466                queue.scheduleBroadcastsLocked();
13467            }
13468            registeredReceivers = null;
13469            NR = 0;
13470        }
13471
13472        // Merge into one list.
13473        int ir = 0;
13474        if (receivers != null) {
13475            // A special case for PACKAGE_ADDED: do not allow the package
13476            // being added to see this broadcast.  This prevents them from
13477            // using this as a back door to get run as soon as they are
13478            // installed.  Maybe in the future we want to have a special install
13479            // broadcast or such for apps, but we'd like to deliberately make
13480            // this decision.
13481            String skipPackages[] = null;
13482            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13483                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13484                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13485                Uri data = intent.getData();
13486                if (data != null) {
13487                    String pkgName = data.getSchemeSpecificPart();
13488                    if (pkgName != null) {
13489                        skipPackages = new String[] { pkgName };
13490                    }
13491                }
13492            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13493                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13494            }
13495            if (skipPackages != null && (skipPackages.length > 0)) {
13496                for (String skipPackage : skipPackages) {
13497                    if (skipPackage != null) {
13498                        int NT = receivers.size();
13499                        for (int it=0; it<NT; it++) {
13500                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13501                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13502                                receivers.remove(it);
13503                                it--;
13504                                NT--;
13505                            }
13506                        }
13507                    }
13508                }
13509            }
13510
13511            int NT = receivers != null ? receivers.size() : 0;
13512            int it = 0;
13513            ResolveInfo curt = null;
13514            BroadcastFilter curr = null;
13515            while (it < NT && ir < NR) {
13516                if (curt == null) {
13517                    curt = (ResolveInfo)receivers.get(it);
13518                }
13519                if (curr == null) {
13520                    curr = registeredReceivers.get(ir);
13521                }
13522                if (curr.getPriority() >= curt.priority) {
13523                    // Insert this broadcast record into the final list.
13524                    receivers.add(it, curr);
13525                    ir++;
13526                    curr = null;
13527                    it++;
13528                    NT++;
13529                } else {
13530                    // Skip to the next ResolveInfo in the final list.
13531                    it++;
13532                    curt = null;
13533                }
13534            }
13535        }
13536        while (ir < NR) {
13537            if (receivers == null) {
13538                receivers = new ArrayList();
13539            }
13540            receivers.add(registeredReceivers.get(ir));
13541            ir++;
13542        }
13543
13544        if ((receivers != null && receivers.size() > 0)
13545                || resultTo != null) {
13546            BroadcastQueue queue = broadcastQueueForIntent(intent);
13547            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13548                    callerPackage, callingPid, callingUid, resolvedType,
13549                    requiredPermission, appOp, receivers, resultTo, resultCode,
13550                    resultData, map, ordered, sticky, false, userId);
13551            if (DEBUG_BROADCAST) Slog.v(
13552                    TAG, "Enqueueing ordered broadcast " + r
13553                    + ": prev had " + queue.mOrderedBroadcasts.size());
13554            if (DEBUG_BROADCAST) {
13555                int seq = r.intent.getIntExtra("seq", -1);
13556                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13557            }
13558            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13559            if (!replaced) {
13560                queue.enqueueOrderedBroadcastLocked(r);
13561                queue.scheduleBroadcastsLocked();
13562            }
13563        }
13564
13565        return ActivityManager.BROADCAST_SUCCESS;
13566    }
13567
13568    final Intent verifyBroadcastLocked(Intent intent) {
13569        // Refuse possible leaked file descriptors
13570        if (intent != null && intent.hasFileDescriptors() == true) {
13571            throw new IllegalArgumentException("File descriptors passed in Intent");
13572        }
13573
13574        int flags = intent.getFlags();
13575
13576        if (!mProcessesReady) {
13577            // if the caller really truly claims to know what they're doing, go
13578            // ahead and allow the broadcast without launching any receivers
13579            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13580                intent = new Intent(intent);
13581                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13582            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13583                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13584                        + " before boot completion");
13585                throw new IllegalStateException("Cannot broadcast before boot completed");
13586            }
13587        }
13588
13589        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13590            throw new IllegalArgumentException(
13591                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13592        }
13593
13594        return intent;
13595    }
13596
13597    public final int broadcastIntent(IApplicationThread caller,
13598            Intent intent, String resolvedType, IIntentReceiver resultTo,
13599            int resultCode, String resultData, Bundle map,
13600            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13601        enforceNotIsolatedCaller("broadcastIntent");
13602        synchronized(this) {
13603            intent = verifyBroadcastLocked(intent);
13604
13605            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13606            final int callingPid = Binder.getCallingPid();
13607            final int callingUid = Binder.getCallingUid();
13608            final long origId = Binder.clearCallingIdentity();
13609            int res = broadcastIntentLocked(callerApp,
13610                    callerApp != null ? callerApp.info.packageName : null,
13611                    intent, resolvedType, resultTo,
13612                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13613                    callingPid, callingUid, userId);
13614            Binder.restoreCallingIdentity(origId);
13615            return res;
13616        }
13617    }
13618
13619    int broadcastIntentInPackage(String packageName, int uid,
13620            Intent intent, String resolvedType, IIntentReceiver resultTo,
13621            int resultCode, String resultData, Bundle map,
13622            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13623        synchronized(this) {
13624            intent = verifyBroadcastLocked(intent);
13625
13626            final long origId = Binder.clearCallingIdentity();
13627            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13628                    resultTo, resultCode, resultData, map, requiredPermission,
13629                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13630            Binder.restoreCallingIdentity(origId);
13631            return res;
13632        }
13633    }
13634
13635    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13636        // Refuse possible leaked file descriptors
13637        if (intent != null && intent.hasFileDescriptors() == true) {
13638            throw new IllegalArgumentException("File descriptors passed in Intent");
13639        }
13640
13641        userId = handleIncomingUser(Binder.getCallingPid(),
13642                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13643
13644        synchronized(this) {
13645            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13646                    != PackageManager.PERMISSION_GRANTED) {
13647                String msg = "Permission Denial: unbroadcastIntent() from pid="
13648                        + Binder.getCallingPid()
13649                        + ", uid=" + Binder.getCallingUid()
13650                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13651                Slog.w(TAG, msg);
13652                throw new SecurityException(msg);
13653            }
13654            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13655            if (stickies != null) {
13656                ArrayList<Intent> list = stickies.get(intent.getAction());
13657                if (list != null) {
13658                    int N = list.size();
13659                    int i;
13660                    for (i=0; i<N; i++) {
13661                        if (intent.filterEquals(list.get(i))) {
13662                            list.remove(i);
13663                            break;
13664                        }
13665                    }
13666                    if (list.size() <= 0) {
13667                        stickies.remove(intent.getAction());
13668                    }
13669                }
13670                if (stickies.size() <= 0) {
13671                    mStickyBroadcasts.remove(userId);
13672                }
13673            }
13674        }
13675    }
13676
13677    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13678            String resultData, Bundle resultExtras, boolean resultAbort) {
13679        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13680        if (r == null) {
13681            Slog.w(TAG, "finishReceiver called but not found on queue");
13682            return false;
13683        }
13684
13685        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13686    }
13687
13688    void backgroundServicesFinishedLocked(int userId) {
13689        for (BroadcastQueue queue : mBroadcastQueues) {
13690            queue.backgroundServicesFinishedLocked(userId);
13691        }
13692    }
13693
13694    public void finishReceiver(IBinder who, int resultCode, String resultData,
13695            Bundle resultExtras, boolean resultAbort) {
13696        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13697
13698        // Refuse possible leaked file descriptors
13699        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13700            throw new IllegalArgumentException("File descriptors passed in Bundle");
13701        }
13702
13703        final long origId = Binder.clearCallingIdentity();
13704        try {
13705            boolean doNext = false;
13706            BroadcastRecord r;
13707
13708            synchronized(this) {
13709                r = broadcastRecordForReceiverLocked(who);
13710                if (r != null) {
13711                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13712                        resultData, resultExtras, resultAbort, true);
13713                }
13714            }
13715
13716            if (doNext) {
13717                r.queue.processNextBroadcast(false);
13718            }
13719            trimApplications();
13720        } finally {
13721            Binder.restoreCallingIdentity(origId);
13722        }
13723    }
13724
13725    // =========================================================
13726    // INSTRUMENTATION
13727    // =========================================================
13728
13729    public boolean startInstrumentation(ComponentName className,
13730            String profileFile, int flags, Bundle arguments,
13731            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13732            int userId) {
13733        enforceNotIsolatedCaller("startInstrumentation");
13734        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13735                userId, false, true, "startInstrumentation", null);
13736        // Refuse possible leaked file descriptors
13737        if (arguments != null && arguments.hasFileDescriptors()) {
13738            throw new IllegalArgumentException("File descriptors passed in Bundle");
13739        }
13740
13741        synchronized(this) {
13742            InstrumentationInfo ii = null;
13743            ApplicationInfo ai = null;
13744            try {
13745                ii = mContext.getPackageManager().getInstrumentationInfo(
13746                    className, STOCK_PM_FLAGS);
13747                ai = AppGlobals.getPackageManager().getApplicationInfo(
13748                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13749            } catch (PackageManager.NameNotFoundException e) {
13750            } catch (RemoteException e) {
13751            }
13752            if (ii == null) {
13753                reportStartInstrumentationFailure(watcher, className,
13754                        "Unable to find instrumentation info for: " + className);
13755                return false;
13756            }
13757            if (ai == null) {
13758                reportStartInstrumentationFailure(watcher, className,
13759                        "Unable to find instrumentation target package: " + ii.targetPackage);
13760                return false;
13761            }
13762
13763            int match = mContext.getPackageManager().checkSignatures(
13764                    ii.targetPackage, ii.packageName);
13765            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13766                String msg = "Permission Denial: starting instrumentation "
13767                        + className + " from pid="
13768                        + Binder.getCallingPid()
13769                        + ", uid=" + Binder.getCallingPid()
13770                        + " not allowed because package " + ii.packageName
13771                        + " does not have a signature matching the target "
13772                        + ii.targetPackage;
13773                reportStartInstrumentationFailure(watcher, className, msg);
13774                throw new SecurityException(msg);
13775            }
13776
13777            final long origId = Binder.clearCallingIdentity();
13778            // Instrumentation can kill and relaunch even persistent processes
13779            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
13780                    "start instr");
13781            ProcessRecord app = addAppLocked(ai, false);
13782            app.instrumentationClass = className;
13783            app.instrumentationInfo = ai;
13784            app.instrumentationProfileFile = profileFile;
13785            app.instrumentationArguments = arguments;
13786            app.instrumentationWatcher = watcher;
13787            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13788            app.instrumentationResultClass = className;
13789            Binder.restoreCallingIdentity(origId);
13790        }
13791
13792        return true;
13793    }
13794
13795    /**
13796     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13797     * error to the logs, but if somebody is watching, send the report there too.  This enables
13798     * the "am" command to report errors with more information.
13799     *
13800     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13801     * @param cn The component name of the instrumentation.
13802     * @param report The error report.
13803     */
13804    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13805            ComponentName cn, String report) {
13806        Slog.w(TAG, report);
13807        try {
13808            if (watcher != null) {
13809                Bundle results = new Bundle();
13810                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13811                results.putString("Error", report);
13812                watcher.instrumentationStatus(cn, -1, results);
13813            }
13814        } catch (RemoteException e) {
13815            Slog.w(TAG, e);
13816        }
13817    }
13818
13819    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13820        if (app.instrumentationWatcher != null) {
13821            try {
13822                // NOTE:  IInstrumentationWatcher *must* be oneway here
13823                app.instrumentationWatcher.instrumentationFinished(
13824                    app.instrumentationClass,
13825                    resultCode,
13826                    results);
13827            } catch (RemoteException e) {
13828            }
13829        }
13830        if (app.instrumentationUiAutomationConnection != null) {
13831            try {
13832                app.instrumentationUiAutomationConnection.shutdown();
13833            } catch (RemoteException re) {
13834                /* ignore */
13835            }
13836            // Only a UiAutomation can set this flag and now that
13837            // it is finished we make sure it is reset to its default.
13838            mUserIsMonkey = false;
13839        }
13840        app.instrumentationWatcher = null;
13841        app.instrumentationUiAutomationConnection = null;
13842        app.instrumentationClass = null;
13843        app.instrumentationInfo = null;
13844        app.instrumentationProfileFile = null;
13845        app.instrumentationArguments = null;
13846
13847        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
13848                "finished inst");
13849    }
13850
13851    public void finishInstrumentation(IApplicationThread target,
13852            int resultCode, Bundle results) {
13853        int userId = UserHandle.getCallingUserId();
13854        // Refuse possible leaked file descriptors
13855        if (results != null && results.hasFileDescriptors()) {
13856            throw new IllegalArgumentException("File descriptors passed in Intent");
13857        }
13858
13859        synchronized(this) {
13860            ProcessRecord app = getRecordForAppLocked(target);
13861            if (app == null) {
13862                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13863                return;
13864            }
13865            final long origId = Binder.clearCallingIdentity();
13866            finishInstrumentationLocked(app, resultCode, results);
13867            Binder.restoreCallingIdentity(origId);
13868        }
13869    }
13870
13871    // =========================================================
13872    // CONFIGURATION
13873    // =========================================================
13874
13875    public ConfigurationInfo getDeviceConfigurationInfo() {
13876        ConfigurationInfo config = new ConfigurationInfo();
13877        synchronized (this) {
13878            config.reqTouchScreen = mConfiguration.touchscreen;
13879            config.reqKeyboardType = mConfiguration.keyboard;
13880            config.reqNavigation = mConfiguration.navigation;
13881            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13882                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13883                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13884            }
13885            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13886                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13887                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13888            }
13889            config.reqGlEsVersion = GL_ES_VERSION;
13890        }
13891        return config;
13892    }
13893
13894    ActivityStack getFocusedStack() {
13895        return mStackSupervisor.getFocusedStack();
13896    }
13897
13898    public Configuration getConfiguration() {
13899        Configuration ci;
13900        synchronized(this) {
13901            ci = new Configuration(mConfiguration);
13902        }
13903        return ci;
13904    }
13905
13906    public void updatePersistentConfiguration(Configuration values) {
13907        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13908                "updateConfiguration()");
13909        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13910                "updateConfiguration()");
13911        if (values == null) {
13912            throw new NullPointerException("Configuration must not be null");
13913        }
13914
13915        synchronized(this) {
13916            final long origId = Binder.clearCallingIdentity();
13917            updateConfigurationLocked(values, null, true, false);
13918            Binder.restoreCallingIdentity(origId);
13919        }
13920    }
13921
13922    public void updateConfiguration(Configuration values) {
13923        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13924                "updateConfiguration()");
13925
13926        synchronized(this) {
13927            if (values == null && mWindowManager != null) {
13928                // sentinel: fetch the current configuration from the window manager
13929                values = mWindowManager.computeNewConfiguration();
13930            }
13931
13932            if (mWindowManager != null) {
13933                mProcessList.applyDisplaySize(mWindowManager);
13934            }
13935
13936            final long origId = Binder.clearCallingIdentity();
13937            if (values != null) {
13938                Settings.System.clearConfiguration(values);
13939            }
13940            updateConfigurationLocked(values, null, false, false);
13941            Binder.restoreCallingIdentity(origId);
13942        }
13943    }
13944
13945    /**
13946     * Do either or both things: (1) change the current configuration, and (2)
13947     * make sure the given activity is running with the (now) current
13948     * configuration.  Returns true if the activity has been left running, or
13949     * false if <var>starting</var> is being destroyed to match the new
13950     * configuration.
13951     * @param persistent TODO
13952     */
13953    boolean updateConfigurationLocked(Configuration values,
13954            ActivityRecord starting, boolean persistent, boolean initLocale) {
13955        int changes = 0;
13956
13957        if (values != null) {
13958            Configuration newConfig = new Configuration(mConfiguration);
13959            changes = newConfig.updateFrom(values);
13960            if (changes != 0) {
13961                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13962                    Slog.i(TAG, "Updating configuration to: " + values);
13963                }
13964
13965                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13966
13967                if (values.locale != null && !initLocale) {
13968                    saveLocaleLocked(values.locale,
13969                                     !values.locale.equals(mConfiguration.locale),
13970                                     values.userSetLocale);
13971                }
13972
13973                mConfigurationSeq++;
13974                if (mConfigurationSeq <= 0) {
13975                    mConfigurationSeq = 1;
13976                }
13977                newConfig.seq = mConfigurationSeq;
13978                mConfiguration = newConfig;
13979                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
13980
13981                final Configuration configCopy = new Configuration(mConfiguration);
13982
13983                // TODO: If our config changes, should we auto dismiss any currently
13984                // showing dialogs?
13985                mShowDialogs = shouldShowDialogs(newConfig);
13986
13987                AttributeCache ac = AttributeCache.instance();
13988                if (ac != null) {
13989                    ac.updateConfiguration(configCopy);
13990                }
13991
13992                // Make sure all resources in our process are updated
13993                // right now, so that anyone who is going to retrieve
13994                // resource values after we return will be sure to get
13995                // the new ones.  This is especially important during
13996                // boot, where the first config change needs to guarantee
13997                // all resources have that config before following boot
13998                // code is executed.
13999                sSystemThread.applyConfigurationToResources(configCopy);
14000
14001                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14002                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14003                    msg.obj = new Configuration(configCopy);
14004                    mHandler.sendMessage(msg);
14005                }
14006
14007                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14008                    ProcessRecord app = mLruProcesses.get(i);
14009                    try {
14010                        if (app.thread != null) {
14011                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14012                                    + app.processName + " new config " + mConfiguration);
14013                            app.thread.scheduleConfigurationChanged(configCopy);
14014                        }
14015                    } catch (Exception e) {
14016                    }
14017                }
14018                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14019                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14020                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14021                        | Intent.FLAG_RECEIVER_FOREGROUND);
14022                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14023                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14024                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14025                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14026                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14027                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14028                    broadcastIntentLocked(null, null, intent,
14029                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14030                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14031                }
14032            }
14033        }
14034
14035        boolean kept = true;
14036        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14037        // mainStack is null during startup.
14038        if (mainStack != null) {
14039            if (changes != 0 && starting == null) {
14040                // If the configuration changed, and the caller is not already
14041                // in the process of starting an activity, then find the top
14042                // activity to check if its configuration needs to change.
14043                starting = mainStack.topRunningActivityLocked(null);
14044            }
14045
14046            if (starting != null) {
14047                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14048                // And we need to make sure at this point that all other activities
14049                // are made visible with the correct configuration.
14050                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14051            }
14052        }
14053
14054        if (values != null && mWindowManager != null) {
14055            mWindowManager.setNewConfiguration(mConfiguration);
14056        }
14057
14058        return kept;
14059    }
14060
14061    /**
14062     * Decide based on the configuration whether we should shouw the ANR,
14063     * crash, etc dialogs.  The idea is that if there is no affordnace to
14064     * press the on-screen buttons, we shouldn't show the dialog.
14065     *
14066     * A thought: SystemUI might also want to get told about this, the Power
14067     * dialog / global actions also might want different behaviors.
14068     */
14069    private static final boolean shouldShowDialogs(Configuration config) {
14070        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14071                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14072    }
14073
14074    /**
14075     * Save the locale.  You must be inside a synchronized (this) block.
14076     */
14077    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14078        if(isDiff) {
14079            SystemProperties.set("user.language", l.getLanguage());
14080            SystemProperties.set("user.region", l.getCountry());
14081        }
14082
14083        if(isPersist) {
14084            SystemProperties.set("persist.sys.language", l.getLanguage());
14085            SystemProperties.set("persist.sys.country", l.getCountry());
14086            SystemProperties.set("persist.sys.localevar", l.getVariant());
14087        }
14088    }
14089
14090    @Override
14091    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14092        ActivityRecord srec = ActivityRecord.forToken(token);
14093        return srec != null && srec.task.affinity != null &&
14094                srec.task.affinity.equals(destAffinity);
14095    }
14096
14097    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14098            Intent resultData) {
14099
14100        synchronized (this) {
14101            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14102            if (stack != null) {
14103                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14104            }
14105            return false;
14106        }
14107    }
14108
14109    public int getLaunchedFromUid(IBinder activityToken) {
14110        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14111        if (srec == null) {
14112            return -1;
14113        }
14114        return srec.launchedFromUid;
14115    }
14116
14117    public String getLaunchedFromPackage(IBinder activityToken) {
14118        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14119        if (srec == null) {
14120            return null;
14121        }
14122        return srec.launchedFromPackage;
14123    }
14124
14125    // =========================================================
14126    // LIFETIME MANAGEMENT
14127    // =========================================================
14128
14129    // Returns which broadcast queue the app is the current [or imminent] receiver
14130    // on, or 'null' if the app is not an active broadcast recipient.
14131    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14132        BroadcastRecord r = app.curReceiver;
14133        if (r != null) {
14134            return r.queue;
14135        }
14136
14137        // It's not the current receiver, but it might be starting up to become one
14138        synchronized (this) {
14139            for (BroadcastQueue queue : mBroadcastQueues) {
14140                r = queue.mPendingBroadcast;
14141                if (r != null && r.curApp == app) {
14142                    // found it; report which queue it's in
14143                    return queue;
14144                }
14145            }
14146        }
14147
14148        return null;
14149    }
14150
14151    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14152            boolean doingAll, long now) {
14153        if (mAdjSeq == app.adjSeq) {
14154            // This adjustment has already been computed.
14155            return app.curRawAdj;
14156        }
14157
14158        if (app.thread == null) {
14159            app.adjSeq = mAdjSeq;
14160            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14161            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14162            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14163        }
14164
14165        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14166        app.adjSource = null;
14167        app.adjTarget = null;
14168        app.empty = false;
14169        app.cached = false;
14170
14171        final int activitiesSize = app.activities.size();
14172
14173        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14174            // The max adjustment doesn't allow this app to be anything
14175            // below foreground, so it is not worth doing work for it.
14176            app.adjType = "fixed";
14177            app.adjSeq = mAdjSeq;
14178            app.curRawAdj = app.maxAdj;
14179            app.foregroundActivities = false;
14180            app.keeping = true;
14181            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14182            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14183            // System process can do UI, and when they do we want to have
14184            // them trim their memory after the user leaves the UI.  To
14185            // facilitate this, here we need to determine whether or not it
14186            // is currently showing UI.
14187            app.systemNoUi = true;
14188            if (app == TOP_APP) {
14189                app.systemNoUi = false;
14190            } else if (activitiesSize > 0) {
14191                for (int j = 0; j < activitiesSize; j++) {
14192                    final ActivityRecord r = app.activities.get(j);
14193                    if (r.visible) {
14194                        app.systemNoUi = false;
14195                    }
14196                }
14197            }
14198            if (!app.systemNoUi) {
14199                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14200            }
14201            return (app.curAdj=app.maxAdj);
14202        }
14203
14204        app.keeping = false;
14205        app.systemNoUi = false;
14206
14207        // Determine the importance of the process, starting with most
14208        // important to least, and assign an appropriate OOM adjustment.
14209        int adj;
14210        int schedGroup;
14211        int procState;
14212        boolean foregroundActivities = false;
14213        boolean interesting = false;
14214        BroadcastQueue queue;
14215        if (app == TOP_APP) {
14216            // The last app on the list is the foreground app.
14217            adj = ProcessList.FOREGROUND_APP_ADJ;
14218            schedGroup = Process.THREAD_GROUP_DEFAULT;
14219            app.adjType = "top-activity";
14220            foregroundActivities = true;
14221            interesting = true;
14222            procState = ActivityManager.PROCESS_STATE_TOP;
14223        } else if (app.instrumentationClass != null) {
14224            // Don't want to kill running instrumentation.
14225            adj = ProcessList.FOREGROUND_APP_ADJ;
14226            schedGroup = Process.THREAD_GROUP_DEFAULT;
14227            app.adjType = "instrumentation";
14228            interesting = true;
14229            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14230        } else if ((queue = isReceivingBroadcast(app)) != null) {
14231            // An app that is currently receiving a broadcast also
14232            // counts as being in the foreground for OOM killer purposes.
14233            // It's placed in a sched group based on the nature of the
14234            // broadcast as reflected by which queue it's active in.
14235            adj = ProcessList.FOREGROUND_APP_ADJ;
14236            schedGroup = (queue == mFgBroadcastQueue)
14237                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14238            app.adjType = "broadcast";
14239            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14240        } else if (app.executingServices.size() > 0) {
14241            // An app that is currently executing a service callback also
14242            // counts as being in the foreground.
14243            adj = ProcessList.FOREGROUND_APP_ADJ;
14244            schedGroup = app.execServicesFg ?
14245                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14246            app.adjType = "exec-service";
14247            procState = ActivityManager.PROCESS_STATE_SERVICE;
14248            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14249        } else {
14250            // As far as we know the process is empty.  We may change our mind later.
14251            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14252            // At this point we don't actually know the adjustment.  Use the cached adj
14253            // value that the caller wants us to.
14254            adj = cachedAdj;
14255            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14256            app.cached = true;
14257            app.empty = true;
14258            app.adjType = "cch-empty";
14259        }
14260
14261        // Examine all activities if not already foreground.
14262        if (!foregroundActivities && activitiesSize > 0) {
14263            for (int j = 0; j < activitiesSize; j++) {
14264                final ActivityRecord r = app.activities.get(j);
14265                if (r.app != app) {
14266                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14267                            + app + "?!?");
14268                    continue;
14269                }
14270                if (r.visible) {
14271                    // App has a visible activity; only upgrade adjustment.
14272                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14273                        adj = ProcessList.VISIBLE_APP_ADJ;
14274                        app.adjType = "visible";
14275                    }
14276                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14277                        procState = ActivityManager.PROCESS_STATE_TOP;
14278                    }
14279                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14280                    app.cached = false;
14281                    app.empty = false;
14282                    foregroundActivities = true;
14283                    break;
14284                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14285                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14286                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14287                        app.adjType = "pausing";
14288                    }
14289                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14290                        procState = ActivityManager.PROCESS_STATE_TOP;
14291                    }
14292                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14293                    app.cached = false;
14294                    app.empty = false;
14295                    foregroundActivities = true;
14296                } else if (r.state == ActivityState.STOPPING) {
14297                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14298                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14299                        app.adjType = "stopping";
14300                    }
14301                    // For the process state, we will at this point consider the
14302                    // process to be cached.  It will be cached either as an activity
14303                    // or empty depending on whether the activity is finishing.  We do
14304                    // this so that we can treat the process as cached for purposes of
14305                    // memory trimming (determing current memory level, trim command to
14306                    // send to process) since there can be an arbitrary number of stopping
14307                    // processes and they should soon all go into the cached state.
14308                    if (!r.finishing) {
14309                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14310                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14311                        }
14312                    }
14313                    app.cached = false;
14314                    app.empty = false;
14315                    foregroundActivities = true;
14316                } else {
14317                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14318                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14319                        app.adjType = "cch-act";
14320                    }
14321                }
14322            }
14323        }
14324
14325        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14326            if (app.foregroundServices) {
14327                // The user is aware of this app, so make it visible.
14328                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14329                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14330                app.cached = false;
14331                app.adjType = "fg-service";
14332                schedGroup = Process.THREAD_GROUP_DEFAULT;
14333            } else if (app.forcingToForeground != null) {
14334                // The user is aware of this app, so make it visible.
14335                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14336                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14337                app.cached = false;
14338                app.adjType = "force-fg";
14339                app.adjSource = app.forcingToForeground;
14340                schedGroup = Process.THREAD_GROUP_DEFAULT;
14341            }
14342        }
14343
14344        if (app.foregroundServices) {
14345            interesting = true;
14346        }
14347
14348        if (app == mHeavyWeightProcess) {
14349            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14350                // We don't want to kill the current heavy-weight process.
14351                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14352                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14353                app.cached = false;
14354                app.adjType = "heavy";
14355            }
14356            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14357                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14358            }
14359        }
14360
14361        if (app == mHomeProcess) {
14362            if (adj > ProcessList.HOME_APP_ADJ) {
14363                // This process is hosting what we currently consider to be the
14364                // home app, so we don't want to let it go into the background.
14365                adj = ProcessList.HOME_APP_ADJ;
14366                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14367                app.cached = false;
14368                app.adjType = "home";
14369            }
14370            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14371                procState = ActivityManager.PROCESS_STATE_HOME;
14372            }
14373        }
14374
14375        if (app == mPreviousProcess && app.activities.size() > 0) {
14376            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14377                // This was the previous process that showed UI to the user.
14378                // We want to try to keep it around more aggressively, to give
14379                // a good experience around switching between two apps.
14380                adj = ProcessList.PREVIOUS_APP_ADJ;
14381                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14382                app.cached = false;
14383                app.adjType = "previous";
14384            }
14385            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14386                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14387            }
14388        }
14389
14390        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14391                + " reason=" + app.adjType);
14392
14393        // By default, we use the computed adjustment.  It may be changed if
14394        // there are applications dependent on our services or providers, but
14395        // this gives us a baseline and makes sure we don't get into an
14396        // infinite recursion.
14397        app.adjSeq = mAdjSeq;
14398        app.curRawAdj = adj;
14399        app.hasStartedServices = false;
14400
14401        if (mBackupTarget != null && app == mBackupTarget.app) {
14402            // If possible we want to avoid killing apps while they're being backed up
14403            if (adj > ProcessList.BACKUP_APP_ADJ) {
14404                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14405                adj = ProcessList.BACKUP_APP_ADJ;
14406                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14407                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14408                }
14409                app.adjType = "backup";
14410                app.cached = false;
14411            }
14412            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14413                procState = ActivityManager.PROCESS_STATE_BACKUP;
14414            }
14415        }
14416
14417        boolean mayBeTop = false;
14418
14419        for (int is = app.services.size()-1;
14420                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14421                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14422                        || procState > ActivityManager.PROCESS_STATE_TOP);
14423                is--) {
14424            ServiceRecord s = app.services.valueAt(is);
14425            if (s.startRequested) {
14426                app.hasStartedServices = true;
14427                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14428                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14429                }
14430                if (app.hasShownUi && app != mHomeProcess) {
14431                    // If this process has shown some UI, let it immediately
14432                    // go to the LRU list because it may be pretty heavy with
14433                    // UI stuff.  We'll tag it with a label just to help
14434                    // debug and understand what is going on.
14435                    if (adj > ProcessList.SERVICE_ADJ) {
14436                        app.adjType = "cch-started-ui-services";
14437                    }
14438                } else {
14439                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14440                        // This service has seen some activity within
14441                        // recent memory, so we will keep its process ahead
14442                        // of the background processes.
14443                        if (adj > ProcessList.SERVICE_ADJ) {
14444                            adj = ProcessList.SERVICE_ADJ;
14445                            app.adjType = "started-services";
14446                            app.cached = false;
14447                        }
14448                    }
14449                    // If we have let the service slide into the background
14450                    // state, still have some text describing what it is doing
14451                    // even though the service no longer has an impact.
14452                    if (adj > ProcessList.SERVICE_ADJ) {
14453                        app.adjType = "cch-started-services";
14454                    }
14455                }
14456                // Don't kill this process because it is doing work; it
14457                // has said it is doing work.
14458                app.keeping = true;
14459            }
14460            for (int conni = s.connections.size()-1;
14461                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14462                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14463                            || procState > ActivityManager.PROCESS_STATE_TOP);
14464                    conni--) {
14465                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14466                for (int i = 0;
14467                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14468                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14469                                || procState > ActivityManager.PROCESS_STATE_TOP);
14470                        i++) {
14471                    // XXX should compute this based on the max of
14472                    // all connected clients.
14473                    ConnectionRecord cr = clist.get(i);
14474                    if (cr.binding.client == app) {
14475                        // Binding to ourself is not interesting.
14476                        continue;
14477                    }
14478                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14479                        ProcessRecord client = cr.binding.client;
14480                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14481                                TOP_APP, doingAll, now);
14482                        int clientProcState = client.curProcState;
14483                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14484                            // If the other app is cached for any reason, for purposes here
14485                            // we are going to consider it empty.  The specific cached state
14486                            // doesn't propagate except under certain conditions.
14487                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14488                        }
14489                        String adjType = null;
14490                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14491                            // Not doing bind OOM management, so treat
14492                            // this guy more like a started service.
14493                            if (app.hasShownUi && app != mHomeProcess) {
14494                                // If this process has shown some UI, let it immediately
14495                                // go to the LRU list because it may be pretty heavy with
14496                                // UI stuff.  We'll tag it with a label just to help
14497                                // debug and understand what is going on.
14498                                if (adj > clientAdj) {
14499                                    adjType = "cch-bound-ui-services";
14500                                }
14501                                app.cached = false;
14502                                clientAdj = adj;
14503                                clientProcState = procState;
14504                            } else {
14505                                if (now >= (s.lastActivity
14506                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14507                                    // This service has not seen activity within
14508                                    // recent memory, so allow it to drop to the
14509                                    // LRU list if there is no other reason to keep
14510                                    // it around.  We'll also tag it with a label just
14511                                    // to help debug and undertand what is going on.
14512                                    if (adj > clientAdj) {
14513                                        adjType = "cch-bound-services";
14514                                    }
14515                                    clientAdj = adj;
14516                                }
14517                            }
14518                        }
14519                        if (adj > clientAdj) {
14520                            // If this process has recently shown UI, and
14521                            // the process that is binding to it is less
14522                            // important than being visible, then we don't
14523                            // care about the binding as much as we care
14524                            // about letting this process get into the LRU
14525                            // list to be killed and restarted if needed for
14526                            // memory.
14527                            if (app.hasShownUi && app != mHomeProcess
14528                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14529                                adjType = "cch-bound-ui-services";
14530                            } else {
14531                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14532                                        |Context.BIND_IMPORTANT)) != 0) {
14533                                    adj = clientAdj;
14534                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14535                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14536                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14537                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14538                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14539                                    adj = clientAdj;
14540                                } else {
14541                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14542                                        adj = ProcessList.VISIBLE_APP_ADJ;
14543                                    }
14544                                }
14545                                if (!client.cached) {
14546                                    app.cached = false;
14547                                }
14548                                if (client.keeping) {
14549                                    app.keeping = true;
14550                                }
14551                                adjType = "service";
14552                            }
14553                        }
14554                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14555                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14556                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14557                            }
14558                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14559                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14560                                    // Special handling of clients who are in the top state.
14561                                    // We *may* want to consider this process to be in the
14562                                    // top state as well, but only if there is not another
14563                                    // reason for it to be running.  Being on the top is a
14564                                    // special state, meaning you are specifically running
14565                                    // for the current top app.  If the process is already
14566                                    // running in the background for some other reason, it
14567                                    // is more important to continue considering it to be
14568                                    // in the background state.
14569                                    mayBeTop = true;
14570                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14571                                } else {
14572                                    // Special handling for above-top states (persistent
14573                                    // processes).  These should not bring the current process
14574                                    // into the top state, since they are not on top.  Instead
14575                                    // give them the best state after that.
14576                                    clientProcState =
14577                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14578                                }
14579                            }
14580                        } else {
14581                            if (clientProcState <
14582                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14583                                clientProcState =
14584                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14585                            }
14586                        }
14587                        if (procState > clientProcState) {
14588                            procState = clientProcState;
14589                        }
14590                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14591                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14592                            app.pendingUiClean = true;
14593                        }
14594                        if (adjType != null) {
14595                            app.adjType = adjType;
14596                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14597                                    .REASON_SERVICE_IN_USE;
14598                            app.adjSource = cr.binding.client;
14599                            app.adjSourceOom = clientAdj;
14600                            app.adjTarget = s.name;
14601                        }
14602                    }
14603                    final ActivityRecord a = cr.activity;
14604                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14605                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14606                                (a.visible || a.state == ActivityState.RESUMED
14607                                 || a.state == ActivityState.PAUSING)) {
14608                            adj = ProcessList.FOREGROUND_APP_ADJ;
14609                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14610                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14611                            }
14612                            app.cached = false;
14613                            app.adjType = "service";
14614                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14615                                    .REASON_SERVICE_IN_USE;
14616                            app.adjSource = a;
14617                            app.adjSourceOom = adj;
14618                            app.adjTarget = s.name;
14619                        }
14620                    }
14621                }
14622            }
14623        }
14624
14625        for (int provi = app.pubProviders.size()-1;
14626                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14627                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14628                        || procState > ActivityManager.PROCESS_STATE_TOP);
14629                provi--) {
14630            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14631            for (int i = cpr.connections.size()-1;
14632                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14633                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14634                            || procState > ActivityManager.PROCESS_STATE_TOP);
14635                    i--) {
14636                ContentProviderConnection conn = cpr.connections.get(i);
14637                ProcessRecord client = conn.client;
14638                if (client == app) {
14639                    // Being our own client is not interesting.
14640                    continue;
14641                }
14642                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14643                int clientProcState = client.curProcState;
14644                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14645                    // If the other app is cached for any reason, for purposes here
14646                    // we are going to consider it empty.
14647                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14648                }
14649                if (adj > clientAdj) {
14650                    if (app.hasShownUi && app != mHomeProcess
14651                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14652                        app.adjType = "cch-ui-provider";
14653                    } else {
14654                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14655                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14656                        app.adjType = "provider";
14657                    }
14658                    app.cached &= client.cached;
14659                    app.keeping |= client.keeping;
14660                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14661                            .REASON_PROVIDER_IN_USE;
14662                    app.adjSource = client;
14663                    app.adjSourceOom = clientAdj;
14664                    app.adjTarget = cpr.name;
14665                }
14666                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14667                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14668                        // Special handling of clients who are in the top state.
14669                        // We *may* want to consider this process to be in the
14670                        // top state as well, but only if there is not another
14671                        // reason for it to be running.  Being on the top is a
14672                        // special state, meaning you are specifically running
14673                        // for the current top app.  If the process is already
14674                        // running in the background for some other reason, it
14675                        // is more important to continue considering it to be
14676                        // in the background state.
14677                        mayBeTop = true;
14678                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14679                    } else {
14680                        // Special handling for above-top states (persistent
14681                        // processes).  These should not bring the current process
14682                        // into the top state, since they are not on top.  Instead
14683                        // give them the best state after that.
14684                        clientProcState =
14685                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14686                    }
14687                }
14688                if (procState > clientProcState) {
14689                    procState = clientProcState;
14690                }
14691                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14692                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14693                }
14694            }
14695            // If the provider has external (non-framework) process
14696            // dependencies, ensure that its adjustment is at least
14697            // FOREGROUND_APP_ADJ.
14698            if (cpr.hasExternalProcessHandles()) {
14699                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14700                    adj = ProcessList.FOREGROUND_APP_ADJ;
14701                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14702                    app.cached = false;
14703                    app.keeping = true;
14704                    app.adjType = "provider";
14705                    app.adjTarget = cpr.name;
14706                }
14707                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14708                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14709                }
14710            }
14711        }
14712
14713        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14714            // A client of one of our services or providers is in the top state.  We
14715            // *may* want to be in the top state, but not if we are already running in
14716            // the background for some other reason.  For the decision here, we are going
14717            // to pick out a few specific states that we want to remain in when a client
14718            // is top (states that tend to be longer-term) and otherwise allow it to go
14719            // to the top state.
14720            switch (procState) {
14721                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14722                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14723                case ActivityManager.PROCESS_STATE_SERVICE:
14724                    // These all are longer-term states, so pull them up to the top
14725                    // of the background states, but not all the way to the top state.
14726                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14727                    break;
14728                default:
14729                    // Otherwise, top is a better choice, so take it.
14730                    procState = ActivityManager.PROCESS_STATE_TOP;
14731                    break;
14732            }
14733        }
14734
14735        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14736            // This is a cached process, but with client activities.  Mark it so.
14737            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14738            app.adjType = "cch-client-act";
14739        }
14740
14741        if (adj == ProcessList.SERVICE_ADJ) {
14742            if (doingAll) {
14743                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14744                mNewNumServiceProcs++;
14745                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14746                if (!app.serviceb) {
14747                    // This service isn't far enough down on the LRU list to
14748                    // normally be a B service, but if we are low on RAM and it
14749                    // is large we want to force it down since we would prefer to
14750                    // keep launcher over it.
14751                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14752                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14753                        app.serviceHighRam = true;
14754                        app.serviceb = true;
14755                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14756                    } else {
14757                        mNewNumAServiceProcs++;
14758                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14759                    }
14760                } else {
14761                    app.serviceHighRam = false;
14762                }
14763            }
14764            if (app.serviceb) {
14765                adj = ProcessList.SERVICE_B_ADJ;
14766            }
14767        }
14768
14769        app.curRawAdj = adj;
14770
14771        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14772        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14773        if (adj > app.maxAdj) {
14774            adj = app.maxAdj;
14775            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14776                schedGroup = Process.THREAD_GROUP_DEFAULT;
14777            }
14778        }
14779        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14780            app.keeping = true;
14781        }
14782
14783        // Do final modification to adj.  Everything we do between here and applying
14784        // the final setAdj must be done in this function, because we will also use
14785        // it when computing the final cached adj later.  Note that we don't need to
14786        // worry about this for max adj above, since max adj will always be used to
14787        // keep it out of the cached vaues.
14788        adj = app.modifyRawOomAdj(adj);
14789
14790        app.curProcState = procState;
14791
14792        int importance = app.memImportance;
14793        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14794            app.curAdj = adj;
14795            app.curSchedGroup = schedGroup;
14796            if (!interesting) {
14797                // For this reporting, if there is not something explicitly
14798                // interesting in this process then we will push it to the
14799                // background importance.
14800                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14801            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14802                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14803            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14804                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14805            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14806                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14807            } else if (adj >= ProcessList.SERVICE_ADJ) {
14808                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14809            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14810                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14811            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14812                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14813            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14814                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14815            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14816                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14817            } else {
14818                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14819            }
14820        }
14821
14822        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14823        if (foregroundActivities != app.foregroundActivities) {
14824            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14825        }
14826        if (changes != 0) {
14827            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14828            app.memImportance = importance;
14829            app.foregroundActivities = foregroundActivities;
14830            int i = mPendingProcessChanges.size()-1;
14831            ProcessChangeItem item = null;
14832            while (i >= 0) {
14833                item = mPendingProcessChanges.get(i);
14834                if (item.pid == app.pid) {
14835                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14836                    break;
14837                }
14838                i--;
14839            }
14840            if (i < 0) {
14841                // No existing item in pending changes; need a new one.
14842                final int NA = mAvailProcessChanges.size();
14843                if (NA > 0) {
14844                    item = mAvailProcessChanges.remove(NA-1);
14845                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14846                } else {
14847                    item = new ProcessChangeItem();
14848                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14849                }
14850                item.changes = 0;
14851                item.pid = app.pid;
14852                item.uid = app.info.uid;
14853                if (mPendingProcessChanges.size() == 0) {
14854                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14855                            "*** Enqueueing dispatch processes changed!");
14856                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14857                }
14858                mPendingProcessChanges.add(item);
14859            }
14860            item.changes |= changes;
14861            item.importance = importance;
14862            item.foregroundActivities = foregroundActivities;
14863            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14864                    + Integer.toHexString(System.identityHashCode(item))
14865                    + " " + app.toShortString() + ": changes=" + item.changes
14866                    + " importance=" + item.importance
14867                    + " foreground=" + item.foregroundActivities
14868                    + " type=" + app.adjType + " source=" + app.adjSource
14869                    + " target=" + app.adjTarget);
14870        }
14871
14872        return app.curRawAdj;
14873    }
14874
14875    /**
14876     * Schedule PSS collection of a process.
14877     */
14878    void requestPssLocked(ProcessRecord proc, int procState) {
14879        if (mPendingPssProcesses.contains(proc)) {
14880            return;
14881        }
14882        if (mPendingPssProcesses.size() == 0) {
14883            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14884        }
14885        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14886        proc.pssProcState = procState;
14887        mPendingPssProcesses.add(proc);
14888    }
14889
14890    /**
14891     * Schedule PSS collection of all processes.
14892     */
14893    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14894        if (!always) {
14895            if (now < (mLastFullPssTime +
14896                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14897                return;
14898            }
14899        }
14900        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
14901        mLastFullPssTime = now;
14902        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
14903        mPendingPssProcesses.clear();
14904        for (int i=mLruProcesses.size()-1; i>=0; i--) {
14905            ProcessRecord app = mLruProcesses.get(i);
14906            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
14907                app.pssProcState = app.setProcState;
14908                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
14909                        mSleeping, now);
14910                mPendingPssProcesses.add(app);
14911            }
14912        }
14913        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14914    }
14915
14916    /**
14917     * Ask a given process to GC right now.
14918     */
14919    final void performAppGcLocked(ProcessRecord app) {
14920        try {
14921            app.lastRequestedGc = SystemClock.uptimeMillis();
14922            if (app.thread != null) {
14923                if (app.reportLowMemory) {
14924                    app.reportLowMemory = false;
14925                    app.thread.scheduleLowMemory();
14926                } else {
14927                    app.thread.processInBackground();
14928                }
14929            }
14930        } catch (Exception e) {
14931            // whatever.
14932        }
14933    }
14934
14935    /**
14936     * Returns true if things are idle enough to perform GCs.
14937     */
14938    private final boolean canGcNowLocked() {
14939        boolean processingBroadcasts = false;
14940        for (BroadcastQueue q : mBroadcastQueues) {
14941            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14942                processingBroadcasts = true;
14943            }
14944        }
14945        return !processingBroadcasts
14946                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
14947    }
14948
14949    /**
14950     * Perform GCs on all processes that are waiting for it, but only
14951     * if things are idle.
14952     */
14953    final void performAppGcsLocked() {
14954        final int N = mProcessesToGc.size();
14955        if (N <= 0) {
14956            return;
14957        }
14958        if (canGcNowLocked()) {
14959            while (mProcessesToGc.size() > 0) {
14960                ProcessRecord proc = mProcessesToGc.remove(0);
14961                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14962                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14963                            <= SystemClock.uptimeMillis()) {
14964                        // To avoid spamming the system, we will GC processes one
14965                        // at a time, waiting a few seconds between each.
14966                        performAppGcLocked(proc);
14967                        scheduleAppGcsLocked();
14968                        return;
14969                    } else {
14970                        // It hasn't been long enough since we last GCed this
14971                        // process...  put it in the list to wait for its time.
14972                        addProcessToGcListLocked(proc);
14973                        break;
14974                    }
14975                }
14976            }
14977
14978            scheduleAppGcsLocked();
14979        }
14980    }
14981
14982    /**
14983     * If all looks good, perform GCs on all processes waiting for them.
14984     */
14985    final void performAppGcsIfAppropriateLocked() {
14986        if (canGcNowLocked()) {
14987            performAppGcsLocked();
14988            return;
14989        }
14990        // Still not idle, wait some more.
14991        scheduleAppGcsLocked();
14992    }
14993
14994    /**
14995     * Schedule the execution of all pending app GCs.
14996     */
14997    final void scheduleAppGcsLocked() {
14998        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
14999
15000        if (mProcessesToGc.size() > 0) {
15001            // Schedule a GC for the time to the next process.
15002            ProcessRecord proc = mProcessesToGc.get(0);
15003            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15004
15005            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15006            long now = SystemClock.uptimeMillis();
15007            if (when < (now+GC_TIMEOUT)) {
15008                when = now + GC_TIMEOUT;
15009            }
15010            mHandler.sendMessageAtTime(msg, when);
15011        }
15012    }
15013
15014    /**
15015     * Add a process to the array of processes waiting to be GCed.  Keeps the
15016     * list in sorted order by the last GC time.  The process can't already be
15017     * on the list.
15018     */
15019    final void addProcessToGcListLocked(ProcessRecord proc) {
15020        boolean added = false;
15021        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15022            if (mProcessesToGc.get(i).lastRequestedGc <
15023                    proc.lastRequestedGc) {
15024                added = true;
15025                mProcessesToGc.add(i+1, proc);
15026                break;
15027            }
15028        }
15029        if (!added) {
15030            mProcessesToGc.add(0, proc);
15031        }
15032    }
15033
15034    /**
15035     * Set up to ask a process to GC itself.  This will either do it
15036     * immediately, or put it on the list of processes to gc the next
15037     * time things are idle.
15038     */
15039    final void scheduleAppGcLocked(ProcessRecord app) {
15040        long now = SystemClock.uptimeMillis();
15041        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15042            return;
15043        }
15044        if (!mProcessesToGc.contains(app)) {
15045            addProcessToGcListLocked(app);
15046            scheduleAppGcsLocked();
15047        }
15048    }
15049
15050    final void checkExcessivePowerUsageLocked(boolean doKills) {
15051        updateCpuStatsNow();
15052
15053        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15054        boolean doWakeKills = doKills;
15055        boolean doCpuKills = doKills;
15056        if (mLastPowerCheckRealtime == 0) {
15057            doWakeKills = false;
15058        }
15059        if (mLastPowerCheckUptime == 0) {
15060            doCpuKills = false;
15061        }
15062        if (stats.isScreenOn()) {
15063            doWakeKills = false;
15064        }
15065        final long curRealtime = SystemClock.elapsedRealtime();
15066        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15067        final long curUptime = SystemClock.uptimeMillis();
15068        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15069        mLastPowerCheckRealtime = curRealtime;
15070        mLastPowerCheckUptime = curUptime;
15071        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15072            doWakeKills = false;
15073        }
15074        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15075            doCpuKills = false;
15076        }
15077        int i = mLruProcesses.size();
15078        while (i > 0) {
15079            i--;
15080            ProcessRecord app = mLruProcesses.get(i);
15081            if (!app.keeping) {
15082                long wtime;
15083                synchronized (stats) {
15084                    wtime = stats.getProcessWakeTime(app.info.uid,
15085                            app.pid, curRealtime);
15086                }
15087                long wtimeUsed = wtime - app.lastWakeTime;
15088                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15089                if (DEBUG_POWER) {
15090                    StringBuilder sb = new StringBuilder(128);
15091                    sb.append("Wake for ");
15092                    app.toShortString(sb);
15093                    sb.append(": over ");
15094                    TimeUtils.formatDuration(realtimeSince, sb);
15095                    sb.append(" used ");
15096                    TimeUtils.formatDuration(wtimeUsed, sb);
15097                    sb.append(" (");
15098                    sb.append((wtimeUsed*100)/realtimeSince);
15099                    sb.append("%)");
15100                    Slog.i(TAG, sb.toString());
15101                    sb.setLength(0);
15102                    sb.append("CPU for ");
15103                    app.toShortString(sb);
15104                    sb.append(": over ");
15105                    TimeUtils.formatDuration(uptimeSince, sb);
15106                    sb.append(" used ");
15107                    TimeUtils.formatDuration(cputimeUsed, sb);
15108                    sb.append(" (");
15109                    sb.append((cputimeUsed*100)/uptimeSince);
15110                    sb.append("%)");
15111                    Slog.i(TAG, sb.toString());
15112                }
15113                // If a process has held a wake lock for more
15114                // than 50% of the time during this period,
15115                // that sounds bad.  Kill!
15116                if (doWakeKills && realtimeSince > 0
15117                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15118                    synchronized (stats) {
15119                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15120                                realtimeSince, wtimeUsed);
15121                    }
15122                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15123                            + " during " + realtimeSince);
15124                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15125                } else if (doCpuKills && uptimeSince > 0
15126                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15127                    synchronized (stats) {
15128                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15129                                uptimeSince, cputimeUsed);
15130                    }
15131                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15132                            + " during " + uptimeSince);
15133                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15134                } else {
15135                    app.lastWakeTime = wtime;
15136                    app.lastCpuTime = app.curCpuTime;
15137                }
15138            }
15139        }
15140    }
15141
15142    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15143            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15144        boolean success = true;
15145
15146        if (app.curRawAdj != app.setRawAdj) {
15147            if (wasKeeping && !app.keeping) {
15148                // This app is no longer something we want to keep.  Note
15149                // its current wake lock time to later know to kill it if
15150                // it is not behaving well.
15151                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15152                synchronized (stats) {
15153                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15154                            app.pid, SystemClock.elapsedRealtime());
15155                }
15156                app.lastCpuTime = app.curCpuTime;
15157            }
15158
15159            app.setRawAdj = app.curRawAdj;
15160        }
15161
15162        if (app.curAdj != app.setAdj) {
15163            ProcessList.setOomAdj(app.pid, app.curAdj);
15164            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15165                TAG, "Set " + app.pid + " " + app.processName +
15166                " adj " + app.curAdj + ": " + app.adjType);
15167            app.setAdj = app.curAdj;
15168        }
15169
15170        if (app.setSchedGroup != app.curSchedGroup) {
15171            app.setSchedGroup = app.curSchedGroup;
15172            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15173                    "Setting process group of " + app.processName
15174                    + " to " + app.curSchedGroup);
15175            if (app.waitingToKill != null &&
15176                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15177                killUnneededProcessLocked(app, app.waitingToKill);
15178                success = false;
15179            } else {
15180                if (true) {
15181                    long oldId = Binder.clearCallingIdentity();
15182                    try {
15183                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15184                    } catch (Exception e) {
15185                        Slog.w(TAG, "Failed setting process group of " + app.pid
15186                                + " to " + app.curSchedGroup);
15187                        e.printStackTrace();
15188                    } finally {
15189                        Binder.restoreCallingIdentity(oldId);
15190                    }
15191                } else {
15192                    if (app.thread != null) {
15193                        try {
15194                            app.thread.setSchedulingGroup(app.curSchedGroup);
15195                        } catch (RemoteException e) {
15196                        }
15197                    }
15198                }
15199                Process.setSwappiness(app.pid,
15200                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15201            }
15202        }
15203        if (app.repProcState != app.curProcState) {
15204            app.repProcState = app.curProcState;
15205            if (!reportingProcessState && app.thread != null) {
15206                try {
15207                    if (false) {
15208                        //RuntimeException h = new RuntimeException("here");
15209                        Slog.i(TAG, "Sending new process state " + app.repProcState
15210                                + " to " + app /*, h*/);
15211                    }
15212                    app.thread.setProcessState(app.repProcState);
15213                } catch (RemoteException e) {
15214                }
15215            }
15216        }
15217        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15218                app.setProcState)) {
15219            app.lastStateTime = now;
15220            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15221                    mSleeping, now);
15222            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15223                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15224                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15225                    + (app.nextPssTime-now) + ": " + app);
15226        } else {
15227            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15228                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15229                requestPssLocked(app, app.setProcState);
15230                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15231                        mSleeping, now);
15232            } else if (false && DEBUG_PSS) {
15233                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15234            }
15235        }
15236        if (app.setProcState != app.curProcState) {
15237            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15238                    "Proc state change of " + app.processName
15239                    + " to " + app.curProcState);
15240            app.setProcState = app.curProcState;
15241            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15242                app.notCachedSinceIdle = false;
15243            }
15244            if (!doingAll) {
15245                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15246            } else {
15247                app.procStateChanged = true;
15248            }
15249        }
15250        return success;
15251    }
15252
15253    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15254        if (proc.thread != null && proc.baseProcessTracker != null) {
15255            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15256        }
15257    }
15258
15259    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15260            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15261        if (app.thread == null) {
15262            return false;
15263        }
15264
15265        final boolean wasKeeping = app.keeping;
15266
15267        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15268
15269        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15270                reportingProcessState, now);
15271    }
15272
15273    private final ActivityRecord resumedAppLocked() {
15274        return mStackSupervisor.resumedAppLocked();
15275    }
15276
15277    final boolean updateOomAdjLocked(ProcessRecord app) {
15278        return updateOomAdjLocked(app, false);
15279    }
15280
15281    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15282        final ActivityRecord TOP_ACT = resumedAppLocked();
15283        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15284        final boolean wasCached = app.cached;
15285
15286        mAdjSeq++;
15287
15288        // This is the desired cached adjusment we want to tell it to use.
15289        // If our app is currently cached, we know it, and that is it.  Otherwise,
15290        // we don't know it yet, and it needs to now be cached we will then
15291        // need to do a complete oom adj.
15292        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15293                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15294        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15295                SystemClock.uptimeMillis());
15296        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15297            // Changed to/from cached state, so apps after it in the LRU
15298            // list may also be changed.
15299            updateOomAdjLocked();
15300        }
15301        return success;
15302    }
15303
15304    final void updateOomAdjLocked() {
15305        final ActivityRecord TOP_ACT = resumedAppLocked();
15306        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15307        final long now = SystemClock.uptimeMillis();
15308        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15309        final int N = mLruProcesses.size();
15310
15311        if (false) {
15312            RuntimeException e = new RuntimeException();
15313            e.fillInStackTrace();
15314            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15315        }
15316
15317        mAdjSeq++;
15318        mNewNumServiceProcs = 0;
15319        mNewNumAServiceProcs = 0;
15320
15321        final int emptyProcessLimit;
15322        final int cachedProcessLimit;
15323        if (mProcessLimit <= 0) {
15324            emptyProcessLimit = cachedProcessLimit = 0;
15325        } else if (mProcessLimit == 1) {
15326            emptyProcessLimit = 1;
15327            cachedProcessLimit = 0;
15328        } else {
15329            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15330            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15331        }
15332
15333        // Let's determine how many processes we have running vs.
15334        // how many slots we have for background processes; we may want
15335        // to put multiple processes in a slot of there are enough of
15336        // them.
15337        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15338                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15339        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15340        if (numEmptyProcs > cachedProcessLimit) {
15341            // If there are more empty processes than our limit on cached
15342            // processes, then use the cached process limit for the factor.
15343            // This ensures that the really old empty processes get pushed
15344            // down to the bottom, so if we are running low on memory we will
15345            // have a better chance at keeping around more cached processes
15346            // instead of a gazillion empty processes.
15347            numEmptyProcs = cachedProcessLimit;
15348        }
15349        int emptyFactor = numEmptyProcs/numSlots;
15350        if (emptyFactor < 1) emptyFactor = 1;
15351        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15352        if (cachedFactor < 1) cachedFactor = 1;
15353        int stepCached = 0;
15354        int stepEmpty = 0;
15355        int numCached = 0;
15356        int numEmpty = 0;
15357        int numTrimming = 0;
15358
15359        mNumNonCachedProcs = 0;
15360        mNumCachedHiddenProcs = 0;
15361
15362        // First update the OOM adjustment for each of the
15363        // application processes based on their current state.
15364        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15365        int nextCachedAdj = curCachedAdj+1;
15366        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15367        int nextEmptyAdj = curEmptyAdj+2;
15368        for (int i=N-1; i>=0; i--) {
15369            ProcessRecord app = mLruProcesses.get(i);
15370            if (!app.killedByAm && app.thread != null) {
15371                app.procStateChanged = false;
15372                final boolean wasKeeping = app.keeping;
15373                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15374
15375                // If we haven't yet assigned the final cached adj
15376                // to the process, do that now.
15377                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15378                    switch (app.curProcState) {
15379                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15380                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15381                            // This process is a cached process holding activities...
15382                            // assign it the next cached value for that type, and then
15383                            // step that cached level.
15384                            app.curRawAdj = curCachedAdj;
15385                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15386                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15387                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15388                                    + ")");
15389                            if (curCachedAdj != nextCachedAdj) {
15390                                stepCached++;
15391                                if (stepCached >= cachedFactor) {
15392                                    stepCached = 0;
15393                                    curCachedAdj = nextCachedAdj;
15394                                    nextCachedAdj += 2;
15395                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15396                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15397                                    }
15398                                }
15399                            }
15400                            break;
15401                        default:
15402                            // For everything else, assign next empty cached process
15403                            // level and bump that up.  Note that this means that
15404                            // long-running services that have dropped down to the
15405                            // cached level will be treated as empty (since their process
15406                            // state is still as a service), which is what we want.
15407                            app.curRawAdj = curEmptyAdj;
15408                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15409                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15410                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15411                                    + ")");
15412                            if (curEmptyAdj != nextEmptyAdj) {
15413                                stepEmpty++;
15414                                if (stepEmpty >= emptyFactor) {
15415                                    stepEmpty = 0;
15416                                    curEmptyAdj = nextEmptyAdj;
15417                                    nextEmptyAdj += 2;
15418                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15419                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15420                                    }
15421                                }
15422                            }
15423                            break;
15424                    }
15425                }
15426
15427                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15428
15429                // Count the number of process types.
15430                switch (app.curProcState) {
15431                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15432                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15433                        mNumCachedHiddenProcs++;
15434                        numCached++;
15435                        if (numCached > cachedProcessLimit) {
15436                            killUnneededProcessLocked(app, "cached #" + numCached);
15437                        }
15438                        break;
15439                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15440                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15441                                && app.lastActivityTime < oldTime) {
15442                            killUnneededProcessLocked(app, "empty for "
15443                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15444                                    / 1000) + "s");
15445                        } else {
15446                            numEmpty++;
15447                            if (numEmpty > emptyProcessLimit) {
15448                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15449                            }
15450                        }
15451                        break;
15452                    default:
15453                        mNumNonCachedProcs++;
15454                        break;
15455                }
15456
15457                if (app.isolated && app.services.size() <= 0) {
15458                    // If this is an isolated process, and there are no
15459                    // services running in it, then the process is no longer
15460                    // needed.  We agressively kill these because we can by
15461                    // definition not re-use the same process again, and it is
15462                    // good to avoid having whatever code was running in them
15463                    // left sitting around after no longer needed.
15464                    killUnneededProcessLocked(app, "isolated not needed");
15465                }
15466
15467                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15468                        && !app.killedByAm) {
15469                    numTrimming++;
15470                }
15471            }
15472        }
15473
15474        mNumServiceProcs = mNewNumServiceProcs;
15475
15476        // Now determine the memory trimming level of background processes.
15477        // Unfortunately we need to start at the back of the list to do this
15478        // properly.  We only do this if the number of background apps we
15479        // are managing to keep around is less than half the maximum we desire;
15480        // if we are keeping a good number around, we'll let them use whatever
15481        // memory they want.
15482        final int numCachedAndEmpty = numCached + numEmpty;
15483        int memFactor;
15484        if (numCached <= ProcessList.TRIM_CACHED_APPS
15485                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15486            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15487                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15488            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15489                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15490            } else {
15491                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15492            }
15493        } else {
15494            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15495        }
15496        // We always allow the memory level to go up (better).  We only allow it to go
15497        // down if we are in a state where that is allowed, *and* the total number of processes
15498        // has gone down since last time.
15499        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15500                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15501                + " last=" + mLastNumProcesses);
15502        if (memFactor > mLastMemoryLevel) {
15503            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15504                memFactor = mLastMemoryLevel;
15505                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15506            }
15507        }
15508        mLastMemoryLevel = memFactor;
15509        mLastNumProcesses = mLruProcesses.size();
15510        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15511        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15512        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15513            if (mLowRamStartTime == 0) {
15514                mLowRamStartTime = now;
15515            }
15516            int step = 0;
15517            int fgTrimLevel;
15518            switch (memFactor) {
15519                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15520                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15521                    break;
15522                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15523                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15524                    break;
15525                default:
15526                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15527                    break;
15528            }
15529            int factor = numTrimming/3;
15530            int minFactor = 2;
15531            if (mHomeProcess != null) minFactor++;
15532            if (mPreviousProcess != null) minFactor++;
15533            if (factor < minFactor) factor = minFactor;
15534            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15535            for (int i=N-1; i>=0; i--) {
15536                ProcessRecord app = mLruProcesses.get(i);
15537                if (allChanged || app.procStateChanged) {
15538                    setProcessTrackerState(app, trackerMemFactor, now);
15539                    app.procStateChanged = false;
15540                }
15541                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15542                        && !app.killedByAm) {
15543                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15544                        try {
15545                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15546                                    "Trimming memory of " + app.processName
15547                                    + " to " + curLevel);
15548                            app.thread.scheduleTrimMemory(curLevel);
15549                        } catch (RemoteException e) {
15550                        }
15551                        if (false) {
15552                            // For now we won't do this; our memory trimming seems
15553                            // to be good enough at this point that destroying
15554                            // activities causes more harm than good.
15555                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15556                                    && app != mHomeProcess && app != mPreviousProcess) {
15557                                // Need to do this on its own message because the stack may not
15558                                // be in a consistent state at this point.
15559                                // For these apps we will also finish their activities
15560                                // to help them free memory.
15561                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15562                            }
15563                        }
15564                    }
15565                    app.trimMemoryLevel = curLevel;
15566                    step++;
15567                    if (step >= factor) {
15568                        step = 0;
15569                        switch (curLevel) {
15570                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15571                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15572                                break;
15573                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15574                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15575                                break;
15576                        }
15577                    }
15578                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15579                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15580                            && app.thread != null) {
15581                        try {
15582                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15583                                    "Trimming memory of heavy-weight " + app.processName
15584                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15585                            app.thread.scheduleTrimMemory(
15586                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15587                        } catch (RemoteException e) {
15588                        }
15589                    }
15590                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15591                } else {
15592                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15593                            || app.systemNoUi) && app.pendingUiClean) {
15594                        // If this application is now in the background and it
15595                        // had done UI, then give it the special trim level to
15596                        // have it free UI resources.
15597                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15598                        if (app.trimMemoryLevel < level && app.thread != null) {
15599                            try {
15600                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15601                                        "Trimming memory of bg-ui " + app.processName
15602                                        + " to " + level);
15603                                app.thread.scheduleTrimMemory(level);
15604                            } catch (RemoteException e) {
15605                            }
15606                        }
15607                        app.pendingUiClean = false;
15608                    }
15609                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15610                        try {
15611                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15612                                    "Trimming memory of fg " + app.processName
15613                                    + " to " + fgTrimLevel);
15614                            app.thread.scheduleTrimMemory(fgTrimLevel);
15615                        } catch (RemoteException e) {
15616                        }
15617                    }
15618                    app.trimMemoryLevel = fgTrimLevel;
15619                }
15620            }
15621        } else {
15622            if (mLowRamStartTime != 0) {
15623                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15624                mLowRamStartTime = 0;
15625            }
15626            for (int i=N-1; i>=0; i--) {
15627                ProcessRecord app = mLruProcesses.get(i);
15628                if (allChanged || app.procStateChanged) {
15629                    setProcessTrackerState(app, trackerMemFactor, now);
15630                    app.procStateChanged = false;
15631                }
15632                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15633                        || app.systemNoUi) && app.pendingUiClean) {
15634                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15635                            && app.thread != null) {
15636                        try {
15637                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15638                                    "Trimming memory of ui hidden " + app.processName
15639                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15640                            app.thread.scheduleTrimMemory(
15641                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15642                        } catch (RemoteException e) {
15643                        }
15644                    }
15645                    app.pendingUiClean = false;
15646                }
15647                app.trimMemoryLevel = 0;
15648            }
15649        }
15650
15651        if (mAlwaysFinishActivities) {
15652            // Need to do this on its own message because the stack may not
15653            // be in a consistent state at this point.
15654            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15655        }
15656
15657        if (allChanged) {
15658            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15659        }
15660
15661        if (mProcessStats.shouldWriteNowLocked(now)) {
15662            mHandler.post(new Runnable() {
15663                @Override public void run() {
15664                    synchronized (ActivityManagerService.this) {
15665                        mProcessStats.writeStateAsyncLocked();
15666                    }
15667                }
15668            });
15669        }
15670
15671        if (DEBUG_OOM_ADJ) {
15672            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15673        }
15674    }
15675
15676    final void trimApplications() {
15677        synchronized (this) {
15678            int i;
15679
15680            // First remove any unused application processes whose package
15681            // has been removed.
15682            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15683                final ProcessRecord app = mRemovedProcesses.get(i);
15684                if (app.activities.size() == 0
15685                        && app.curReceiver == null && app.services.size() == 0) {
15686                    Slog.i(
15687                        TAG, "Exiting empty application process "
15688                        + app.processName + " ("
15689                        + (app.thread != null ? app.thread.asBinder() : null)
15690                        + ")\n");
15691                    if (app.pid > 0 && app.pid != MY_PID) {
15692                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15693                                app.processName, app.setAdj, "empty");
15694                        app.killedByAm = true;
15695                        Process.killProcessQuiet(app.pid);
15696                    } else {
15697                        try {
15698                            app.thread.scheduleExit();
15699                        } catch (Exception e) {
15700                            // Ignore exceptions.
15701                        }
15702                    }
15703                    cleanUpApplicationRecordLocked(app, false, true, -1);
15704                    mRemovedProcesses.remove(i);
15705
15706                    if (app.persistent) {
15707                        if (app.persistent) {
15708                            addAppLocked(app.info, false);
15709                        }
15710                    }
15711                }
15712            }
15713
15714            // Now update the oom adj for all processes.
15715            updateOomAdjLocked();
15716        }
15717    }
15718
15719    /** This method sends the specified signal to each of the persistent apps */
15720    public void signalPersistentProcesses(int sig) throws RemoteException {
15721        if (sig != Process.SIGNAL_USR1) {
15722            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15723        }
15724
15725        synchronized (this) {
15726            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15727                    != PackageManager.PERMISSION_GRANTED) {
15728                throw new SecurityException("Requires permission "
15729                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15730            }
15731
15732            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15733                ProcessRecord r = mLruProcesses.get(i);
15734                if (r.thread != null && r.persistent) {
15735                    Process.sendSignal(r.pid, sig);
15736                }
15737            }
15738        }
15739    }
15740
15741    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15742        if (proc == null || proc == mProfileProc) {
15743            proc = mProfileProc;
15744            path = mProfileFile;
15745            profileType = mProfileType;
15746            clearProfilerLocked();
15747        }
15748        if (proc == null) {
15749            return;
15750        }
15751        try {
15752            proc.thread.profilerControl(false, path, null, profileType);
15753        } catch (RemoteException e) {
15754            throw new IllegalStateException("Process disappeared");
15755        }
15756    }
15757
15758    private void clearProfilerLocked() {
15759        if (mProfileFd != null) {
15760            try {
15761                mProfileFd.close();
15762            } catch (IOException e) {
15763            }
15764        }
15765        mProfileApp = null;
15766        mProfileProc = null;
15767        mProfileFile = null;
15768        mProfileType = 0;
15769        mAutoStopProfiler = false;
15770    }
15771
15772    public boolean profileControl(String process, int userId, boolean start,
15773            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15774
15775        try {
15776            synchronized (this) {
15777                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15778                // its own permission.
15779                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15780                        != PackageManager.PERMISSION_GRANTED) {
15781                    throw new SecurityException("Requires permission "
15782                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15783                }
15784
15785                if (start && fd == null) {
15786                    throw new IllegalArgumentException("null fd");
15787                }
15788
15789                ProcessRecord proc = null;
15790                if (process != null) {
15791                    proc = findProcessLocked(process, userId, "profileControl");
15792                }
15793
15794                if (start && (proc == null || proc.thread == null)) {
15795                    throw new IllegalArgumentException("Unknown process: " + process);
15796                }
15797
15798                if (start) {
15799                    stopProfilerLocked(null, null, 0);
15800                    setProfileApp(proc.info, proc.processName, path, fd, false);
15801                    mProfileProc = proc;
15802                    mProfileType = profileType;
15803                    try {
15804                        fd = fd.dup();
15805                    } catch (IOException e) {
15806                        fd = null;
15807                    }
15808                    proc.thread.profilerControl(start, path, fd, profileType);
15809                    fd = null;
15810                    mProfileFd = null;
15811                } else {
15812                    stopProfilerLocked(proc, path, profileType);
15813                    if (fd != null) {
15814                        try {
15815                            fd.close();
15816                        } catch (IOException e) {
15817                        }
15818                    }
15819                }
15820
15821                return true;
15822            }
15823        } catch (RemoteException e) {
15824            throw new IllegalStateException("Process disappeared");
15825        } finally {
15826            if (fd != null) {
15827                try {
15828                    fd.close();
15829                } catch (IOException e) {
15830                }
15831            }
15832        }
15833    }
15834
15835    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15836        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15837                userId, true, true, callName, null);
15838        ProcessRecord proc = null;
15839        try {
15840            int pid = Integer.parseInt(process);
15841            synchronized (mPidsSelfLocked) {
15842                proc = mPidsSelfLocked.get(pid);
15843            }
15844        } catch (NumberFormatException e) {
15845        }
15846
15847        if (proc == null) {
15848            ArrayMap<String, SparseArray<ProcessRecord>> all
15849                    = mProcessNames.getMap();
15850            SparseArray<ProcessRecord> procs = all.get(process);
15851            if (procs != null && procs.size() > 0) {
15852                proc = procs.valueAt(0);
15853                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
15854                    for (int i=1; i<procs.size(); i++) {
15855                        ProcessRecord thisProc = procs.valueAt(i);
15856                        if (thisProc.userId == userId) {
15857                            proc = thisProc;
15858                            break;
15859                        }
15860                    }
15861                }
15862            }
15863        }
15864
15865        return proc;
15866    }
15867
15868    public boolean dumpHeap(String process, int userId, boolean managed,
15869            String path, ParcelFileDescriptor fd) throws RemoteException {
15870
15871        try {
15872            synchronized (this) {
15873                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15874                // its own permission (same as profileControl).
15875                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15876                        != PackageManager.PERMISSION_GRANTED) {
15877                    throw new SecurityException("Requires permission "
15878                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15879                }
15880
15881                if (fd == null) {
15882                    throw new IllegalArgumentException("null fd");
15883                }
15884
15885                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
15886                if (proc == null || proc.thread == null) {
15887                    throw new IllegalArgumentException("Unknown process: " + process);
15888                }
15889
15890                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15891                if (!isDebuggable) {
15892                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15893                        throw new SecurityException("Process not debuggable: " + proc);
15894                    }
15895                }
15896
15897                proc.thread.dumpHeap(managed, path, fd);
15898                fd = null;
15899                return true;
15900            }
15901        } catch (RemoteException e) {
15902            throw new IllegalStateException("Process disappeared");
15903        } finally {
15904            if (fd != null) {
15905                try {
15906                    fd.close();
15907                } catch (IOException e) {
15908                }
15909            }
15910        }
15911    }
15912
15913    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15914    public void monitor() {
15915        synchronized (this) { }
15916    }
15917
15918    void onCoreSettingsChange(Bundle settings) {
15919        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15920            ProcessRecord processRecord = mLruProcesses.get(i);
15921            try {
15922                if (processRecord.thread != null) {
15923                    processRecord.thread.setCoreSettings(settings);
15924                }
15925            } catch (RemoteException re) {
15926                /* ignore */
15927            }
15928        }
15929    }
15930
15931    // Multi-user methods
15932
15933    @Override
15934    public boolean switchUser(final int userId) {
15935        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
15936                != PackageManager.PERMISSION_GRANTED) {
15937            String msg = "Permission Denial: switchUser() from pid="
15938                    + Binder.getCallingPid()
15939                    + ", uid=" + Binder.getCallingUid()
15940                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
15941            Slog.w(TAG, msg);
15942            throw new SecurityException(msg);
15943        }
15944
15945        final long ident = Binder.clearCallingIdentity();
15946        try {
15947            synchronized (this) {
15948                final int oldUserId = mCurrentUserId;
15949                if (oldUserId == userId) {
15950                    return true;
15951                }
15952
15953                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
15954                if (userInfo == null) {
15955                    Slog.w(TAG, "No user info for user #" + userId);
15956                    return false;
15957                }
15958
15959                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
15960                        R.anim.screen_user_enter);
15961
15962                boolean needStart = false;
15963
15964                // If the user we are switching to is not currently started, then
15965                // we need to start it now.
15966                if (mStartedUsers.get(userId) == null) {
15967                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
15968                    updateStartedUserArrayLocked();
15969                    needStart = true;
15970                }
15971
15972                mCurrentUserId = userId;
15973                final Integer userIdInt = Integer.valueOf(userId);
15974                mUserLru.remove(userIdInt);
15975                mUserLru.add(userIdInt);
15976
15977                mWindowManager.setCurrentUser(userId);
15978
15979                // Once the internal notion of the active user has switched, we lock the device
15980                // with the option to show the user switcher on the keyguard.
15981                mWindowManager.lockNow(null);
15982
15983                final UserStartedState uss = mStartedUsers.get(userId);
15984
15985                // Make sure user is in the started state.  If it is currently
15986                // stopping, we need to knock that off.
15987                if (uss.mState == UserStartedState.STATE_STOPPING) {
15988                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
15989                    // so we can just fairly silently bring the user back from
15990                    // the almost-dead.
15991                    uss.mState = UserStartedState.STATE_RUNNING;
15992                    updateStartedUserArrayLocked();
15993                    needStart = true;
15994                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
15995                    // This means ACTION_SHUTDOWN has been sent, so we will
15996                    // need to treat this as a new boot of the user.
15997                    uss.mState = UserStartedState.STATE_BOOTING;
15998                    updateStartedUserArrayLocked();
15999                    needStart = true;
16000                }
16001
16002                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16003                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16004                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16005                        oldUserId, userId, uss));
16006                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16007                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16008                if (needStart) {
16009                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16010                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16011                            | Intent.FLAG_RECEIVER_FOREGROUND);
16012                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16013                    broadcastIntentLocked(null, null, intent,
16014                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16015                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16016                }
16017
16018                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16019                    if (userId != 0) {
16020                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16021                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16022                        broadcastIntentLocked(null, null, intent, null,
16023                                new IIntentReceiver.Stub() {
16024                                    public void performReceive(Intent intent, int resultCode,
16025                                            String data, Bundle extras, boolean ordered,
16026                                            boolean sticky, int sendingUser) {
16027                                        userInitialized(uss, userId);
16028                                    }
16029                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16030                                true, false, MY_PID, Process.SYSTEM_UID,
16031                                userId);
16032                        uss.initializing = true;
16033                    } else {
16034                        getUserManagerLocked().makeInitialized(userInfo.id);
16035                    }
16036                }
16037
16038                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16039                if (homeInFront) {
16040                    startHomeActivityLocked(userId);
16041                } else {
16042                    mStackSupervisor.resumeTopActivitiesLocked();
16043                }
16044
16045                EventLogTags.writeAmSwitchUser(userId);
16046                getUserManagerLocked().userForeground(userId);
16047                sendUserSwitchBroadcastsLocked(oldUserId, userId);
16048                if (needStart) {
16049                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16050                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16051                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16052                    broadcastIntentLocked(null, null, intent,
16053                            null, new IIntentReceiver.Stub() {
16054                                @Override
16055                                public void performReceive(Intent intent, int resultCode, String data,
16056                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16057                                        throws RemoteException {
16058                                }
16059                            }, 0, null, null,
16060                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16061                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16062                }
16063            }
16064        } finally {
16065            Binder.restoreCallingIdentity(ident);
16066        }
16067
16068        return true;
16069    }
16070
16071    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16072        long ident = Binder.clearCallingIdentity();
16073        try {
16074            Intent intent;
16075            if (oldUserId >= 0) {
16076                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16077                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16078                        | Intent.FLAG_RECEIVER_FOREGROUND);
16079                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16080                broadcastIntentLocked(null, null, intent,
16081                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16082                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16083            }
16084            if (newUserId >= 0) {
16085                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16086                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16087                        | Intent.FLAG_RECEIVER_FOREGROUND);
16088                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16089                broadcastIntentLocked(null, null, intent,
16090                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16091                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16092                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16093                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16094                        | Intent.FLAG_RECEIVER_FOREGROUND);
16095                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16096                broadcastIntentLocked(null, null, intent,
16097                        null, null, 0, null, null,
16098                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16099                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16100            }
16101        } finally {
16102            Binder.restoreCallingIdentity(ident);
16103        }
16104    }
16105
16106    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16107            final int newUserId) {
16108        final int N = mUserSwitchObservers.beginBroadcast();
16109        if (N > 0) {
16110            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16111                int mCount = 0;
16112                @Override
16113                public void sendResult(Bundle data) throws RemoteException {
16114                    synchronized (ActivityManagerService.this) {
16115                        if (mCurUserSwitchCallback == this) {
16116                            mCount++;
16117                            if (mCount == N) {
16118                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16119                            }
16120                        }
16121                    }
16122                }
16123            };
16124            synchronized (this) {
16125                uss.switching = true;
16126                mCurUserSwitchCallback = callback;
16127            }
16128            for (int i=0; i<N; i++) {
16129                try {
16130                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16131                            newUserId, callback);
16132                } catch (RemoteException e) {
16133                }
16134            }
16135        } else {
16136            synchronized (this) {
16137                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16138            }
16139        }
16140        mUserSwitchObservers.finishBroadcast();
16141    }
16142
16143    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16144        synchronized (this) {
16145            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16146            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16147        }
16148    }
16149
16150    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16151        mCurUserSwitchCallback = null;
16152        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16153        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16154                oldUserId, newUserId, uss));
16155    }
16156
16157    void userInitialized(UserStartedState uss, int newUserId) {
16158        completeSwitchAndInitalize(uss, newUserId, true, false);
16159    }
16160
16161    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16162        completeSwitchAndInitalize(uss, newUserId, false, true);
16163    }
16164
16165    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16166            boolean clearInitializing, boolean clearSwitching) {
16167        boolean unfrozen = false;
16168        synchronized (this) {
16169            if (clearInitializing) {
16170                uss.initializing = false;
16171                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16172            }
16173            if (clearSwitching) {
16174                uss.switching = false;
16175            }
16176            if (!uss.switching && !uss.initializing) {
16177                mWindowManager.stopFreezingScreen();
16178                unfrozen = true;
16179            }
16180        }
16181        if (unfrozen) {
16182            final int N = mUserSwitchObservers.beginBroadcast();
16183            for (int i=0; i<N; i++) {
16184                try {
16185                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16186                } catch (RemoteException e) {
16187                }
16188            }
16189            mUserSwitchObservers.finishBroadcast();
16190        }
16191    }
16192
16193    void finishUserSwitch(UserStartedState uss) {
16194        synchronized (this) {
16195            if (uss.mState == UserStartedState.STATE_BOOTING
16196                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16197                uss.mState = UserStartedState.STATE_RUNNING;
16198                final int userId = uss.mHandle.getIdentifier();
16199                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16200                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16201                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16202                broadcastIntentLocked(null, null, intent,
16203                        null, null, 0, null, null,
16204                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16205                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16206            }
16207            int num = mUserLru.size();
16208            int i = 0;
16209            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16210                Integer oldUserId = mUserLru.get(i);
16211                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16212                if (oldUss == null) {
16213                    // Shouldn't happen, but be sane if it does.
16214                    mUserLru.remove(i);
16215                    num--;
16216                    continue;
16217                }
16218                if (oldUss.mState == UserStartedState.STATE_STOPPING
16219                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16220                    // This user is already stopping, doesn't count.
16221                    num--;
16222                    i++;
16223                    continue;
16224                }
16225                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16226                    // Owner and current can't be stopped, but count as running.
16227                    i++;
16228                    continue;
16229                }
16230                // This is a user to be stopped.
16231                stopUserLocked(oldUserId, null);
16232                num--;
16233                i++;
16234            }
16235        }
16236    }
16237
16238    @Override
16239    public int stopUser(final int userId, final IStopUserCallback callback) {
16240        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16241                != PackageManager.PERMISSION_GRANTED) {
16242            String msg = "Permission Denial: switchUser() from pid="
16243                    + Binder.getCallingPid()
16244                    + ", uid=" + Binder.getCallingUid()
16245                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16246            Slog.w(TAG, msg);
16247            throw new SecurityException(msg);
16248        }
16249        if (userId <= 0) {
16250            throw new IllegalArgumentException("Can't stop primary user " + userId);
16251        }
16252        synchronized (this) {
16253            return stopUserLocked(userId, callback);
16254        }
16255    }
16256
16257    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16258        if (mCurrentUserId == userId) {
16259            return ActivityManager.USER_OP_IS_CURRENT;
16260        }
16261
16262        final UserStartedState uss = mStartedUsers.get(userId);
16263        if (uss == null) {
16264            // User is not started, nothing to do...  but we do need to
16265            // callback if requested.
16266            if (callback != null) {
16267                mHandler.post(new Runnable() {
16268                    @Override
16269                    public void run() {
16270                        try {
16271                            callback.userStopped(userId);
16272                        } catch (RemoteException e) {
16273                        }
16274                    }
16275                });
16276            }
16277            return ActivityManager.USER_OP_SUCCESS;
16278        }
16279
16280        if (callback != null) {
16281            uss.mStopCallbacks.add(callback);
16282        }
16283
16284        if (uss.mState != UserStartedState.STATE_STOPPING
16285                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16286            uss.mState = UserStartedState.STATE_STOPPING;
16287            updateStartedUserArrayLocked();
16288
16289            long ident = Binder.clearCallingIdentity();
16290            try {
16291                // We are going to broadcast ACTION_USER_STOPPING and then
16292                // once that is done send a final ACTION_SHUTDOWN and then
16293                // stop the user.
16294                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16295                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16296                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16297                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16298                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16299                // This is the result receiver for the final shutdown broadcast.
16300                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16301                    @Override
16302                    public void performReceive(Intent intent, int resultCode, String data,
16303                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16304                        finishUserStop(uss);
16305                    }
16306                };
16307                // This is the result receiver for the initial stopping broadcast.
16308                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16309                    @Override
16310                    public void performReceive(Intent intent, int resultCode, String data,
16311                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16312                        // On to the next.
16313                        synchronized (ActivityManagerService.this) {
16314                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16315                                // Whoops, we are being started back up.  Abort, abort!
16316                                return;
16317                            }
16318                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16319                        }
16320                        broadcastIntentLocked(null, null, shutdownIntent,
16321                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16322                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16323                    }
16324                };
16325                // Kick things off.
16326                broadcastIntentLocked(null, null, stoppingIntent,
16327                        null, stoppingReceiver, 0, null, null,
16328                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16329                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16330            } finally {
16331                Binder.restoreCallingIdentity(ident);
16332            }
16333        }
16334
16335        return ActivityManager.USER_OP_SUCCESS;
16336    }
16337
16338    void finishUserStop(UserStartedState uss) {
16339        final int userId = uss.mHandle.getIdentifier();
16340        boolean stopped;
16341        ArrayList<IStopUserCallback> callbacks;
16342        synchronized (this) {
16343            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16344            if (mStartedUsers.get(userId) != uss) {
16345                stopped = false;
16346            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16347                stopped = false;
16348            } else {
16349                stopped = true;
16350                // User can no longer run.
16351                mStartedUsers.remove(userId);
16352                mUserLru.remove(Integer.valueOf(userId));
16353                updateStartedUserArrayLocked();
16354
16355                // Clean up all state and processes associated with the user.
16356                // Kill all the processes for the user.
16357                forceStopUserLocked(userId, "finish user");
16358            }
16359        }
16360
16361        for (int i=0; i<callbacks.size(); i++) {
16362            try {
16363                if (stopped) callbacks.get(i).userStopped(userId);
16364                else callbacks.get(i).userStopAborted(userId);
16365            } catch (RemoteException e) {
16366            }
16367        }
16368
16369        mStackSupervisor.removeUserLocked(userId);
16370    }
16371
16372    @Override
16373    public UserInfo getCurrentUser() {
16374        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16375                != PackageManager.PERMISSION_GRANTED) && (
16376                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16377                != PackageManager.PERMISSION_GRANTED)) {
16378            String msg = "Permission Denial: getCurrentUser() from pid="
16379                    + Binder.getCallingPid()
16380                    + ", uid=" + Binder.getCallingUid()
16381                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16382            Slog.w(TAG, msg);
16383            throw new SecurityException(msg);
16384        }
16385        synchronized (this) {
16386            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16387        }
16388    }
16389
16390    int getCurrentUserIdLocked() {
16391        return mCurrentUserId;
16392    }
16393
16394    @Override
16395    public boolean isUserRunning(int userId, boolean orStopped) {
16396        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16397                != PackageManager.PERMISSION_GRANTED) {
16398            String msg = "Permission Denial: isUserRunning() from pid="
16399                    + Binder.getCallingPid()
16400                    + ", uid=" + Binder.getCallingUid()
16401                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16402            Slog.w(TAG, msg);
16403            throw new SecurityException(msg);
16404        }
16405        synchronized (this) {
16406            return isUserRunningLocked(userId, orStopped);
16407        }
16408    }
16409
16410    boolean isUserRunningLocked(int userId, boolean orStopped) {
16411        UserStartedState state = mStartedUsers.get(userId);
16412        if (state == null) {
16413            return false;
16414        }
16415        if (orStopped) {
16416            return true;
16417        }
16418        return state.mState != UserStartedState.STATE_STOPPING
16419                && state.mState != UserStartedState.STATE_SHUTDOWN;
16420    }
16421
16422    @Override
16423    public int[] getRunningUserIds() {
16424        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16425                != PackageManager.PERMISSION_GRANTED) {
16426            String msg = "Permission Denial: isUserRunning() from pid="
16427                    + Binder.getCallingPid()
16428                    + ", uid=" + Binder.getCallingUid()
16429                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16430            Slog.w(TAG, msg);
16431            throw new SecurityException(msg);
16432        }
16433        synchronized (this) {
16434            return mStartedUserArray;
16435        }
16436    }
16437
16438    private void updateStartedUserArrayLocked() {
16439        int num = 0;
16440        for (int i=0; i<mStartedUsers.size();  i++) {
16441            UserStartedState uss = mStartedUsers.valueAt(i);
16442            // This list does not include stopping users.
16443            if (uss.mState != UserStartedState.STATE_STOPPING
16444                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16445                num++;
16446            }
16447        }
16448        mStartedUserArray = new int[num];
16449        num = 0;
16450        for (int i=0; i<mStartedUsers.size();  i++) {
16451            UserStartedState uss = mStartedUsers.valueAt(i);
16452            if (uss.mState != UserStartedState.STATE_STOPPING
16453                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16454                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16455                num++;
16456            }
16457        }
16458    }
16459
16460    @Override
16461    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16462        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16463                != PackageManager.PERMISSION_GRANTED) {
16464            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16465                    + Binder.getCallingPid()
16466                    + ", uid=" + Binder.getCallingUid()
16467                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16468            Slog.w(TAG, msg);
16469            throw new SecurityException(msg);
16470        }
16471
16472        mUserSwitchObservers.register(observer);
16473    }
16474
16475    @Override
16476    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16477        mUserSwitchObservers.unregister(observer);
16478    }
16479
16480    private boolean userExists(int userId) {
16481        if (userId == 0) {
16482            return true;
16483        }
16484        UserManagerService ums = getUserManagerLocked();
16485        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16486    }
16487
16488    int[] getUsersLocked() {
16489        UserManagerService ums = getUserManagerLocked();
16490        return ums != null ? ums.getUserIds() : new int[] { 0 };
16491    }
16492
16493    UserManagerService getUserManagerLocked() {
16494        if (mUserManager == null) {
16495            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16496            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16497        }
16498        return mUserManager;
16499    }
16500
16501    private int applyUserId(int uid, int userId) {
16502        return UserHandle.getUid(userId, uid);
16503    }
16504
16505    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16506        if (info == null) return null;
16507        ApplicationInfo newInfo = new ApplicationInfo(info);
16508        newInfo.uid = applyUserId(info.uid, userId);
16509        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16510                + info.packageName;
16511        return newInfo;
16512    }
16513
16514    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16515        if (aInfo == null
16516                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16517            return aInfo;
16518        }
16519
16520        ActivityInfo info = new ActivityInfo(aInfo);
16521        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16522        return info;
16523    }
16524}
16525